diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-11 10:58:59 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-12 13:24:41 +0200 |
commit | e135271b933c896068a343b161773ce3b685be43 (patch) | |
tree | 83faf308498a9695ba551f8e5b3f7473daa37d68 | |
parent | score: Use thread state lock for current state (diff) | |
download | rtems-e135271b933c896068a343b161773ce3b685be43.tar.bz2 |
score: Avoid Giant lock _Scheduler_Set_affinity()
Update #2555.
-rw-r--r-- | cpukit/libmisc/monitor/mon-prmisc.c | 1 | ||||
-rw-r--r-- | cpukit/posix/src/pthreadcreate.c | 8 | ||||
-rw-r--r-- | cpukit/posix/src/pthreadsetaffinitynp.c | 59 | ||||
-rw-r--r-- | cpukit/rtems/src/tasksetaffinity.c | 43 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/schedulerimpl.h | 6 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/statesimpl.h | 2 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/thread.h | 1 | ||||
-rw-r--r-- | cpukit/score/src/schedulerpriorityaffinitysmp.c | 25 | ||||
-rw-r--r-- | cpukit/score/src/schedulersetaffinity.c | 20 |
9 files changed, 96 insertions, 69 deletions
diff --git a/cpukit/libmisc/monitor/mon-prmisc.c b/cpukit/libmisc/monitor/mon-prmisc.c index a3dfb4564a..526103b847 100644 --- a/cpukit/libmisc/monitor/mon-prmisc.c +++ b/cpukit/libmisc/monitor/mon-prmisc.c @@ -116,7 +116,6 @@ rtems_monitor_dump_priority(rtems_task_priority priority) static const rtems_assoc_t rtems_monitor_state_assoc[] = { { "DELAY", STATES_DELAYING, 0 }, { "DORM", STATES_DORMANT, 0 }, - { "MIGRA", STATES_MIGRATING, 0 }, { "RESTA", STATES_RESTARTING, 0 }, { "SUSP", STATES_SUSPENDED, 0 }, { "Wbar", STATES_WAITING_FOR_BARRIER, 0 }, diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c index 2533345ff6..eedb80e203 100644 --- a/cpukit/posix/src/pthreadcreate.c +++ b/cpukit/posix/src/pthreadcreate.c @@ -74,7 +74,7 @@ int pthread_create( struct sched_param schedparam; Objects_Name name; int rc; - ISR_Level level; + ISR_lock_Context lock_context; if ( !start_routine ) return EFAULT; @@ -202,11 +202,13 @@ int pthread_create( } #if defined(RTEMS_SMP) && __RTEMS_HAVE_SYS_CPUSET_H__ + _ISR_lock_ISR_disable( &lock_context ); status = _Scheduler_Set_affinity( the_thread, the_attr->affinitysetsize, the_attr->affinityset ); + _ISR_lock_ISR_enable( &lock_context ); if ( !status ) { _POSIX_Threads_Free( the_thread ); _RTEMS_Unlock_allocator(); @@ -247,13 +249,13 @@ int pthread_create( #endif if ( schedpolicy == SCHED_SPORADIC ) { - _ISR_Disable_without_giant( level ); + _ISR_lock_ISR_disable( &lock_context ); _Watchdog_Per_CPU_insert_relative( &api->Sporadic_timer, _Per_CPU_Get(), _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period ) ); - _ISR_Enable_without_giant( level ); + _ISR_lock_ISR_enable( &lock_context ); } _Thread_Enable_dispatch(); diff --git a/cpukit/posix/src/pthreadsetaffinitynp.c b/cpukit/posix/src/pthreadsetaffinitynp.c index 711d6dcaeb..6dd8bce224 100644 --- a/cpukit/posix/src/pthreadsetaffinitynp.c +++ b/cpukit/posix/src/pthreadsetaffinitynp.c @@ -31,41 +31,44 @@ #include <rtems/score/schedulerimpl.h> int pthread_setaffinity_np( - pthread_t id, - size_t cpusetsize, - const cpu_set_t *cpuset) + pthread_t thread, + size_t cpusetsize, + const cpu_set_t *cpuset +) { - Objects_Locations location; - POSIX_API_Control *api; - Thread_Control *the_thread; - bool ok; + Thread_Control *the_thread; + ISR_lock_Context lock_context; + Per_CPU_Control *cpu_self; + bool ok; - if ( !cpuset ) + if ( cpuset == NULL ) { return EFAULT; + } - the_thread = _Thread_Get( id, &location ); - switch ( location ) { + the_thread = _Thread_Get_interrupt_disable( thread, &lock_context ); - case OBJECTS_LOCAL: - ok = _Scheduler_Set_affinity( - the_thread, - cpusetsize, - cpuset - ); - if ( ok ) { - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - CPU_COPY( api->Attributes.affinityset, cpuset ); - } - _Objects_Put( &the_thread->Object ); - return ok ? 0 : EINVAL; + if ( the_thread == NULL ) { + return ESRCH; + } -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: - break; + cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); + _Thread_State_acquire_critical( the_thread, &lock_context ); + + ok = _Scheduler_Set_affinity( + the_thread, + cpusetsize, + cpuset + ); + + if ( ok ) { + POSIX_API_Control *api; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + CPU_COPY( api->Attributes.affinityset, cpuset ); } - return ESRCH; + _Thread_State_release( the_thread, &lock_context ); + _Thread_Dispatch_enable( cpu_self ); + return ok ? 0 : EINVAL; } #endif diff --git a/cpukit/rtems/src/tasksetaffinity.c b/cpukit/rtems/src/tasksetaffinity.c index a7a18be4d5..6389e4c795 100644 --- a/cpukit/rtems/src/tasksetaffinity.c +++ b/cpukit/rtems/src/tasksetaffinity.c @@ -31,33 +31,38 @@ rtems_status_code rtems_task_set_affinity( const cpu_set_t *cpuset ) { - Thread_Control *the_thread; - Objects_Locations location; - int ok; + Thread_Control *the_thread; + ISR_lock_Context lock_context; + Per_CPU_Control *cpu_self; + bool ok; - if ( !cpuset ) + if ( cpuset == NULL ) { return RTEMS_INVALID_ADDRESS; + } - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_LOCAL: - ok = _Scheduler_Set_affinity( - the_thread, - cpusetsize, - cpuset - ); - _Objects_Put( &the_thread->Object ); - return ok ? RTEMS_SUCCESSFUL : RTEMS_INVALID_NUMBER; + the_thread = _Thread_Get_interrupt_disable( id, &lock_context ); + if ( the_thread == NULL ) { #if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: + if ( _Thread_MP_Is_remote( id ) ) { + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; + } #endif - case OBJECTS_ERROR: - break; + return RTEMS_INVALID_ID; } - return RTEMS_INVALID_ID; + cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); + _Thread_State_acquire_critical( the_thread, &lock_context ); + + ok = _Scheduler_Set_affinity( + the_thread, + cpusetsize, + cpuset + ); + + _Thread_State_release( the_thread, &lock_context ); + _Thread_Dispatch_enable( cpu_self ); + return ok ? RTEMS_SUCCESSFUL : RTEMS_INVALID_NUMBER; } #endif diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index c888237376..640f871b05 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -698,9 +698,9 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_default_Set_affinity_body( } bool _Scheduler_Set_affinity( - Thread_Control *the_thread, - size_t cpusetsize, - const cpu_set_t *cpuset + Thread_Control *the_thread, + size_t cpusetsize, + const cpu_set_t *cpuset ); #endif /* defined(__RTEMS_HAVE_SYS_CPUSET_H__) */ diff --git a/cpukit/score/include/rtems/score/statesimpl.h b/cpukit/score/include/rtems/score/statesimpl.h index 97cadb2888..f3c2293b96 100644 --- a/cpukit/score/include/rtems/score/statesimpl.h +++ b/cpukit/score/include/rtems/score/statesimpl.h @@ -80,8 +80,6 @@ extern "C" { #define STATES_WAITING_FOR_TERMINATION 0x100000 /** This macro corresponds to a task being a zombie. */ #define STATES_ZOMBIE 0x200000 -/** This macro corresponds to a task migrating to another scheduler. */ -#define STATES_MIGRATING 0x400000 /** This macro corresponds to a task restarting. */ #define STATES_RESTARTING 0x800000 /** This macro corresponds to a task waiting for a join. */ diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index 15b068d92b..18e0f5429b 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -718,6 +718,7 @@ struct _Thread_Control { * The lock of this thread queue is used for various purposes. It protects * the following fields * + * - POSIX_API_Control::Attributes, * - RTEMS_API_Control::Signal, * - Thread_Control::current_state, * - Thread_Control::Post_switch_actions, diff --git a/cpukit/score/src/schedulerpriorityaffinitysmp.c b/cpukit/score/src/schedulerpriorityaffinitysmp.c index 98487ec43f..fa56e2b1b5 100644 --- a/cpukit/score/src/schedulerpriorityaffinitysmp.c +++ b/cpukit/score/src/schedulerpriorityaffinitysmp.c @@ -616,10 +616,8 @@ bool _Scheduler_priority_affinity_SMP_Set_affinity( const cpu_set_t *cpuset ) { - Scheduler_priority_affinity_SMP_Node *node = - _Scheduler_priority_affinity_SMP_Thread_get_node(thread); - - (void) scheduler; + Scheduler_priority_affinity_SMP_Node *node; + States_Control current_state; /* * Validate that the cpset meets basic requirements. @@ -628,6 +626,8 @@ bool _Scheduler_priority_affinity_SMP_Set_affinity( return false; } + node = _Scheduler_priority_affinity_SMP_Thread_get_node( thread ); + /* * The old and new set are the same, there is no point in * doing anything. @@ -635,9 +635,20 @@ bool _Scheduler_priority_affinity_SMP_Set_affinity( if ( CPU_EQUAL_S( cpusetsize, cpuset, node->Affinity.set ) ) return true; - _Thread_Set_state( thread, STATES_MIGRATING ); - CPU_COPY( node->Affinity.set, cpuset ); - _Thread_Clear_state( thread, STATES_MIGRATING ); + current_state = thread->current_state; + + if ( _States_Is_ready( current_state ) ) { + _Scheduler_priority_affinity_SMP_Block( scheduler, thread ); + } + + CPU_COPY( node->Affinity.set, cpuset ); + + if ( _States_Is_ready( current_state ) ) { + /* + * FIXME: Do not ignore threads in need for help. + */ + (void) _Scheduler_priority_affinity_SMP_Unblock( scheduler, thread ); + } return true; } diff --git a/cpukit/score/src/schedulersetaffinity.c b/cpukit/score/src/schedulersetaffinity.c index f7c9336df1..b59d8eb68e 100644 --- a/cpukit/score/src/schedulersetaffinity.c +++ b/cpukit/score/src/schedulersetaffinity.c @@ -21,32 +21,40 @@ #if defined(__RTEMS_HAVE_SYS_CPUSET_H__) bool _Scheduler_Set_affinity( - Thread_Control *the_thread, - size_t cpusetsize, - const cpu_set_t *cpuset + Thread_Control *the_thread, + size_t cpusetsize, + const cpu_set_t *cpuset ) { - const Scheduler_Control *scheduler = _Scheduler_Get( the_thread ); + const Scheduler_Control *scheduler; + ISR_lock_Context lock_context; + bool ok; if ( !_CPU_set_Is_large_enough( cpusetsize ) ) { return false; } + scheduler = _Scheduler_Get( the_thread ); + _Scheduler_Acquire_critical( scheduler, &lock_context ); + #if defined(RTEMS_SMP) - return ( *scheduler->Operations.set_affinity )( + ok = ( *scheduler->Operations.set_affinity )( scheduler, the_thread, cpusetsize, cpuset ); #else - return _Scheduler_default_Set_affinity_body( + ok = _Scheduler_default_Set_affinity_body( scheduler, the_thread, cpusetsize, cpuset ); #endif + + _Scheduler_Release_critical( scheduler, &lock_context ); + return ok; } #endif /* defined(__RTEMS_HAVE_SYS_CPUSET_H__) */ |