[rtems-central commit] spec: Add performance requirements
Sebastian Huber
sebh at rtems.org
Fri Nov 26 07:40:41 UTC 2021
Module: rtems-central
Branch: master
Commit: 64942a060989e9d5e7195710ff29809e8c9d2524
Changeset: http://git.rtems.org/rtems-central/commit/?id=64942a060989e9d5e7195710ff29809e8c9d2524
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Thu Nov 25 17:54:12 2021 +0100
spec: Add performance requirements
---
spec/rtems/task/req/perf-construct.yml | 3 +-
spec/rtems/task/req/perf-restart-preempt.yml | 59 ++++++++++++++++
spec/rtems/task/req/perf-restart-self.yml | 53 ++++++++++++++
spec/rtems/task/req/perf-restart.yml | 53 ++++++++++++++
spec/rtems/task/req/perf-set-scheduler-move.yml | 55 +++++++++++++++
spec/rtems/task/req/perf-set-scheduler-nop.yml | 43 ++++++++++++
spec/rtems/task/req/perf-set-scheduler-other.yml | 59 ++++++++++++++++
spec/rtems/task/req/perf-set-scheduler-preempt.yml | 81 ++++++++++++++++++++++
spec/rtems/task/req/perf-start-preempt.yml | 56 +++++++++++++++
spec/rtems/task/req/perf-start.yml | 50 +++++++++++++
spec/rtems/task/val/perf.yml | 61 +++++++++++++++-
11 files changed, 570 insertions(+), 3 deletions(-)
diff --git a/spec/rtems/task/req/perf-construct.yml b/spec/rtems/task/req/perf-construct.yml
index 83ed57d..da8414c 100644
--- a/spec/rtems/task/req/perf-construct.yml
+++ b/spec/rtems/task/req/perf-construct.yml
@@ -15,7 +15,7 @@ references: []
requirement-type: non-functional
test-body:
brief: |
- Construct a task.
+ Construct a worker task.
code: |
ctx->status = rtems_task_construct( &config, &ctx->worker_id );
description: null
@@ -29,6 +29,7 @@ test-teardown:
T_quiet_rsc_success( ctx->status );
DeleteTask( ctx->worker_id );
+ KillZombies();
return tic == toc;
description: null
diff --git a/spec/rtems/task/req/perf-restart-preempt.yml b/spec/rtems/task/req/perf-restart-preempt.yml
new file mode 100644
index 0000000..c0cb7ca
--- /dev/null
+++ b/spec/rtems/task/req/perf-restart-preempt.yml
@@ -0,0 +1,59 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+limits: {}
+links:
+- role: requirement-refinement
+ uid: perf-runtime
+- role: runtime-measurement-request
+ uid: ../val/perf
+non-functional-type: performance-runtime
+params: {}
+rationale: null
+references: []
+requirement-type: non-functional
+test-body:
+ brief: |
+ Restart the worker task.
+ code: |
+ ctx->begin = T_tick();
+ ctx->status = rtems_task_restart(
+ ctx->worker_id,
+ (rtems_task_argument) ctx
+ );
+ description: null
+test-cleanup:
+ brief: |
+ Delete the worker task.
+ code: |
+ DeleteTask( ctx->worker_id );
+ description: null
+test-prepare:
+ brief: |
+ Create and start a worker task.
+ code: |
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+ description: null
+test-setup: null
+test-teardown:
+ brief: |
+ Set the measured runtime. Discard samples interrupted by a clock tick.
+ code: |
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+ description: null
+text: |
+ Let ``U` and `V`` be two tasks with the same home scheduler. Let :math:`B`
+ be a time point measured by ``U`` right before a call to
+ ${../if/restart:/name} which starts task ``V`` which preempts the caller.
+ Let :math:`E` be a time point measured by ``V`` right after the first context
+ switch after :math:`B`.
+
+ While the execution environment is ${.:/environment}, while the measurement
+ sample is :math:`E - B`, the ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/task/req/perf-restart-self.yml b/spec/rtems/task/req/perf-restart-self.yml
new file mode 100644
index 0000000..36bd1e9
--- /dev/null
+++ b/spec/rtems/task/req/perf-restart-self.yml
@@ -0,0 +1,53 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+limits: {}
+links:
+- role: requirement-refinement
+ uid: perf-runtime
+- role: runtime-measurement-request
+ uid: ../val/perf
+non-functional-type: performance-runtime
+params: {}
+rationale: null
+references: []
+requirement-type: non-functional
+test-body:
+ brief: |
+ Restart the worker task.
+ code: |
+ Send( ctx, EVENT_RESTART );
+ description: null
+test-cleanup:
+ brief: |
+ Delete the worker task.
+ code: |
+ DeleteTask( ctx->worker_id );
+ description: null
+test-prepare:
+ brief: |
+ Create and start a worker task.
+ code: |
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+ description: null
+test-setup: null
+test-teardown:
+ brief: |
+ Set the measured runtime. Discard samples interrupted by a clock tick.
+ code: |
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+ description: null
+text: |
+ Let :math:`B` be a time point measured by a task right before a call to
+ ${../if/restart:/name} which restarts the caller. Let :math:`E` be a time
+ point measured by ``V`` right after the first context switch after :math:`B`.
+
+ While the execution environment is ${.:/environment}, while the measurement
+ sample is :math:`E - B`, the ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/task/req/perf-restart.yml b/spec/rtems/task/req/perf-restart.yml
new file mode 100644
index 0000000..1efb9ce
--- /dev/null
+++ b/spec/rtems/task/req/perf-restart.yml
@@ -0,0 +1,53 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+limits: {}
+links:
+- role: requirement-refinement
+ uid: perf-runtime
+- role: runtime-measurement-request
+ uid: ../val/perf
+non-functional-type: performance-runtime
+params: {}
+rationale: null
+references: []
+requirement-type: non-functional
+test-body:
+ brief: |
+ Restart the worker task.
+ code: |
+ ctx->status = rtems_task_restart(
+ ctx->worker_id,
+ (rtems_task_argument) ctx
+ );
+ description: null
+test-cleanup:
+ brief: |
+ Delete the worker task.
+ code: |
+ DeleteTask( ctx->worker_id );
+ description: null
+test-prepare:
+ brief: |
+ Create and start a worker task.
+ code: |
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+ description: null
+test-setup: null
+test-teardown:
+ brief: |
+ Discard samples interrupted by a clock tick.
+ code: |
+ T_quiet_rsc_success( ctx->status );
+
+ return tic == toc;
+ description: null
+text: |
+ While the execution environment is ${.:/environment}, while the measurement
+ sample is the runtime of exactly one successful call to
+ ${../if/restart:/name} which does not preempt the caller, when exactly
+ ${../val/perf:/params/sample-count} samples are collected, the
+ ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/task/req/perf-set-scheduler-move.yml b/spec/rtems/task/req/perf-set-scheduler-move.yml
new file mode 100644
index 0000000..201a5b0
--- /dev/null
+++ b/spec/rtems/task/req/perf-set-scheduler-move.yml
@@ -0,0 +1,55 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: RTEMS_SMP
+limits: {}
+links:
+- role: requirement-refinement
+ uid: perf-runtime
+- role: runtime-measurement-request
+ uid: ../val/perf
+non-functional-type: performance-runtime
+params: {}
+rationale: null
+references: []
+requirement-type: non-functional
+test-body:
+ brief: |
+ Set the scheduler of the runner.
+ code: |
+ ctx->status = rtems_task_set_scheduler(
+ RTEMS_SELF,
+ SCHEDULER_B_ID,
+ PRIO_NORMAL
+ );
+ description: null
+test-cleanup:
+ brief: |
+ Restore the runner affinity.
+ code: |
+ SetSelfAffinityOne( 0 );
+ description: null
+test-prepare:
+ brief: |
+ Set the runner affinity.
+ code: |
+ SetSelfAffinityAll();
+ description: null
+test-setup: null
+test-teardown:
+ brief: |
+ Discard samples interrupted by a clock tick.
+ code: |
+ T_quiet_rsc_success( ctx->status );
+
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
+
+ return tic == toc;
+ description: null
+text: |
+ While the execution environment is ${.:/environment}, while the measurement
+ sample is the runtime of exactly one successful call to
+ ${../if/set-scheduler:/name} which changes the scheduler of the caller, when
+ exactly ${../val/perf:/params/sample-count} samples are collected, the
+ ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/task/req/perf-set-scheduler-nop.yml b/spec/rtems/task/req/perf-set-scheduler-nop.yml
new file mode 100644
index 0000000..8237745
--- /dev/null
+++ b/spec/rtems/task/req/perf-set-scheduler-nop.yml
@@ -0,0 +1,43 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+limits: {}
+links:
+- role: requirement-refinement
+ uid: perf-runtime
+- role: runtime-measurement-request
+ uid: ../val/perf
+non-functional-type: performance-runtime
+params: {}
+rationale: null
+references: []
+requirement-type: non-functional
+test-body:
+ brief: |
+ Set the scheduler of the runner.
+ code: |
+ ctx->status = rtems_task_set_scheduler(
+ RTEMS_SELF,
+ SCHEDULER_A_ID,
+ PRIO_NORMAL
+ );
+ description: null
+test-cleanup: null
+test-prepare: null
+test-setup: null
+test-teardown:
+ brief: |
+ Discard samples interrupted by a clock tick.
+ code: |
+ T_quiet_rsc_success( ctx->status );
+
+ return tic == toc;
+ description: null
+text: |
+ While the execution environment is ${.:/environment}, while the measurement
+ sample is the runtime of exactly one successful call to
+ ${../if/set-scheduler:/name} which does not change the scheduler or priority,
+ when exactly ${../val/perf:/params/sample-count} samples are collected, the
+ ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/task/req/perf-set-scheduler-other.yml b/spec/rtems/task/req/perf-set-scheduler-other.yml
new file mode 100644
index 0000000..fd62875
--- /dev/null
+++ b/spec/rtems/task/req/perf-set-scheduler-other.yml
@@ -0,0 +1,59 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: RTEMS_SMP
+limits: {}
+links:
+- role: requirement-refinement
+ uid: perf-runtime
+- role: runtime-measurement-request
+ uid: ../val/perf
+non-functional-type: performance-runtime
+params: {}
+rationale: null
+references: []
+requirement-type: non-functional
+test-body:
+ brief: |
+ Move the worker to scheduler A.
+ code: |
+ ctx->status = rtems_task_set_scheduler(
+ ctx->worker_id,
+ SCHEDULER_A_ID,
+ PRIO_LOW
+ );
+ description: null
+test-cleanup:
+ brief: |
+ Delete the worker task.
+ code: |
+ DeleteTask( ctx->worker_id );
+ description: null
+test-prepare:
+ brief: |
+ Create and start a worker task for scheduler B.
+ code: |
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_id, Worker, ctx );
+ description: null
+test-setup: null
+test-teardown:
+ brief: |
+ Move the worker back to scheduler B. Discard samples interrupted by a
+ clock tick.
+ code: |
+ T_quiet_rsc_success( ctx->status );
+
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+
+ return tic == toc;
+ description: null
+text: |
+ While the execution environment is ${.:/environment}, while the measurement
+ sample is the runtime of exactly one successful call to
+ ${../if/set-scheduler:/name} which moves the task to the home scheduler of
+ the caller which does not preempt the caller, when exactly
+ ${../val/perf:/params/sample-count} samples are collected, the
+ ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/task/req/perf-set-scheduler-preempt.yml b/spec/rtems/task/req/perf-set-scheduler-preempt.yml
new file mode 100644
index 0000000..9333c02
--- /dev/null
+++ b/spec/rtems/task/req/perf-set-scheduler-preempt.yml
@@ -0,0 +1,81 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: RTEMS_SMP
+limits: {}
+links:
+- role: requirement-refinement
+ uid: perf-runtime
+- role: runtime-measurement-request
+ uid: ../val/perf
+non-functional-type: performance-runtime
+params: {}
+rationale: null
+references: []
+requirement-type: non-functional
+test-body:
+ brief: |
+ Move the worker to scheduler A.
+ code: |
+ ctx->begin = T_tick();
+ ctx->status = rtems_task_set_scheduler(
+ ctx->worker_id,
+ SCHEDULER_A_ID,
+ PRIO_HIGH
+ );
+ description: null
+test-cleanup:
+ brief: |
+ Delete the worker tasks.
+ code: |
+ ResumeTask( ctx->worker_2_id );
+ DeleteTask( ctx->worker_2_id );
+ DeleteTask( ctx->worker_id );
+ description: null
+test-prepare:
+ brief: |
+ Create and start two worker tasks for scheduler B. Make the second worker
+ busy.
+ code: |
+ 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 );
+ description: null
+test-setup:
+ brief: |
+ Move the worker to scheduler B. Make the worker ready to set the end time.
+ code: |
+ ResumeTask( ctx->worker_2_id );
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ Send( ctx, EVENT_SET_END );
+ description: null
+test-teardown:
+ brief: |
+ Set the measured runtime. Discard samples interrupted by a clock tick.
+ code: |
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+ SuspendTask( ctx->worker_2_id );
+
+ return tic == toc;
+ description: null
+text: |
+ Let ``U` and `V`` be two tasks with the distinct home schedulers. Let
+ :math:`B` be a time point measured by ``U`` right before a call to
+ ${../if/set-scheduler:/name} which moves task ``V`` to the home scheduler of
+ ``U`` which preempts the caller. Let :math:`E` be a time point measured by
+ ``V`` right after the first context switch after :math:`B`.
+
+ While the execution environment is ${.:/environment}, while the measurement
+ sample is :math:`E - B`, when exactly ${../val/perf:/params/sample-count}
+ samples are collected, the ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/task/req/perf-start-preempt.yml b/spec/rtems/task/req/perf-start-preempt.yml
new file mode 100644
index 0000000..363a76a
--- /dev/null
+++ b/spec/rtems/task/req/perf-start-preempt.yml
@@ -0,0 +1,56 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+limits: {}
+links:
+- role: requirement-refinement
+ uid: perf-runtime
+- role: runtime-measurement-request
+ uid: ../val/perf
+non-functional-type: performance-runtime
+params: {}
+rationale: null
+references: []
+requirement-type: non-functional
+test-body:
+ brief: |
+ Start the worker task.
+ code: |
+ ctx->begin = T_tick();
+ ctx->status = rtems_task_start(
+ ctx->worker_id,
+ Worker,
+ (rtems_task_argument) ctx
+ );
+ description: null
+test-cleanup: null
+test-prepare: null
+test-setup:
+ brief: |
+ Create a worker task.
+ code: |
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ description: null
+test-teardown:
+ brief: |
+ Set the measured runtime. Delete the worker. Discard samples interrupted by
+ a clock tick.
+ code: |
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+ DeleteTask( ctx->worker_id );
+
+ return tic == toc;
+ description: null
+text: |
+ Let ``U` and `V`` be two tasks with the same home scheduler. Let :math:`B`
+ be a time point measured by ``U`` right before a call to ${../if/start:/name}
+ which starts task ``V`` which preempts the caller. Let :math:`E` be a time
+ point measured by ``V`` right after the first context switch after :math:`B`.
+
+ While the execution environment is ${.:/environment}, while the measurement
+ sample is :math:`E - B`, when exactly ${../val/perf:/params/sample-count}
+ samples are collected, the ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/task/req/perf-start.yml b/spec/rtems/task/req/perf-start.yml
new file mode 100644
index 0000000..d92f509
--- /dev/null
+++ b/spec/rtems/task/req/perf-start.yml
@@ -0,0 +1,50 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+limits: {}
+links:
+- role: requirement-refinement
+ uid: perf-runtime
+- role: runtime-measurement-request
+ uid: ../val/perf
+non-functional-type: performance-runtime
+params: {}
+rationale: null
+references: []
+requirement-type: non-functional
+test-body:
+ brief: |
+ Start the worker task.
+ code: |
+ ctx->status = rtems_task_start(
+ ctx->worker_id,
+ Worker,
+ (rtems_task_argument) ctx
+ );
+ description: null
+test-cleanup: null
+test-prepare: null
+test-setup:
+ brief: |
+ Create a worker task.
+ code: |
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ description: null
+test-teardown:
+ brief: |
+ Delete the worker. Discard samples interrupted by a clock tick.
+ code: |
+ T_quiet_rsc_success( ctx->status );
+
+ DeleteTask( ctx->worker_id );
+
+ return tic == toc;
+ description: null
+text: |
+ While the execution environment is ${.:/environment}, while the measurement
+ sample is the runtime of exactly one successful call to ${../if/start:/name}
+ which does not preempt the caller, when exactly
+ ${../val/perf:/params/sample-count} samples are collected, the
+ ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/task/val/perf.yml b/spec/rtems/task/val/perf.yml
index c8056b3..f299b8b 100644
--- a/spec/rtems/task/val/perf.yml
+++ b/spec/rtems/task/val/perf.yml
@@ -18,6 +18,11 @@ test-context:
member: |
rtems_id worker_id
- brief: |
+ This member provides a second worker identifier.
+ description: null
+ member: |
+ rtems_id worker_2_id
+- brief: |
This member provides a status code.
description: null
member: |
@@ -30,9 +35,22 @@ test-local-includes:
- ts-config.h
- tx-support.h
test-prepare: null
-test-setup: null
+test-setup:
+ brief: |
+ Set the runner priority.
+ code: |
+ SetSelfPriority( PRIO_NORMAL );
+ description: null
test-stop: null
test-support: |
+ typedef ${.:/test-context-type} 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,
@@ -49,6 +67,45 @@ test-support: |
.initial_modes = RTEMS_DEFAULT_MODES,
.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 );
+ }
+ }
+ }
test-target: testsuites/validation/tc-task-performance.c
-test-teardown: null
+test-teardown:
+ brief: |
+ Restore the runner priority.
+ code: |
+ RestoreRunnerPriority();
+ description: null
type: runtime-measurement-test
More information about the vc
mailing list