diff options
-rw-r--r-- | cpukit/score/src/threadqenqueue.c | 2 | ||||
-rw-r--r-- | cpukit/score/src/threadqflush.c | 7 | ||||
-rw-r--r-- | testsuites/smptests/smpmutex01/init.c | 58 |
3 files changed, 64 insertions, 3 deletions
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c index 62d3671222..f62ec29b02 100644 --- a/cpukit/score/src/threadqenqueue.c +++ b/cpukit/score/src/threadqenqueue.c @@ -568,7 +568,6 @@ bool _Thread_queue_Extract_locked( Thread_queue_Context *queue_context ) { - _Thread_queue_Context_clear_priority_updates( queue_context ); #if defined(RTEMS_MULTIPROCESSING) _Thread_queue_MP_set_callout( the_thread, queue_context ); #endif @@ -627,6 +626,7 @@ void _Thread_queue_Extract( Thread_Control *the_thread ) Thread_queue_Queue *queue; _Thread_queue_Context_initialize( &queue_context ); + _Thread_queue_Context_clear_priority_updates( &queue_context ); _Thread_Wait_acquire( the_thread, &queue_context ); queue = the_thread->Wait.queue; diff --git a/cpukit/score/src/threadqflush.c b/cpukit/score/src/threadqflush.c index ef4d6b1f09..4310e06edf 100644 --- a/cpukit/score/src/threadqflush.c +++ b/cpukit/score/src/threadqflush.c @@ -92,6 +92,13 @@ size_t _Thread_queue_Flush_critical( break; } + /* + * We do not have enough space in the queue context to collect all priority + * updates, so clear it each time. We unconditionally do the priority + * update for the owner later if it exists. + */ + _Thread_queue_Context_clear_priority_updates( queue_context ); + do_unblock = _Thread_queue_Extract_locked( queue, operations, diff --git a/testsuites/smptests/smpmutex01/init.c b/testsuites/smptests/smpmutex01/init.c index 6586788876..3cf068d809 100644 --- a/testsuites/smptests/smpmutex01/init.c +++ b/testsuites/smptests/smpmutex01/init.c @@ -47,7 +47,9 @@ typedef enum { REQ_SET_DONE = RTEMS_EVENT_10, REQ_WAIT_FOR_DONE = RTEMS_EVENT_11, REQ_SEND_EVENT_2 = RTEMS_EVENT_12, - REQ_SEND_EVENT_3 = RTEMS_EVENT_13 + REQ_SEND_EVENT_3 = RTEMS_EVENT_13, + REQ_CEIL_OBTAIN = RTEMS_EVENT_14, + REQ_CEIL_RELEASE = RTEMS_EVENT_15 } request_id; typedef enum { @@ -67,6 +69,7 @@ typedef struct { rtems_id mtx; rtems_id mtx_2; rtems_id sem; + rtems_id ceil; rtems_id tasks[TASK_COUNT]; Atomic_Uint done; task_id id_2; @@ -305,6 +308,22 @@ static void sem_release(test_context *ctx) rtems_test_assert(sc == RTEMS_SUCCESSFUL); } +static void ceil_obtain(test_context *ctx) +{ + rtems_status_code sc; + + sc = rtems_semaphore_obtain(ctx->ceil, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + +static void ceil_release(test_context *ctx) +{ + rtems_status_code sc; + + sc = rtems_semaphore_release(ctx->ceil); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + static void wait(void) { rtems_status_code sc; @@ -467,6 +486,16 @@ static void worker(rtems_task_argument arg) send_event(ctx, ctx->id_3, ctx->events_3); } + if ((events & REQ_CEIL_OBTAIN) != 0) { + ceil_obtain(ctx); + ++ctx->generation[id]; + } + + if ((events & REQ_CEIL_RELEASE) != 0) { + ceil_release(ctx); + ++ctx->generation[id]; + } + if ((events & REQ_SET_DONE) != 0) { set_done(ctx); } @@ -520,6 +549,15 @@ static void test_init(test_context *ctx) &ctx->sem ); rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_semaphore_create( + rtems_build_name('C', 'E', 'I', 'L'), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING, + 1, + &ctx->ceil + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); } static void test_simple_inheritance(test_context *ctx) @@ -548,6 +586,21 @@ static void test_flush_inheritance(test_context *ctx) release(ctx); } +static void test_ceiling_mutex(test_context *ctx) +{ + assert_prio(ctx, M, 3); + ceil_obtain(ctx); + assert_prio(ctx, M, 1); + send_event(ctx, A_1, REQ_CEIL_OBTAIN); + yield(); + check_generations(ctx, NONE, NONE); + ceil_release(ctx); + check_generations(ctx, A_1, NONE); + assert_prio(ctx, M, 3); + send_event(ctx, A_1, REQ_CEIL_RELEASE); + check_generations(ctx, A_1, NONE); +} + static void test_dequeue_order_one_scheduler_instance(test_context *ctx) { obtain(ctx); @@ -967,6 +1020,7 @@ static void test(test_context *ctx) } test_flush_inheritance(ctx); + test_ceiling_mutex(ctx); } static void Init(rtems_task_argument arg) @@ -1000,7 +1054,7 @@ RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b); #define CONFIGURE_MAXIMUM_TASKS TASK_COUNT -#define CONFIGURE_MAXIMUM_SEMAPHORES 3 +#define CONFIGURE_MAXIMUM_SEMAPHORES 4 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION |