diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-03-17 10:32:20 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-03-17 10:32:57 +0100 |
commit | 8c7eb0039c34b1de7a7e95c856b867857010f2fd (patch) | |
tree | 6d2a4012f34ca2e82828d97fc9d11c63c5d392e4 | |
parent | bsp/qoriq: Add register blocks for T variants (diff) | |
download | rtems-8c7eb0039c34b1de7a7e95c856b867857010f2fd.tar.bz2 |
testsupport: Add worker setup handler
Add rtems_test_parallel_get_task_id().
-rw-r--r-- | cpukit/libmisc/testsupport/test.h | 44 | ||||
-rw-r--r-- | cpukit/libmisc/testsupport/testparallel.c | 39 | ||||
-rw-r--r-- | testsuites/smptests/smpatomic01/init.c | 35 | ||||
-rw-r--r-- | testsuites/tmtests/tmfine01/init.c | 2 |
4 files changed, 96 insertions, 24 deletions
diff --git a/cpukit/libmisc/testsupport/test.h b/cpukit/libmisc/testsupport/test.h index ae6c17e388..497c4b679b 100644 --- a/cpukit/libmisc/testsupport/test.h +++ b/cpukit/libmisc/testsupport/test.h @@ -125,11 +125,27 @@ typedef struct { Atomic_Ulong stop; SMP_barrier_Control barrier; size_t worker_count; + rtems_id worker_ids[32]; rtems_id stop_worker_timer_id; - rtems_id master_id; } rtems_test_parallel_context; /** + * @brief Worker task setup handler. + * + * Called during rtems_test_parallel() to optionally setup a worker task before + * it is started. + * + * @param[in] ctx The parallel context. + * @param[in] worker_index The worker index. + * @param[in] worker_id The worker task identifier. + */ +typedef void (*rtems_test_parallel_worker_setup)( + rtems_test_parallel_context *ctx, + size_t worker_index, + rtems_id worker_id +); + +/** * @brief Basic parallel job description. */ typedef struct { @@ -211,7 +227,7 @@ typedef struct { * @retval false Otherwise. */ static inline bool rtems_test_parallel_stop_job( - rtems_test_parallel_context *ctx + const rtems_test_parallel_context *ctx ) { return _Atomic_Load_ulong(&ctx->stop, ATOMIC_ORDER_RELAXED) != 0; @@ -233,19 +249,37 @@ static inline bool rtems_test_parallel_is_master_worker(size_t worker_index) } /** + * @brief Returns the task identifier for a worker. + * + * @param[in] ctx The parallel context. + * @param[in] worker_index The worker index. + * + * @return The task identifier of the worker. + */ +static inline rtems_id rtems_test_parallel_get_task_id( + const rtems_test_parallel_context *ctx, + size_t worker_index +) +{ + return ctx->worker_ids[worker_index]; +} + +/** * @brief Runs a bunch of jobs in parallel on all processors of the system. * + * The worker tasks inherit the priority of the executing task. + * * There are SMP barriers before and after the job body. * * @param[in] ctx The parallel context. - * @param[in] non_master_worker_priority The task priority for non-master - * workers. + * @param[in] worker_setup Optional handler to setup a worker task before it is + * started. * @param[in] jobs The table of jobs. * @param[in] job_count The count of jobs in the job table. */ void rtems_test_parallel( rtems_test_parallel_context *ctx, - rtems_task_priority non_master_worker_priority, + rtems_test_parallel_worker_setup worker_setup, const rtems_test_parallel_job *jobs, size_t job_count ); diff --git a/cpukit/libmisc/testsupport/testparallel.c b/cpukit/libmisc/testsupport/testparallel.c index c1bdeda9f0..b8dc16c598 100644 --- a/cpukit/libmisc/testsupport/testparallel.c +++ b/cpukit/libmisc/testsupport/testparallel.c @@ -100,36 +100,50 @@ static void worker_task(rtems_task_argument arg) worker_arg warg = *(worker_arg *) arg; rtems_status_code sc; - sc = rtems_event_transient_send(warg.ctx->master_id); + sc = rtems_event_transient_send(warg.ctx->worker_ids[0]); _Assert(sc == RTEMS_SUCCESSFUL); (void) sc; run_tests(warg.ctx, warg.jobs, warg.job_count, warg.worker_index); - rtems_task_delete(RTEMS_SELF); + rtems_task_suspend(RTEMS_SELF); } void rtems_test_parallel( rtems_test_parallel_context *ctx, - rtems_task_priority non_master_worker_priority, + rtems_test_parallel_worker_setup worker_setup, const rtems_test_parallel_job *jobs, size_t job_count ) { rtems_status_code sc; size_t worker_index; + rtems_task_priority worker_priority; _Atomic_Init_ulong(&ctx->stop, 0); _SMP_barrier_Control_initialize(&ctx->barrier); ctx->worker_count = rtems_get_processor_count(); - ctx->master_id = rtems_task_self(); + ctx->worker_ids[0] = rtems_task_self(); + + if (RTEMS_ARRAY_SIZE(ctx->worker_ids) < ctx->worker_count) { + rtems_fatal_error_occurred(0xdeadbeef); + } + + sc = rtems_task_set_priority( + RTEMS_SELF, + RTEMS_CURRENT_PRIORITY, + &worker_priority + ); + if (sc != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(0xdeadbeef); + } sc = rtems_timer_create( rtems_build_name('S', 'T', 'O', 'P'), &ctx->stop_worker_timer_id ); if (sc != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(sc); + rtems_fatal_error_occurred(0xdeadbeef); } for (worker_index = 1; worker_index < ctx->worker_count; ++worker_index) { @@ -143,14 +157,20 @@ void rtems_test_parallel( sc = rtems_task_create( rtems_build_name('W', 'O', 'R', 'K'), - non_master_worker_priority, + worker_priority, RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &worker_id ); if (sc != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(sc); + rtems_fatal_error_occurred(0xdeadbeef); + } + + ctx->worker_ids[worker_index] = worker_id; + + if (worker_setup != NULL) { + (*worker_setup)(ctx, worker_index, worker_id); } sc = rtems_task_start(worker_id, worker_task, (rtems_task_argument) &warg); @@ -162,6 +182,11 @@ void rtems_test_parallel( run_tests(ctx, jobs, job_count, 0); + for (worker_index = 1; worker_index < ctx->worker_count; ++worker_index) { + sc = rtems_task_delete(ctx->worker_ids[worker_index]); + _Assert(sc == RTEMS_SUCCESSFUL); + } + sc = rtems_timer_delete(ctx->stop_worker_timer_id); _Assert(sc == RTEMS_SUCCESSFUL); } diff --git a/testsuites/smptests/smpatomic01/init.c b/testsuites/smptests/smpatomic01/init.c index 0241a019da..72ccdf2806 100644 --- a/testsuites/smptests/smpatomic01/init.c +++ b/testsuites/smptests/smpatomic01/init.c @@ -418,27 +418,40 @@ static const rtems_test_parallel_job test_jobs[] = { .fini = test_atomic_add_fini }, { .init = test_atomic_flag_init, - .body =test_atomic_flag_body, - .fini =test_atomic_flag_fini + .body = test_atomic_flag_body, + .fini = test_atomic_flag_fini }, { .init = test_atomic_sub_init, - .body =test_atomic_sub_body, - .fini =test_atomic_sub_fini + .body = test_atomic_sub_body, + .fini = test_atomic_sub_fini }, { .init = test_atomic_compare_exchange_init, - .body =test_atomic_compare_exchange_body, - .fini =test_atomic_compare_exchange_fini + .body = test_atomic_compare_exchange_body, + .fini = test_atomic_compare_exchange_fini }, { .init = test_atomic_or_and_init, - .body =test_atomic_or_and_body, - .fini =test_atomic_or_and_fini + .body = test_atomic_or_and_body, + .fini = test_atomic_or_and_fini }, { .init = test_atomic_fence_init, - .body =test_atomic_fence_body, - .fini =test_atomic_fence_fini + .body = test_atomic_fence_body, + .fini = test_atomic_fence_fini }, }; +static void setup_worker( + rtems_test_parallel_context *base, + size_t worker_index, + rtems_id worker_id +) +{ + rtems_status_code sc; + rtems_task_priority prio; + + sc = rtems_task_set_priority(worker_id, WORKER_PRIORITY, &prio); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + static void Init(rtems_task_argument arg) { smpatomic01_context *ctx = &test_instance; @@ -447,7 +460,7 @@ static void Init(rtems_task_argument arg) rtems_test_parallel( &ctx->base, - WORKER_PRIORITY, + setup_worker, &test_jobs[0], RTEMS_ARRAY_SIZE(test_jobs) ); diff --git a/testsuites/tmtests/tmfine01/init.c b/testsuites/tmtests/tmfine01/init.c index ed5f42992c..8b2b514b91 100644 --- a/testsuites/tmtests/tmfine01/init.c +++ b/testsuites/tmtests/tmfine01/init.c @@ -438,7 +438,7 @@ static void Init(rtems_task_argument arg) rtems_test_parallel( &ctx->base, - 1, + NULL, &test_jobs[0], RTEMS_ARRAY_SIZE(test_jobs) ); |