diff options
Diffstat (limited to 'testsuites/smptests/smpthreadlife01/init.c')
-rw-r--r-- | testsuites/smptests/smpthreadlife01/init.c | 169 |
1 files changed, 156 insertions, 13 deletions
diff --git a/testsuites/smptests/smpthreadlife01/init.c b/testsuites/smptests/smpthreadlife01/init.c index 65d8709898..2d0cce5a98 100644 --- a/testsuites/smptests/smpthreadlife01/init.c +++ b/testsuites/smptests/smpthreadlife01/init.c @@ -45,6 +45,11 @@ static test_context test_instance = { .worker_barrier_state = SMP_BARRIER_STATE_INITIALIZER }; +static void barrier(test_context *ctx, SMP_barrier_State *state) +{ + _SMP_barrier_Wait(&ctx->barrier, state, CPU_COUNT); +} + static void restart_extension( Thread_Control *executing, Thread_Control *restarted @@ -74,7 +79,10 @@ static void switch_extension(Thread_Control *executing, Thread_Control *heir) if (ctx->delay_switch_for_executing == executing) { ctx->delay_switch_for_executing = NULL; - _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT); + + /* (A) */ + barrier(ctx, &ctx->worker_barrier_state); + rtems_counter_delay_nanoseconds(100000000); /* Avoid bad profiling statisitics */ @@ -90,7 +98,8 @@ static void worker_task(rtems_task_argument arg) ctx->worker_arg = arg; - _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT); + /* (B) */ + barrier(ctx, &ctx->worker_barrier_state); while (true) { /* Do nothing */ @@ -120,7 +129,8 @@ static void test_restart(void) sc = rtems_task_start(id, worker_task, 0); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT); + /* (B) */ + barrier(ctx, &ctx->main_barrier_state); for (arg = 1; arg < 23; ++arg) { ctx->main_arg = arg; @@ -129,7 +139,8 @@ static void test_restart(void) sc = rtems_task_restart(id, arg); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT); + /* (B) */ + barrier(ctx, &ctx->main_barrier_state); rtems_test_assert(ctx->worker_arg == arg); } @@ -168,7 +179,8 @@ static void test_delete(void) sc = rtems_task_start(id, worker_task, arg); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT); + /* (B) */ + barrier(ctx, &ctx->main_barrier_state); rtems_test_assert(ctx->worker_arg == arg); rtems_test_assert(!ctx->terminated); @@ -190,7 +202,8 @@ static void delay_ipi_task(rtems_task_argument variant) _ISR_Disable_without_giant(level); (void) level; - _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT); + /* (C) */ + barrier(ctx, &ctx->worker_barrier_state); /* * Interrupts are disabled, so the inter-processor interrupt deleting us will @@ -237,7 +250,8 @@ static void test_set_life_protection(rtems_task_argument variant) 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); + /* (C) */ + barrier(ctx, &ctx->main_barrier_state); sc = rtems_task_delete(id); rtems_test_assert(sc == RTEMS_SUCCESSFUL); @@ -256,7 +270,8 @@ static void delay_switch_task(rtems_task_argument arg) ctx->delay_switch_for_executing = _Thread_Get_executing(); - _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT); + /* (D) */ + barrier(ctx, &ctx->worker_barrier_state); sc = rtems_task_delete(RTEMS_SELF); rtems_test_assert(sc == RTEMS_SUCCESSFUL); @@ -284,11 +299,11 @@ static void test_wait_for_execution_stop(void) sc = rtems_task_start(id, delay_switch_task, 0); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - /* Wait for delay switch task */ - _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT); + /* (D) */ + barrier(ctx, &ctx->main_barrier_state); - /* Wait for delay switch extension */ - _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT); + /* (A) */ + barrier(ctx, &ctx->main_barrier_state); sc = rtems_task_create( rtems_build_name('W', 'A', 'I', 'T'), @@ -306,6 +321,131 @@ static void test_wait_for_execution_stop(void) rtems_test_assert(rtems_resource_snapshot_check(&snapshot)); } +static void suspend_task(rtems_task_argument arg) +{ + test_context *ctx = &test_instance; + ISR_Level level; + + _ISR_Disable_without_giant(level); + (void) level; + + /* (E) */ + barrier(ctx, &ctx->worker_barrier_state); + + /* (F) */ + barrier(ctx, &ctx->worker_barrier_state); + + rtems_task_suspend(RTEMS_SELF); + rtems_test_assert(0); +} + +static void event_task(rtems_task_argument arg) +{ + test_context *ctx = &test_instance; + ISR_Level level; + rtems_event_set events; + + _ISR_Disable_without_giant(level); + (void) level; + + /* (E) */ + barrier(ctx, &ctx->worker_barrier_state); + + /* (F) */ + barrier(ctx, &ctx->worker_barrier_state); + + rtems_event_receive( + RTEMS_EVENT_0, + RTEMS_EVENT_ALL | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events + ); + rtems_test_assert(0); +} + +static void system_event_task(rtems_task_argument arg) +{ + test_context *ctx = &test_instance; + ISR_Level level; + rtems_event_set events; + + _ISR_Disable_without_giant(level); + (void) level; + + /* (E) */ + barrier(ctx, &ctx->worker_barrier_state); + + /* (F) */ + barrier(ctx, &ctx->worker_barrier_state); + + rtems_event_system_receive( + RTEMS_EVENT_0, + RTEMS_EVENT_ALL | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events + ); + rtems_test_assert(0); +} + +static void help_task(rtems_task_argument arg) +{ + test_context *ctx = &test_instance; + + /* (F) */ + barrier(ctx, &ctx->main_barrier_state); + + rtems_task_suspend(RTEMS_SELF); + rtems_test_assert(0); +} + +static void test_operation_with_delete_in_progress(rtems_task_entry entry) +{ + test_context *ctx = &test_instance; + rtems_status_code sc; + rtems_id worker_id; + rtems_id help_id; + rtems_resource_snapshot snapshot; + + rtems_resource_snapshot_take(&snapshot); + + sc = rtems_task_create( + rtems_build_name('W', 'O', 'R', 'K'), + 1, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &worker_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start(worker_id, entry, 0); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + /* (E) */ + barrier(ctx, &ctx->main_barrier_state); + + sc = rtems_task_create( + rtems_build_name('H', 'E', 'L', 'P'), + 2, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &help_id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start(help_id, help_task, 0); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_delete(worker_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_delete(help_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(rtems_resource_snapshot_check(&snapshot)); +} + static void Init(rtems_task_argument arg) { TEST_BEGIN(); @@ -316,6 +456,9 @@ static void Init(rtems_task_argument arg) test_set_life_protection(0); test_set_life_protection(1); test_wait_for_execution_stop(); + test_operation_with_delete_in_progress(suspend_task); + test_operation_with_delete_in_progress(event_task); + test_operation_with_delete_in_progress(system_event_task); } TEST_END(); @@ -329,7 +472,7 @@ static void Init(rtems_task_argument arg) #define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT -#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT +#define CONFIGURE_MAXIMUM_TASKS (CPU_COUNT + 1) #define CONFIGURE_INITIAL_EXTENSIONS \ { \ |