[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