From 9c30c31e24069555a9e3e9ccae0d8af04fba35f5 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 16 Nov 2017 14:38:07 +0100 Subject: score: Fix _Thread_queue_Flush_critical() The thread queue extract operations performed by the _Thread_queue_Flush_critical() may result in a priority change of the thread queue owner. Carry out the scheduler priority update operation. This is especially important in SMP configurations. Close #3236. --- testsuites/smptests/smpmutex01/init.c | 103 +++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 33 deletions(-) (limited to 'testsuites/smptests') diff --git a/testsuites/smptests/smpmutex01/init.c b/testsuites/smptests/smpmutex01/init.c index 7f64415f89..6586788876 100644 --- a/testsuites/smptests/smpmutex01/init.c +++ b/testsuites/smptests/smpmutex01/init.c @@ -38,15 +38,16 @@ typedef enum { REQ_WAKE_UP_HELPER = RTEMS_EVENT_1, REQ_MTX_OBTAIN = RTEMS_EVENT_2, REQ_MTX_OBTAIN_TIMEOUT = RTEMS_EVENT_3, - REQ_MTX_RELEASE = RTEMS_EVENT_4, - REQ_MTX_2_OBTAIN = RTEMS_EVENT_5, - REQ_MTX_2_RELEASE = RTEMS_EVENT_6, - REQ_SEM_OBTAIN_RELEASE = RTEMS_EVENT_7, - REQ_SEM_RELEASE = RTEMS_EVENT_8, - REQ_SET_DONE = RTEMS_EVENT_9, - REQ_WAIT_FOR_DONE = RTEMS_EVENT_10, - REQ_SEND_EVENT_2 = RTEMS_EVENT_11, - REQ_SEND_EVENT_3 = RTEMS_EVENT_12 + REQ_MTX_OBTAIN_UNSATISFIED = RTEMS_EVENT_4, + REQ_MTX_RELEASE = RTEMS_EVENT_5, + REQ_MTX_2_OBTAIN = RTEMS_EVENT_6, + REQ_MTX_2_RELEASE = RTEMS_EVENT_7, + REQ_SEM_OBTAIN_RELEASE = RTEMS_EVENT_8, + REQ_SEM_RELEASE = RTEMS_EVENT_9, + 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 } request_id; typedef enum { @@ -248,6 +249,14 @@ static void obtain_timeout(test_context *ctx) rtems_test_assert(sc == RTEMS_TIMEOUT); } +static void obtain_unsatisfied(test_context *ctx) +{ + rtems_status_code sc; + + sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + rtems_test_assert(sc == RTEMS_UNSATISFIED); +} + static void release(test_context *ctx) { rtems_status_code sc; @@ -256,6 +265,14 @@ static void release(test_context *ctx) rtems_test_assert(sc == RTEMS_SUCCESSFUL); } +static void flush(test_context *ctx) +{ + rtems_status_code sc; + + sc = rtems_semaphore_flush(ctx->mtx); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + static void obtain_2(test_context *ctx) { rtems_status_code sc; @@ -416,6 +433,11 @@ static void worker(rtems_task_argument arg) ++ctx->generation[id]; } + if ((events & REQ_MTX_OBTAIN_UNSATISFIED) != 0) { + obtain_unsatisfied(ctx); + ++ctx->generation[id]; + } + if ((events & REQ_MTX_RELEASE) != 0) { release(ctx); ++ctx->generation[id]; @@ -463,11 +485,14 @@ static void test_init(test_context *ctx) start_task(ctx, A_1, worker, 1, SCHED_A); start_task(ctx, A_2_0, worker, 2, SCHED_A); start_task(ctx, A_2_1, worker, 2, SCHED_A); - start_task(ctx, B_4, worker, 4, SCHED_B); - start_task(ctx, B_5_0, worker, 5, SCHED_B); - start_task(ctx, B_5_1, worker, 5, SCHED_B); start_task(ctx, H_A, helper, 3, SCHED_A); - start_task(ctx, H_B, helper, 6, SCHED_B); + + if (rtems_get_processor_count() >= PART_COUNT) { + start_task(ctx, B_4, worker, 4, SCHED_B); + start_task(ctx, B_5_0, worker, 5, SCHED_B); + start_task(ctx, B_5_1, worker, 5, SCHED_B); + start_task(ctx, H_B, helper, 6, SCHED_B); + } sc = rtems_semaphore_create( rtems_build_name('M', 'T', 'X', '1'), @@ -510,6 +535,19 @@ static void test_simple_inheritance(test_context *ctx) check_generations(ctx, A_1, NONE); } +static void test_flush_inheritance(test_context *ctx) +{ + assert_prio(ctx, M, 3); + obtain(ctx); + send_event(ctx, A_1, REQ_MTX_OBTAIN_UNSATISFIED); + check_generations(ctx, NONE, NONE); + assert_prio(ctx, M, 1); + flush(ctx); + check_generations(ctx, A_1, NONE); + assert_prio(ctx, M, 3); + release(ctx); +} + static void test_dequeue_order_one_scheduler_instance(test_context *ctx) { obtain(ctx); @@ -909,33 +947,32 @@ static void test_omip_yield(test_context *ctx) check_generations(ctx, B_5_0, NONE); } -static void test(void) +static void test(test_context *ctx) { - test_context *ctx = &test_instance; - test_init(ctx); - test_task_get_priority_not_defined(ctx); - test_simple_inheritance(ctx); - test_dequeue_order_one_scheduler_instance(ctx); - test_mixed_queue_two_scheduler_instances(ctx); - test_mixed_queue_two_scheduler_instances_sem_only(ctx); - test_simple_inheritance_two_scheduler_instances(ctx); - test_nested_inheritance_two_scheduler_instances(ctx); - test_dequeue_order_two_scheduler_instances(ctx); - test_omip_pre_emption(ctx); - test_omip_rescue(ctx); - test_omip_timeout(ctx); - test_omip_yield(ctx); + + if (rtems_get_processor_count() >= PART_COUNT) { + test_task_get_priority_not_defined(ctx); + test_simple_inheritance(ctx); + test_dequeue_order_one_scheduler_instance(ctx); + test_mixed_queue_two_scheduler_instances(ctx); + test_mixed_queue_two_scheduler_instances_sem_only(ctx); + test_simple_inheritance_two_scheduler_instances(ctx); + test_nested_inheritance_two_scheduler_instances(ctx); + test_dequeue_order_two_scheduler_instances(ctx); + test_omip_pre_emption(ctx); + test_omip_rescue(ctx); + test_omip_timeout(ctx); + test_omip_yield(ctx); + } + + test_flush_inheritance(ctx); } static void Init(rtems_task_argument arg) { TEST_BEGIN(); - - if (rtems_get_processor_count() >= PART_COUNT) { - test(); - } - + test(&test_instance); TEST_END(); rtems_test_exit(0); } -- cgit v1.2.3