From 9555341f0fc309243e1d92f95e4278a7b820f485 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 6 Apr 2016 16:26:22 +0200 Subject: posix: Use a dedicated lock for scheduler changes Update #2555. --- cpukit/posix/include/rtems/posix/pthreadimpl.h | 17 +++++++ cpukit/posix/include/rtems/posix/threadsup.h | 3 ++ cpukit/posix/src/pthread.c | 65 ++++++++++++++++---------- cpukit/posix/src/pthreadcreate.c | 4 +- cpukit/posix/src/pthreadsetschedparam.c | 34 ++++++++------ 5 files changed, 83 insertions(+), 40 deletions(-) (limited to 'cpukit') diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h index 42f10b08bc..ef5821e48f 100644 --- a/cpukit/posix/include/rtems/posix/pthreadimpl.h +++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h @@ -223,6 +223,23 @@ 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 7cd235409c..93ba2c1c7c 100644 --- a/cpukit/posix/include/rtems/posix/threadsup.h +++ b/cpukit/posix/include/rtems/posix/threadsup.h @@ -19,6 +19,7 @@ #define _RTEMS_POSIX_THREADSUP_H #include +#include #include #include #include @@ -51,6 +52,8 @@ 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 12f02df6d1..cf4eab4cc5 100644 --- a/cpukit/posix/src/pthread.c +++ b/cpukit/posix/src/pthread.c @@ -106,39 +106,37 @@ static bool _POSIX_Threads_Sporadic_budget_TSR_filter( */ void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog ) { - uint32_t ticks; POSIX_API_Control *api; Thread_Control *the_thread; - ISR_Level level; + ISR_lock_Context lock_context; + Priority_Control new_priority; api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic_timer ); the_thread = api->thread; - /* ticks is guaranteed to be at least one */ - ticks = _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget ); + _POSIX_Threads_Scheduler_acquire( api, &lock_context ); - the_thread->cpu_time_budget = ticks; + the_thread->cpu_time_budget = + _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget ); + + _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer ); + _Watchdog_Per_CPU_insert_relative( + &api->Sporadic_timer, + _Per_CPU_Get(), + _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period ) + ); + + new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority ); + + _POSIX_Threads_Scheduler_release( api, &lock_context ); _Thread_Change_priority( the_thread, - _POSIX_Priority_To_core( api->schedparam.sched_priority ), + new_priority, NULL, _POSIX_Threads_Sporadic_budget_TSR_filter, true ); - - /* ticks is guaranteed to be at least one */ - ticks = _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period ); - - _Thread_Disable_dispatch(); - _ISR_Disable( level ); - _Watchdog_Per_CPU_insert_relative( - &api->Sporadic_timer, - _Per_CPU_Get(), - ticks - ); - _ISR_Enable( level ); - _Thread_Unnest_dispatch(); } static bool _POSIX_Threads_Sporadic_budget_callout_filter( @@ -202,6 +200,8 @@ 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 ); @@ -244,12 +244,26 @@ static bool _POSIX_Threads_Create_extension( return true; } +static void _POSIX_Threads_Delete_extension( + Thread_Control *executing, + Thread_Control *deleted +) +{ + POSIX_API_Control *api; + + api = deleted->API_Extensions[ THREAD_API_POSIX ]; + + _ISR_lock_Destroy( &api->Scheduler_lock ); + _Thread_queue_Destroy( &api->Join_List ); +} + static void _POSIX_Threads_Terminate_extension( Thread_Control *executing ) { Thread_Control *the_thread; POSIX_API_Control *api; + ISR_lock_Context lock_context; void **value_ptr; api = executing->API_Extensions[ THREAD_API_POSIX ]; @@ -265,12 +279,15 @@ static void _POSIX_Threads_Terminate_extension( *(void **)the_thread->Wait.return_argument = value_ptr; } - if ( api->schedpolicy == SCHED_SPORADIC ) - _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer ); + _Thread_Enable_dispatch(); - _Thread_queue_Destroy( &api->Join_List ); + _POSIX_Threads_Scheduler_acquire( api, &lock_context ); - _Thread_Enable_dispatch(); + if ( api->schedpolicy == SCHED_SPORADIC ) { + _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer ); + } + + _POSIX_Threads_Scheduler_release( api, &lock_context ); } /* @@ -296,7 +313,7 @@ User_extensions_Control _POSIX_Threads_User_extensions = { { _POSIX_Threads_Create_extension, /* create */ NULL, /* start */ NULL, /* restart */ - NULL, /* delete */ + _POSIX_Threads_Delete_extension, /* delete */ NULL, /* switch */ NULL, /* begin */ _POSIX_Threads_Exitted_extension, /* exitted */ diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c index fc07b1f7e1..2533345ff6 100644 --- a/cpukit/posix/src/pthreadcreate.c +++ b/cpukit/posix/src/pthreadcreate.c @@ -247,13 +247,13 @@ int pthread_create( #endif if ( schedpolicy == SCHED_SPORADIC ) { - _ISR_Disable( level ); + _ISR_Disable_without_giant( level ); _Watchdog_Per_CPU_insert_relative( &api->Sporadic_timer, _Per_CPU_Get(), _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period ) ); - _ISR_Enable( level ); + _ISR_Enable_without_giant( level ); } _Thread_Enable_dispatch(); diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c index c9560f59ac..57a2bc8ce1 100644 --- a/cpukit/posix/src/pthreadsetschedparam.c +++ b/cpukit/posix/src/pthreadsetschedparam.c @@ -44,7 +44,8 @@ int pthread_setschedparam( Objects_Locations location; int rc; Priority_Control unused; - ISR_Level level; + ISR_lock_Context lock_context; + Priority_Control new_priority; /* * Check all the parameters @@ -70,10 +71,10 @@ int pthread_setschedparam( case OBJECTS_LOCAL: api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + _POSIX_Threads_Scheduler_acquire( api, &lock_context ); + if ( api->schedpolicy == SCHED_SPORADIC ) { - _ISR_Disable( level ); _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer ); - _ISR_Enable( level ); } api->schedpolicy = policy; @@ -84,26 +85,31 @@ int pthread_setschedparam( the_thread->budget_algorithm = budget_algorithm; the_thread->budget_callout = budget_callout; - switch ( api->schedpolicy ) { + switch ( policy ) { case SCHED_OTHER: case SCHED_FIFO: case SCHED_RR: the_thread->cpu_time_budget = rtems_configuration_get_ticks_per_timeslice(); - - _Thread_Set_priority( - the_thread, - _POSIX_Priority_To_core( api->schedparam.sched_priority ), - &unused, - true - ); + new_priority = + _POSIX_Priority_To_core( api->schedparam.sched_priority ); break; case SCHED_SPORADIC: api->ss_high_priority = api->schedparam.sched_priority; - _ISR_Disable( level ); - _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer ); - _ISR_Enable( level ); + 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; } -- cgit v1.2.3