From 82f907430887607180211c2eba06c03ae0f175e0 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 21 May 2014 10:30:34 +0200 Subject: score: _Thread_Set_life_protection() Enable usage of _Thread_Set_life_protection() in thread dispatch critical sections. This can be used to enable the thread life-protection with thread dispatching disabled and then enable thread dispatching. --- testsuites/smptests/smpthreadlife01/init.c | 23 ++++++++-- testsuites/sptests/spthreadlife01/init.c | 74 +++++++++++++++++++++++++----- 2 files changed, 80 insertions(+), 17 deletions(-) (limited to 'testsuites') diff --git a/testsuites/smptests/smpthreadlife01/init.c b/testsuites/smptests/smpthreadlife01/init.c index 38b054f41c..0a8b068eee 100644 --- a/testsuites/smptests/smpthreadlife01/init.c +++ b/testsuites/smptests/smpthreadlife01/init.c @@ -182,7 +182,7 @@ static void test_delete(void) } } -static void delay_ipi_task(rtems_task_argument arg) +static void delay_ipi_task(rtems_task_argument variant) { test_context *ctx = &test_instance; rtems_interrupt_level level; @@ -198,12 +198,24 @@ static void delay_ipi_task(rtems_task_argument arg) */ rtems_counter_delay_nanoseconds(100000000); - /* We get deleted as a side effect of enabling the thread life protection */ + if (variant != 0) { + _Thread_Disable_dispatch(); + } + + /* + * We get deleted as a side effect of enabling the thread life protection or + * later if we enable the thread dispatching. + */ _Thread_Set_life_protection(true); + + if (variant != 0) { + _Thread_Enable_dispatch(); + } + rtems_test_assert(0); } -static void test_set_life_protection(void) +static void test_set_life_protection(rtems_task_argument variant) { test_context *ctx = &test_instance; rtems_status_code sc; @@ -222,7 +234,7 @@ static void test_set_life_protection(void) ); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - sc = rtems_task_start(id, delay_ipi_task, 0); + sc = rtems_task_start(id, delay_ipi_task, variant); rtems_test_assert(sc == RTEMS_SUCCESSFUL); _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT); @@ -301,7 +313,8 @@ static void Init(rtems_task_argument arg) if (rtems_get_processor_count() >= CPU_COUNT) { test_restart(); test_delete(); - test_set_life_protection(); + test_set_life_protection(0); + test_set_life_protection(1); test_wait_for_execution_stop(); } diff --git a/testsuites/sptests/spthreadlife01/init.c b/testsuites/sptests/spthreadlife01/init.c index b85b98c165..4e6c98487b 100644 --- a/testsuites/sptests/spthreadlife01/init.c +++ b/testsuites/sptests/spthreadlife01/init.c @@ -19,6 +19,8 @@ #include #include +#include + #include "tmacros.h" #define PRIO_INIT 1 @@ -48,6 +50,12 @@ typedef enum { DELETE_1, DELETE_2, DELETE_3, + SET_PROTECTION, + SET_PROTECTION_DONE, + CLEAR_PROTECTION, + DELETE_4, + DELETE_5, + DELETE_6, INVALID } test_state; @@ -157,8 +165,17 @@ static void delete_extension( assert_priority(PRIO_INIT); - rtems_test_assert(ctx->current == DELETE_2); - ctx->current = DELETE_3; + switch (ctx->current) { + case DELETE_2: + ctx->current = DELETE_3; + break; + case DELETE_5: + ctx->current = DELETE_6; + break; + default: + rtems_test_assert(0); + break; + } } static void terminate_extension(Thread_Control *executing) @@ -179,6 +196,9 @@ static void terminate_extension(Thread_Control *executing) case DELETE_1: ctx->current = DELETE_2; break; + case DELETE_4: + ctx->current = DELETE_5; + break; default: rtems_test_assert(0); break; @@ -192,6 +212,7 @@ static void worker_task(rtems_task_argument arg) while (true) { test_state state = ctx->current; rtems_status_code sc; + bool previous_thread_life_protection; switch (state) { case SET_PRIO: @@ -231,6 +252,19 @@ static void worker_task(rtems_task_argument arg) case RESTART_2: assert_priority(PRIO_HIGH); break; + case SET_PROTECTION: + _Thread_Disable_dispatch(); + previous_thread_life_protection = _Thread_Set_life_protection(true); + rtems_test_assert(!previous_thread_life_protection); + _Thread_Enable_dispatch(); + break; + case CLEAR_PROTECTION: + _Thread_Disable_dispatch(); + previous_thread_life_protection = _Thread_Set_life_protection(false); + rtems_test_assert(previous_thread_life_protection); + ctx->current = DELETE_4; + _Thread_Enable_dispatch(); + break; default: rtems_test_assert(0); break; @@ -255,17 +289,9 @@ static void create_sema(test_context *ctx) rtems_test_assert(sc == RTEMS_SUCCESSFUL); } -static void test(void) +static void create_and_start_worker(test_context *ctx) { - test_context *ctx = &test_instance; rtems_status_code sc; - rtems_resource_snapshot snapshot; - - ctx->main_task_id = rtems_task_self(); - - rtems_resource_snapshot_take(&snapshot); - - create_sema(ctx); sc = rtems_task_create( rtems_build_name('W', 'O', 'R', 'K'), @@ -279,6 +305,20 @@ static void test(void) sc = rtems_task_start(ctx->worker_task_id, worker_task, 0); rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + +static void test(void) +{ + test_context *ctx = &test_instance; + rtems_status_code sc; + rtems_resource_snapshot snapshot; + + ctx->main_task_id = rtems_task_self(); + + rtems_resource_snapshot_take(&snapshot); + + create_sema(ctx); + create_and_start_worker(ctx); change_state_and_wait(ctx, INIT, SET_PRIO, SET_PRIO_DONE); change_state_and_wait(ctx, SET_PRIO_DONE, DO_OBTAIN_0, OBTAIN_DONE_0); @@ -316,7 +356,17 @@ static void test(void) rtems_test_assert(rtems_resource_snapshot_check(&snapshot)); - rtems_test_assert(ctx->current == DELETE_3); + create_and_start_worker(ctx); + + change_state_and_wait(ctx, DELETE_3, SET_PROTECTION, SET_PROTECTION_DONE); + change_state(ctx, SET_PROTECTION_DONE, CLEAR_PROTECTION, INVALID); + + sc = rtems_task_delete(ctx->worker_task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(rtems_resource_snapshot_check(&snapshot)); + + rtems_test_assert(ctx->current == DELETE_6); } static void Init(rtems_task_argument arg) -- cgit v1.2.3