summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-11-26 08:39:15 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-11-26 08:39:15 +0100
commit9e5c5408bc7f2b41b4c38c74673fbf73dc4a7039 (patch)
tree0c00a5c964a05401a4d1a50bacd158efc7f9cf27
parent915ae266fec004daa1f0b463a5cd364032766a06 (diff)
validation: Performancequal-49
-rw-r--r--testsuites/validation/tc-barrier-performance.c2
-rw-r--r--testsuites/validation/tc-event-performance.c2
-rw-r--r--testsuites/validation/tc-message-performance.c2
-rw-r--r--testsuites/validation/tc-part-performance.c2
-rw-r--r--testsuites/validation/tc-sem-performance.c2
-rw-r--r--testsuites/validation/tc-task-performance.c852
6 files changed, 854 insertions, 8 deletions
diff --git a/testsuites/validation/tc-barrier-performance.c b/testsuites/validation/tc-barrier-performance.c
index 498d13cb69..91573e4c10 100644
--- a/testsuites/validation/tc-barrier-performance.c
+++ b/testsuites/validation/tc-barrier-performance.c
@@ -136,7 +136,7 @@ static void RtemsBarrierValPerf_Setup_Context(
T_measure_runtime_config config;
memset( &config, 0, sizeof( config ) );
- config.sample_count = 1000;
+ config.sample_count = 100;
ctx->request.arg = ctx;
ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
ctx->context = T_measure_runtime_create( &config );
diff --git a/testsuites/validation/tc-event-performance.c b/testsuites/validation/tc-event-performance.c
index 77e690d662..1baefecea5 100644
--- a/testsuites/validation/tc-event-performance.c
+++ b/testsuites/validation/tc-event-performance.c
@@ -159,7 +159,7 @@ static void RtemsEventValPerf_Setup_Context( RtemsEventValPerf_Context *ctx )
T_measure_runtime_config config;
memset( &config, 0, sizeof( config ) );
- config.sample_count = 1000;
+ config.sample_count = 100;
ctx->request.arg = ctx;
ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
ctx->context = T_measure_runtime_create( &config );
diff --git a/testsuites/validation/tc-message-performance.c b/testsuites/validation/tc-message-performance.c
index 28fbd585c2..162c094078 100644
--- a/testsuites/validation/tc-message-performance.c
+++ b/testsuites/validation/tc-message-performance.c
@@ -209,7 +209,7 @@ static void RtemsMessageValPerf_Setup_Context(
T_measure_runtime_config config;
memset( &config, 0, sizeof( config ) );
- config.sample_count = 1000;
+ config.sample_count = 100;
ctx->request.arg = ctx;
ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
ctx->context = T_measure_runtime_create( &config );
diff --git a/testsuites/validation/tc-part-performance.c b/testsuites/validation/tc-part-performance.c
index 474e220f03..4c223910d0 100644
--- a/testsuites/validation/tc-part-performance.c
+++ b/testsuites/validation/tc-part-performance.c
@@ -126,7 +126,7 @@ static void RtemsPartValPerf_Setup_Context( RtemsPartValPerf_Context *ctx )
T_measure_runtime_config config;
memset( &config, 0, sizeof( config ) );
- config.sample_count = 1000;
+ config.sample_count = 100;
ctx->request.arg = ctx;
ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
ctx->context = T_measure_runtime_create( &config );
diff --git a/testsuites/validation/tc-sem-performance.c b/testsuites/validation/tc-sem-performance.c
index f59e9d5c23..5bbff6a587 100644
--- a/testsuites/validation/tc-sem-performance.c
+++ b/testsuites/validation/tc-sem-performance.c
@@ -182,7 +182,7 @@ static void RtemsSemValPerf_Setup_Context( RtemsSemValPerf_Context *ctx )
T_measure_runtime_config config;
memset( &config, 0, sizeof( config ) );
- config.sample_count = 1000;
+ config.sample_count = 100;
ctx->request.arg = ctx;
ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
ctx->context = T_measure_runtime_create( &config );
diff --git a/testsuites/validation/tc-task-performance.c b/testsuites/validation/tc-task-performance.c
index 68037aaf5f..2900ac6ca0 100644
--- a/testsuites/validation/tc-task-performance.c
+++ b/testsuites/validation/tc-task-performance.c
@@ -80,6 +80,11 @@ typedef struct {
rtems_id worker_id;
/**
+ * @brief This member provides a second worker identifier.
+ */
+ rtems_id worker_2_id;
+
+ /**
* @brief This member provides a status code.
*/
rtems_status_code status;
@@ -108,6 +113,14 @@ typedef struct {
static RtemsTaskValPerf_Context
RtemsTaskValPerf_Instance;
+typedef RtemsTaskValPerf_Context Context;
+
+enum {
+ EVENT_RESTART = RTEMS_EVENT_0,
+ EVENT_SET_END = RTEMS_EVENT_1,
+ EVENT_BUSY = RTEMS_EVENT_2
+} Event;
+
RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT ) static char task_storage[
RTEMS_TASK_STORAGE_SIZE(
TEST_MAXIMUM_TLS_SIZE + TEST_MINIMUM_STACK_SIZE,
@@ -125,36 +138,95 @@ static const rtems_task_config config = {
.attributes = RTEMS_DEFAULT_ATTRIBUTES
};
+static void Send( const Context *ctx, rtems_event_set events )
+{
+ SendEvents( ctx->worker_id, events );
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ ctx->end = T_tick();
+
+ while ( true ) {
+ rtems_event_set events;
+ T_ticks ticks;
+
+ events = ReceiveAnyEvents();
+ ticks = T_tick();
+
+ if ( ( events & EVENT_RESTART ) != 0 ) {
+ ctx->begin = T_tick();
+ (void) rtems_task_restart( RTEMS_SELF, (rtems_task_argument) ctx );
+ }
+
+ if ( ( events & EVENT_SET_END ) != 0 ) {
+ ctx->end = ticks;
+ }
+
+ if ( ( events & EVENT_BUSY ) != 0 ) {
+ (void) _CPU_Thread_Idle_body( 0 );
+ }
+ }
+}
+
static void RtemsTaskValPerf_Setup_Context( RtemsTaskValPerf_Context *ctx )
{
T_measure_runtime_config config;
memset( &config, 0, sizeof( config ) );
- config.sample_count = 1000;
+ config.sample_count = 100;
ctx->request.arg = ctx;
ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
ctx->context = T_measure_runtime_create( &config );
T_assert_not_null( ctx->context );
}
+/**
+ * @brief Set the runner priority.
+ */
+static void RtemsTaskValPerf_Setup( RtemsTaskValPerf_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+}
+
static void RtemsTaskValPerf_Setup_Wrap( void *arg )
{
RtemsTaskValPerf_Context *ctx;
ctx = arg;
RtemsTaskValPerf_Setup_Context( ctx );
+ RtemsTaskValPerf_Setup( ctx );
+}
+
+/**
+ * @brief Restore the runner priority.
+ */
+static void RtemsTaskValPerf_Teardown( RtemsTaskValPerf_Context *ctx )
+{
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskValPerf_Teardown_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskValPerf_Teardown( ctx );
}
static T_fixture RtemsTaskValPerf_Fixture = {
.setup = RtemsTaskValPerf_Setup_Wrap,
.stop = NULL,
- .teardown = NULL,
+ .teardown = RtemsTaskValPerf_Teardown_Wrap,
.scope = NULL,
.initial_context = &RtemsTaskValPerf_Instance
};
/**
- * @brief Construct a task.
+ * @brief Construct a worker task.
*/
static void RtemsTaskReqPerfConstruct_Body( RtemsTaskValPerf_Context *ctx )
{
@@ -183,6 +255,7 @@ static bool RtemsTaskReqPerfConstruct_Teardown(
T_quiet_rsc_success( ctx->status );
DeleteTask( ctx->worker_id );
+ KillZombies();
return tic == toc;
}
@@ -202,6 +275,707 @@ static bool RtemsTaskReqPerfConstruct_Teardown_Wrap(
}
/**
+ * @brief Create and start a worker task.
+ */
+static void RtemsTaskReqPerfRestart_Prepare( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+/**
+ * @brief Restart the worker task.
+ */
+static void RtemsTaskReqPerfRestart_Body( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->status = rtems_task_restart(
+ ctx->worker_id,
+ (rtems_task_argument) ctx
+ );
+}
+
+static void RtemsTaskReqPerfRestart_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfRestart_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfRestart_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfRestart_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfRestart_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/**
+ * @brief Delete the worker task.
+ */
+static void RtemsTaskReqPerfRestart_Cleanup( RtemsTaskValPerf_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+}
+
+/**
+ * @brief Create and start a worker task.
+ */
+static void RtemsTaskReqPerfRestartPreempt_Prepare(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+/**
+ * @brief Restart the worker task.
+ */
+static void RtemsTaskReqPerfRestartPreempt_Body(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_task_restart(
+ ctx->worker_id,
+ (rtems_task_argument) ctx
+ );
+}
+
+static void RtemsTaskReqPerfRestartPreempt_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfRestartPreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsTaskReqPerfRestartPreempt_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfRestartPreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfRestartPreempt_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Delete the worker task.
+ */
+static void RtemsTaskReqPerfRestartPreempt_Cleanup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+/**
+ * @brief Create and start a worker task.
+ */
+static void RtemsTaskReqPerfRestartSelf_Prepare(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+/**
+ * @brief Restart the worker task.
+ */
+static void RtemsTaskReqPerfRestartSelf_Body( RtemsTaskValPerf_Context *ctx )
+{
+ Send( ctx, EVENT_RESTART );
+}
+
+static void RtemsTaskReqPerfRestartSelf_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfRestartSelf_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsTaskReqPerfRestartSelf_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfRestartSelf_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfRestartSelf_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/**
+ * @brief Delete the worker task.
+ */
+static void RtemsTaskReqPerfRestartSelf_Cleanup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief Set the runner affinity.
+ */
+static void RtemsTaskReqPerfSetSchedulerMove_Prepare(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ SetSelfAffinityAll();
+}
+
+/**
+ * @brief Set the scheduler of the runner.
+ */
+static void RtemsTaskReqPerfSetSchedulerMove_Body(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->status = rtems_task_set_scheduler(
+ RTEMS_SELF,
+ SCHEDULER_B_ID,
+ PRIO_NORMAL
+ );
+}
+
+static void RtemsTaskReqPerfSetSchedulerMove_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfSetSchedulerMove_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfSetSchedulerMove_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfSetSchedulerMove_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfSetSchedulerMove_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Restore the runner affinity.
+ */
+static void RtemsTaskReqPerfSetSchedulerMove_Cleanup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ SetSelfAffinityOne( 0 );
+}
+#endif
+
+/**
+ * @brief Set the scheduler of the runner.
+ */
+static void RtemsTaskReqPerfSetSchedulerNop_Body(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->status = rtems_task_set_scheduler(
+ RTEMS_SELF,
+ SCHEDULER_A_ID,
+ PRIO_NORMAL
+ );
+}
+
+static void RtemsTaskReqPerfSetSchedulerNop_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfSetSchedulerNop_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfSetSchedulerNop_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfSetSchedulerNop_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfSetSchedulerNop_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief Create and start a worker task for scheduler B.
+ */
+static void RtemsTaskReqPerfSetSchedulerOther_Prepare(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+/**
+ * @brief Move the worker to scheduler A.
+ */
+static void RtemsTaskReqPerfSetSchedulerOther_Body(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->status = rtems_task_set_scheduler(
+ ctx->worker_id,
+ SCHEDULER_A_ID,
+ PRIO_LOW
+ );
+}
+
+static void RtemsTaskReqPerfSetSchedulerOther_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfSetSchedulerOther_Body( ctx );
+}
+
+/**
+ * @brief Move the worker back to scheduler B. Discard samples interrupted by
+ * a clock tick.
+ */
+static bool RtemsTaskReqPerfSetSchedulerOther_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfSetSchedulerOther_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfSetSchedulerOther_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Delete the worker task.
+ */
+static void RtemsTaskReqPerfSetSchedulerOther_Cleanup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+#endif
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief Create and start two worker tasks for scheduler B. Make the second
+ * worker busy.
+ */
+static void RtemsTaskReqPerfSetSchedulerPreempt_Prepare(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_id, Worker, ctx );
+ Send( ctx, EVENT_SET_END );
+ WaitForNextTask( 1, ctx->worker_id );
+
+ ctx->worker_2_id = CreateTask( "WRK2", PRIO_NORMAL );
+ SetScheduler( ctx->worker_2_id, SCHEDULER_B_ID, PRIO_HIGH );
+ StartTask( ctx->worker_2_id, Worker, ctx );
+ SendEvents( ctx->worker_2_id, EVENT_BUSY );
+ SuspendTask( ctx->worker_2_id );
+}
+
+/**
+ * @brief Move the worker to scheduler B. Make the worker ready to set the end
+ * time.
+ */
+static void RtemsTaskReqPerfSetSchedulerPreempt_Setup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ResumeTask( ctx->worker_2_id );
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ Send( ctx, EVENT_SET_END );
+}
+
+static void RtemsTaskReqPerfSetSchedulerPreempt_Setup_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfSetSchedulerPreempt_Setup( ctx );
+}
+
+/**
+ * @brief Move the worker to scheduler A.
+ */
+static void RtemsTaskReqPerfSetSchedulerPreempt_Body(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_task_set_scheduler(
+ ctx->worker_id,
+ SCHEDULER_A_ID,
+ PRIO_HIGH
+ );
+}
+
+static void RtemsTaskReqPerfSetSchedulerPreempt_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfSetSchedulerPreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsTaskReqPerfSetSchedulerPreempt_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+ SuspendTask( ctx->worker_2_id );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfSetSchedulerPreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfSetSchedulerPreempt_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Delete the worker tasks.
+ */
+static void RtemsTaskReqPerfSetSchedulerPreempt_Cleanup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ResumeTask( ctx->worker_2_id );
+ DeleteTask( ctx->worker_2_id );
+ DeleteTask( ctx->worker_id );
+}
+#endif
+
+/**
+ * @brief Create a worker task.
+ */
+static void RtemsTaskReqPerfStart_Setup( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+}
+
+static void RtemsTaskReqPerfStart_Setup_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfStart_Setup( ctx );
+}
+
+/**
+ * @brief Start the worker task.
+ */
+static void RtemsTaskReqPerfStart_Body( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->status = rtems_task_start(
+ ctx->worker_id,
+ Worker,
+ (rtems_task_argument) ctx
+ );
+}
+
+static void RtemsTaskReqPerfStart_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfStart_Body( ctx );
+}
+
+/**
+ * @brief Delete the worker. Discard samples interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfStart_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ DeleteTask( ctx->worker_id );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfStart_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfStart_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/**
+ * @brief Create a worker task.
+ */
+static void RtemsTaskReqPerfStartPreempt_Setup( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+}
+
+static void RtemsTaskReqPerfStartPreempt_Setup_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfStartPreempt_Setup( ctx );
+}
+
+/**
+ * @brief Start the worker task.
+ */
+static void RtemsTaskReqPerfStartPreempt_Body( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_task_start(
+ ctx->worker_id,
+ Worker,
+ (rtems_task_argument) ctx
+ );
+}
+
+static void RtemsTaskReqPerfStartPreempt_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfStartPreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Delete the worker. Discard samples
+ * interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfStartPreempt_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+ DeleteTask( ctx->worker_id );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfStartPreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfStartPreempt_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/**
* @fn void T_case_body_RtemsTaskValPerf( void )
*/
T_TEST_CASE_FIXTURE( RtemsTaskValPerf, &RtemsTaskValPerf_Fixture )
@@ -215,6 +989,78 @@ T_TEST_CASE_FIXTURE( RtemsTaskValPerf, &RtemsTaskValPerf_Fixture )
ctx->request.body = RtemsTaskReqPerfConstruct_Body_Wrap;
ctx->request.teardown = RtemsTaskReqPerfConstruct_Teardown_Wrap;
T_measure_runtime( ctx->context, &ctx->request );
+
+ RtemsTaskReqPerfRestart_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfRestart";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfRestart_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfRestart_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfRestart_Cleanup( ctx );
+
+ RtemsTaskReqPerfRestartPreempt_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfRestartPreempt";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfRestartPreempt_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfRestartPreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfRestartPreempt_Cleanup( ctx );
+
+ RtemsTaskReqPerfRestartSelf_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfRestartSelf";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfRestartSelf_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfRestartSelf_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfRestartSelf_Cleanup( ctx );
+
+ #if defined(RTEMS_SMP)
+ RtemsTaskReqPerfSetSchedulerMove_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfSetSchedulerMove";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfSetSchedulerMove_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfSetSchedulerMove_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfSetSchedulerMove_Cleanup( ctx );
+ #endif
+
+ ctx->request.name = "RtemsTaskReqPerfSetSchedulerNop";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfSetSchedulerNop_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfSetSchedulerNop_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ #if defined(RTEMS_SMP)
+ RtemsTaskReqPerfSetSchedulerOther_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfSetSchedulerOther";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfSetSchedulerOther_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfSetSchedulerOther_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfSetSchedulerOther_Cleanup( ctx );
+ #endif
+
+ #if defined(RTEMS_SMP)
+ RtemsTaskReqPerfSetSchedulerPreempt_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfSetSchedulerPreempt";
+ ctx->request.setup = RtemsTaskReqPerfSetSchedulerPreempt_Setup_Wrap;
+ ctx->request.body = RtemsTaskReqPerfSetSchedulerPreempt_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfSetSchedulerPreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfSetSchedulerPreempt_Cleanup( ctx );
+ #endif
+
+ ctx->request.name = "RtemsTaskReqPerfStart";
+ ctx->request.setup = RtemsTaskReqPerfStart_Setup_Wrap;
+ ctx->request.body = RtemsTaskReqPerfStart_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfStart_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsTaskReqPerfStartPreempt";
+ ctx->request.setup = RtemsTaskReqPerfStartPreempt_Setup_Wrap;
+ ctx->request.body = RtemsTaskReqPerfStartPreempt_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfStartPreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
}
/** @} */