diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-08-02 11:26:56 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-08-03 13:57:30 +0200 |
commit | ff2e6c647d166fa54769f3c300855ef7f8020668 (patch) | |
tree | 2fe5ea9069fc561d1344e54e0524950aefd86e21 /cpukit/score/src/threadqops.c | |
parent | posix: Fix for RTEMS_DEBUG (diff) | |
download | rtems-ff2e6c647d166fa54769f3c300855ef7f8020668.tar.bz2 |
score: Fix and simplify thread wait locks
There was a subtile race condition in _Thread_queue_Do_extract_locked().
It must first update the thread wait flags and then restore the default
thread wait state. In the previous implementation this could lead under
rare timing conditions to an ineffective _Thread_Wait_tranquilize()
resulting to a corrupt system state.
Update #2556.
Diffstat (limited to 'cpukit/score/src/threadqops.c')
-rw-r--r-- | cpukit/score/src/threadqops.c | 66 |
1 files changed, 16 insertions, 50 deletions
diff --git a/cpukit/score/src/threadqops.c b/cpukit/score/src/threadqops.c index 8059446578..d6e42fda8f 100644 --- a/cpukit/score/src/threadqops.c +++ b/cpukit/score/src/threadqops.c @@ -22,50 +22,25 @@ #include <rtems/score/rbtreeimpl.h> #include <rtems/score/schedulerimpl.h> -static void _Thread_queue_Default_priority_change( +static void _Thread_queue_Do_nothing_priority_change( + Thread_queue_Queue *queue, Thread_Control *the_thread, - Priority_Control new_priority, - bool prepend_it, - Thread_queue_Queue *queue + Priority_Control new_priority ) { (void) queue; - - _Scheduler_Thread_set_priority( the_thread, new_priority, prepend_it ); + (void) the_thread; + (void) new_priority; } static void _Thread_queue_Do_nothing_extract( Thread_queue_Queue *queue, - Thread_Control *the_thread -) -{ - /* Do nothing */ -} - -#if defined(RTEMS_SMP) -static void _Thread_queue_Stale_queue_priority_change( - Thread_Control *the_thread, - Priority_Control new_priority, - bool prepend_it, - Thread_queue_Queue *queue + Thread_Control *the_thread ) { - ISR_lock_Context lock_context; - (void) queue; - - /* - * This operation is used to change the priority in case we have a thread - * queue context with a stale thread queue. We own the thread queue lock of - * the former thread queue. In addition, we need the thread wait default - * lock, see _Thread_Wait_restore_default(). - */ - - _Thread_Wait_acquire_default_critical( the_thread, &lock_context ); - _Scheduler_Thread_set_priority( the_thread, new_priority, prepend_it ); - _Thread_Wait_release_default_critical( the_thread, &lock_context ); + (void) the_thread; } -#endif static Thread_queue_Heads *_Thread_queue_Queue_enqueue( Thread_queue_Queue *queue, @@ -216,10 +191,9 @@ static bool _Thread_queue_Priority_less( } static void _Thread_queue_Priority_priority_change( + Thread_queue_Queue *queue, Thread_Control *the_thread, - Priority_Control new_priority, - bool prepend_it, - Thread_queue_Queue *queue + Priority_Control new_priority ) { Thread_queue_Heads *heads = queue->heads; @@ -227,8 +201,6 @@ static void _Thread_queue_Priority_priority_change( _Assert( heads != NULL ); - _Scheduler_Thread_set_priority( the_thread, new_priority, prepend_it ); - priority_queue = _Thread_queue_Priority_queue( heads, the_thread ); _RBTree_Extract( @@ -389,11 +361,12 @@ static void _Thread_queue_Priority_inherit_enqueue( owner->priority_restore_hint = true; _Atomic_Fence( ATOMIC_ORDER_ACQ_REL ); - _Thread_queue_Context_priority_change( - &path->Start.Queue_context, + _Scheduler_Thread_set_priority( owner, priority, false ); + + ( *owner->Wait.operations->priority_change )( + owner->Wait.queue, owner, - priority, - false + priority ); } else { path->update_priority = NULL; @@ -424,7 +397,7 @@ void _Thread_queue_Boost_priority( #endif const Thread_queue_Operations _Thread_queue_Operations_default = { - .priority_change = _Thread_queue_Default_priority_change, + .priority_change = _Thread_queue_Do_nothing_priority_change, .extract = _Thread_queue_Do_nothing_extract /* * The default operations are only used in _Thread_Change_priority() and @@ -434,7 +407,7 @@ const Thread_queue_Operations _Thread_queue_Operations_default = { }; const Thread_queue_Operations _Thread_queue_Operations_FIFO = { - .priority_change = _Thread_queue_Default_priority_change, + .priority_change = _Thread_queue_Do_nothing_priority_change, .enqueue = _Thread_queue_FIFO_enqueue, .extract = _Thread_queue_FIFO_extract, .first = _Thread_queue_FIFO_first @@ -453,10 +426,3 @@ const Thread_queue_Operations _Thread_queue_Operations_priority_inherit = { .extract = _Thread_queue_Priority_extract, .first = _Thread_queue_Priority_first }; - -#if defined(RTEMS_SMP) -const Thread_queue_Operations _Thread_queue_Operations_stale_queue = { - .priority_change = _Thread_queue_Stale_queue_priority_change, - .extract = _Thread_queue_Do_nothing_extract -}; -#endif |