Avoid Giant lock for pthread_getattr_np(), pthread_setschedparam() and pthread_getschedparam(). Replace POSIX threads scheduler lock with thread state lock.
Update #2555. --- cpukit/posix/include/rtems/posix/pthreadimpl.h | 17 ---- cpukit/posix/include/rtems/posix/threadsup.h | 2 - cpukit/posix/src/pthread.c | 11 +-- cpukit/posix/src/pthreadgetattrnp.c | 35 ++++--- cpukit/posix/src/pthreadgetschedparam.c | 42 ++++----- cpukit/posix/src/pthreadsetschedparam.c | 123 ++++++++++++------------- cpukit/score/include/rtems/score/thread.h | 5 + 7 files changed, 103 insertions(+), 132 deletions(-) diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h index ef5821e..42f10b0 100644 --- a/cpukit/posix/include/rtems/posix/pthreadimpl.h +++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h @@ -223,23 +223,6 @@ RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Join_dequeue( ); } -RTEMS_INLINE_ROUTINE void _POSIX_Threads_Scheduler_acquire( - POSIX_API_Control *api, - ISR_lock_Context *lock_context -) -{ - _ISR_lock_ISR_disable_and_acquire( &api->Scheduler_lock, lock_context ); -} - -RTEMS_INLINE_ROUTINE void _POSIX_Threads_Scheduler_release( - POSIX_API_Control *api, - ISR_lock_Context *lock_context -) -{ - _ISR_lock_Release_and_ISR_enable( &api->Scheduler_lock, lock_context ); -} - - /** @} */ #ifdef __cplusplus diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h index 93ba2c1..8109921 100644 --- a/cpukit/posix/include/rtems/posix/threadsup.h +++ b/cpukit/posix/include/rtems/posix/threadsup.h @@ -52,8 +52,6 @@ typedef struct { /** This is the set of threads waiting for the thread to exit. */ Thread_queue_Control Join_List; /** This is the thread's current scheduling policy. */ - ISR_LOCK_MEMBER( Scheduler_lock ) - /** This is the thread's current scheduling policy. */ int schedpolicy; /** This is the thread's current set of scheduling parameters. */ struct sched_param schedparam; diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c index 61e498b..5c5cff7 100644 --- a/cpukit/posix/src/pthread.c +++ b/cpukit/posix/src/pthread.c @@ -114,7 +114,7 @@ void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog ) api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic_timer ); the_thread = api->thread; - _POSIX_Threads_Scheduler_acquire( api, &lock_context ); + _Thread_State_acquire( the_thread, &lock_context ); the_thread->cpu_time_budget = _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget ); @@ -128,7 +128,7 @@ void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog ) new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority ); - _POSIX_Threads_Scheduler_release( api, &lock_context ); + _Thread_State_release( the_thread, &lock_context ); _Thread_Change_priority( the_thread, @@ -200,8 +200,6 @@ static bool _POSIX_Threads_Create_extension( api = created->API_Extensions[ THREAD_API_POSIX ]; - _ISR_lock_Initialize( &api->Scheduler_lock, "POSIX Threads Scheduler" ); - /* XXX check all fields are touched */ api->thread = created; _POSIX_Threads_Initialize_attributes( &api->Attributes ); @@ -253,7 +251,6 @@ static void _POSIX_Threads_Delete_extension( api = deleted->API_Extensions[ THREAD_API_POSIX ]; - _ISR_lock_Destroy( &api->Scheduler_lock ); _Thread_queue_Destroy( &api->Join_List ); } @@ -281,13 +278,13 @@ static void _POSIX_Threads_Terminate_extension( _Thread_Enable_dispatch(); - _POSIX_Threads_Scheduler_acquire( api, &lock_context ); + _Thread_State_acquire( executing, &lock_context ); if ( api->schedpolicy == SCHED_SPORADIC ) { _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer ); } - _POSIX_Threads_Scheduler_release( api, &lock_context ); + _Thread_State_release( executing, &lock_context ); } /* diff --git a/cpukit/posix/src/pthreadgetattrnp.c b/cpukit/posix/src/pthreadgetattrnp.c index f71819f..57c5318 100644 --- a/cpukit/posix/src/pthreadgetattrnp.c +++ b/cpukit/posix/src/pthreadgetattrnp.c @@ -26,32 +26,29 @@ #include <rtems/score/threadimpl.h> int pthread_getattr_np( - pthread_t id, + pthread_t thread, pthread_attr_t *attr ) { - Objects_Locations location; - POSIX_API_Control *api; - Thread_Control *the_thread; + Thread_Control *the_thread; + ISR_lock_Context lock_context; + POSIX_API_Control *api; - if ( !attr ) + if ( attr == NULL ) { return EINVAL; + } - the_thread = _Thread_Get( id, &location ); - switch ( location ) { - - case OBJECTS_LOCAL: - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - _POSIX_Threads_Copy_attributes( attr, &api->Attributes); - _Objects_Put( &the_thread->Object ); - return 0; + the_thread = _Thread_Get_interrupt_disable( thread, &lock_context ); -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: - break; + if ( the_thread == NULL ) { + return ESRCH; } - return ESRCH; + _Thread_State_acquire_critical( the_thread, &lock_context ); + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + _POSIX_Threads_Copy_attributes( attr, &api->Attributes); + + _Thread_State_release( the_thread, &lock_context ); + return 0; } diff --git a/cpukit/posix/src/pthreadgetschedparam.c b/cpukit/posix/src/pthreadgetschedparam.c index d3fa9d4..d769d8a 100644 --- a/cpukit/posix/src/pthreadgetschedparam.c +++ b/cpukit/posix/src/pthreadgetschedparam.c @@ -34,35 +34,29 @@ int pthread_getschedparam( struct sched_param *param ) { - Objects_Locations location; - POSIX_API_Control *api; - Thread_Control *the_thread; + Thread_Control *the_thread; + ISR_lock_Context lock_context; + POSIX_API_Control *api; - if ( !policy || !param ) + if ( policy == NULL || param == NULL ) { return EINVAL; + } - the_thread = _Thread_Get( thread, &location ); - switch ( location ) { - - case OBJECTS_LOCAL: - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - if ( policy ) - *policy = api->schedpolicy; - if ( param ) { - *param = api->schedparam; - param->sched_priority = - _POSIX_Priority_From_core( the_thread->current_priority ); - } - _Objects_Put( &the_thread->Object ); - return 0; + the_thread = _Thread_Get_interrupt_disable( thread, &lock_context ); -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: - break; + if ( the_thread == NULL ) { + return ESRCH; } - return ESRCH; + _Thread_State_acquire_critical( the_thread, &lock_context ); + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + *policy = api->schedpolicy; + *param = api->schedparam; + param->sched_priority = _POSIX_Priority_From_core( + the_thread->current_priority + ); + _Thread_State_release( the_thread, &lock_context ); + return 0; } diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c index 57a2bc8..8f3cc20 100644 --- a/cpukit/posix/src/pthreadsetschedparam.c +++ b/cpukit/posix/src/pthreadsetschedparam.c @@ -38,11 +38,11 @@ int pthread_setschedparam( ) { Thread_Control *the_thread; + Per_CPU_Control *cpu_self; POSIX_API_Control *api; Thread_CPU_budget_algorithms budget_algorithm; Thread_CPU_budget_algorithm_callout budget_callout; - Objects_Locations location; - int rc; + int eno; Priority_Control unused; ISR_lock_Context lock_context; Priority_Control new_priority; @@ -50,79 +50,76 @@ int pthread_setschedparam( /* * Check all the parameters */ - if ( !param ) + + if ( param == NULL ) { return EINVAL; + } - rc = _POSIX_Thread_Translate_sched_param( + eno = _POSIX_Thread_Translate_sched_param( policy, param, &budget_algorithm, &budget_callout ); - if ( rc ) - return rc; + if ( eno != 0 ) { + return eno; + } + + the_thread = _Thread_Get_interrupt_disable( thread, &lock_context ); + + if ( the_thread == NULL ) { + return ESRCH; + } /* * Actually change the scheduling policy and parameters */ - the_thread = _Thread_Get( thread, &location ); - switch ( location ) { - - case OBJECTS_LOCAL: - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - - _POSIX_Threads_Scheduler_acquire( api, &lock_context ); - - if ( api->schedpolicy == SCHED_SPORADIC ) { - _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer ); - } - - api->schedpolicy = policy; - api->schedparam = *param; - api->Attributes.schedpolicy = policy; - api->Attributes.schedparam = *param; - - the_thread->budget_algorithm = budget_algorithm; - the_thread->budget_callout = budget_callout; - - switch ( policy ) { - case SCHED_OTHER: - case SCHED_FIFO: - case SCHED_RR: - the_thread->cpu_time_budget = - rtems_configuration_get_ticks_per_timeslice(); - new_priority = - _POSIX_Priority_To_core( api->schedparam.sched_priority ); - break; - - case SCHED_SPORADIC: - api->ss_high_priority = api->schedparam.sched_priority; - break; - } - - _POSIX_Threads_Scheduler_release( api, &lock_context ); - - switch ( policy ) { - case SCHED_OTHER: - case SCHED_FIFO: - case SCHED_RR: - _Thread_Set_priority( the_thread, new_priority, &unused, true ); - break; - - case SCHED_SPORADIC: - _POSIX_Threads_Sporadic_budget_TSR( &api->Sporadic_timer ); - break; - } - - _Objects_Put( &the_thread->Object ); - return 0; - -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: + + cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); + _Thread_State_acquire_critical( the_thread, &lock_context ); + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + if ( api->schedpolicy == SCHED_SPORADIC ) { + _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer ); + } + + api->schedpolicy = policy; + api->schedparam = *param; + api->Attributes.schedpolicy = policy; + api->Attributes.schedparam = *param; + + the_thread->budget_algorithm = budget_algorithm; + the_thread->budget_callout = budget_callout; + + switch ( policy ) { + case SCHED_OTHER: + case SCHED_FIFO: + case SCHED_RR: + the_thread->cpu_time_budget = + rtems_configuration_get_ticks_per_timeslice(); + new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority ); + break; + + case SCHED_SPORADIC: + api->ss_high_priority = api->schedparam.sched_priority; + break; + } + + _Thread_State_release( the_thread, &lock_context ); + + switch ( policy ) { + case SCHED_OTHER: + case SCHED_FIFO: + case SCHED_RR: + _Thread_Set_priority( the_thread, new_priority, &unused, true ); + break; + + case SCHED_SPORADIC: + _POSIX_Threads_Sporadic_budget_TSR( &api->Sporadic_timer ); break; } - return ESRCH; + _Thread_Dispatch_enable( cpu_self ); + return 0; } diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index 18e0f54..b8e0e00 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -719,7 +719,12 @@ struct _Thread_Control { * the following fields * * - POSIX_API_Control::Attributes, + * - POSIX_API_Control::schedparam, + * - POSIX_API_Control::schedpolicy, * - RTEMS_API_Control::Signal, + * - Thread_Control::budget_algorithm, + * - Thread_Control::budget_callout, + * - Thread_Control::cpu_time_budget, * - Thread_Control::current_state, * - Thread_Control::Post_switch_actions, * - Thread_Control::Scheduler::control, and -- 1.8.4.5 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel