summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/threadqops.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-08-02 11:26:56 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-08-03 13:57:30 +0200
commitff2e6c647d166fa54769f3c300855ef7f8020668 (patch)
tree2fe5ea9069fc561d1344e54e0524950aefd86e21 /cpukit/score/src/threadqops.c
parentposix: Fix for RTEMS_DEBUG (diff)
downloadrtems-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.c66
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