From 96ea09ac4c781955c22ee810e3a05669b9a6a00a Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 5 Feb 2021 14:35:56 +0100 Subject: score: Add barrier thread queue operations This fixes a missing decrement of the number of waiting threads during a barrier wait timeout. Close #4230. --- cpukit/include/rtems/score/corebarrierimpl.h | 9 +++++++- cpukit/score/src/corebarrierrelease.c | 3 +-- cpukit/score/src/corebarrierwait.c | 32 +++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 4 deletions(-) (limited to 'cpukit') diff --git a/cpukit/include/rtems/score/corebarrierimpl.h b/cpukit/include/rtems/score/corebarrierimpl.h index c2dfea8f9b..922eb5d28f 100644 --- a/cpukit/include/rtems/score/corebarrierimpl.h +++ b/cpukit/include/rtems/score/corebarrierimpl.h @@ -33,7 +33,14 @@ extern "C" { * @{ */ -#define CORE_BARRIER_TQ_OPERATIONS &_Thread_queue_Operations_FIFO +/** + * @brief These thread queue operations are used for core barriers. + * + * They are a specialization of ::_Thread_queue_Operations_FIFO. The only + * difference is that the extract operation decrements + * CORE_barrier_Control::number_of_waiting_threads. + */ +extern const Thread_queue_Operations _CORE_barrier_Thread_queue_operations; /** * @brief Initializes the core barrier. diff --git a/cpukit/score/src/corebarrierrelease.c b/cpukit/score/src/corebarrierrelease.c index 5d510107d6..3202171e7f 100644 --- a/cpukit/score/src/corebarrierrelease.c +++ b/cpukit/score/src/corebarrierrelease.c @@ -28,10 +28,9 @@ uint32_t _CORE_barrier_Do_flush( Thread_queue_Context *queue_context ) { - the_barrier->number_of_waiting_threads = 0; return _Thread_queue_Flush_critical( &the_barrier->Wait_queue.Queue, - CORE_BARRIER_TQ_OPERATIONS, + &_CORE_barrier_Thread_queue_operations, filter, queue_context ); diff --git a/cpukit/score/src/corebarrierwait.c b/cpukit/score/src/corebarrierwait.c index 3da9b05953..197e0cf405 100644 --- a/cpukit/score/src/corebarrierwait.c +++ b/cpukit/score/src/corebarrierwait.c @@ -23,6 +23,36 @@ #include #include #include +#include + +static void _CORE_barrier_Thread_queue_extract( + Thread_queue_Queue *queue, + Thread_Control *the_thread, + Thread_queue_Context *queue_context +) +{ + CORE_barrier_Control *the_barrier; + + the_barrier = RTEMS_CONTAINER_OF( + queue, + CORE_barrier_Control, + Wait_queue.Queue + ); + --the_barrier->number_of_waiting_threads; + _Thread_queue_FIFO_extract( + &the_barrier->Wait_queue.Queue, + the_thread, + queue_context + ); +} + +const Thread_queue_Operations _CORE_barrier_Thread_queue_operations = { + .priority_actions = _Thread_queue_Do_nothing_priority_actions, + .enqueue = _Thread_queue_FIFO_enqueue, + .extract = _CORE_barrier_Thread_queue_extract, + .surrender = _Thread_queue_FIFO_surrender, + .first = _Thread_queue_FIFO_first +}; Status_Control _CORE_barrier_Seize( CORE_barrier_Control *the_barrier, @@ -52,7 +82,7 @@ Status_Control _CORE_barrier_Seize( ); _Thread_queue_Enqueue( &the_barrier->Wait_queue.Queue, - CORE_BARRIER_TQ_OPERATIONS, + &_CORE_barrier_Thread_queue_operations, executing, queue_context ); -- cgit v1.2.3