[rtems-central commit] spec: Add performance requirements

Sebastian Huber sebh at rtems.org
Thu Nov 25 10:28:43 UTC 2021


Module:    rtems-central
Branch:    master
Commit:    9d7f2a1cf614ce4d55bdf5ade4c25424570dae44
Changeset: http://git.rtems.org/rtems-central/commit/?id=9d7f2a1cf614ce4d55bdf5ade4c25424570dae44

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Nov 25 10:03:22 2021 +0100

spec: Add performance requirements

---

 spec/rtems/event/req/perf-isr-preempt.yml          |  46 +++++++
 spec/rtems/event/req/perf-other-cpu.yml            |  59 +++++++++
 spec/rtems/event/req/perf-other-not-satisfied.yml  |  42 +++++++
 spec/rtems/event/req/perf-other-preempt.yml        |  47 ++++++++
 spec/rtems/event/req/perf-other.yml                |  47 ++++++++
 spec/rtems/event/val/perf.yml                      |  73 ++++++++++-
 spec/rtems/message/req/perf-receive-try.yml        |  48 ++++++++
 .../message/req/perf-receive-wait-forever.yml      |  63 ++++++++++
 spec/rtems/message/req/perf-receive-wait-timed.yml |  63 ++++++++++
 spec/rtems/message/req/perf-send-other-cpu.yml     |  72 +++++++++++
 spec/rtems/message/req/perf-send-other.yml         |  54 +++++++++
 spec/rtems/message/req/perf-send-preempt.yml       |  59 +++++++++
 spec/rtems/message/req/perf-send.yml               |  52 ++++++++
 spec/rtems/message/val/perf.yml                    | 133 ++++++++++++++++++++-
 .../sem/req/perf-mtx-pi-release-other-cpu.yml      |  14 +--
 spec/rtems/sem/req/perf-mtx-pi-release-preempt.yml |  17 +--
 spec/rtems/sem/req/perf-mtx-pi-wait-forever.yml    |   9 +-
 spec/rtems/sem/req/perf-mtx-pi-wait-timed.yml      |   9 +-
 18 files changed, 876 insertions(+), 31 deletions(-)

diff --git a/spec/rtems/event/req/perf-isr-preempt.yml b/spec/rtems/event/req/perf-isr-preempt.yml
new file mode 100644
index 0000000..ece8849
--- /dev/null
+++ b/spec/rtems/event/req/perf-isr-preempt.yml
@@ -0,0 +1,46 @@
+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: |
+    Send two events from with interrupt context.  Satisfy the event condition.
+  code: |
+    CallWithinISR( Satisfy, ctx );
+  description: null
+test-cleanup: null
+test-prepare: 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` be an interrupt service and `V`` be a task which both execute on the
+  same processor.  Let :math:`B` be a time point measured by ``U`` right before
+  a call to ${../if/send:/name} which unblocks task ``V`` which preempts the
+  executing task.  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 task ``V`` waits
+  for events, 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/event/req/perf-other-cpu.yml b/spec/rtems/event/req/perf-other-cpu.yml
new file mode 100644
index 0000000..ccc2dae
--- /dev/null
+++ b/spec/rtems/event/req/perf-other-cpu.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: |
+    Send two events.  Satisfy the event condition.
+  code: |
+    ctx->begin = T_tick();
+    ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
+  description: null
+test-cleanup:
+  brief: |
+    Move worker to scheduler A.
+  code: |
+    SetScheduler( ctx->worker_id, SCHEDULER_A_ID, PRIO_HIGH );
+  description: null
+test-prepare:
+  brief: |
+    Move worker to scheduler B.
+  code: |
+    SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+  description: null
+test-setup: null
+test-teardown:
+  brief: |
+    Set the measured runtime.  Make sure the worker waits for the next event.
+    Discard samples interrupted by a clock tick.
+  code: |
+    T_quiet_rsc_success( ctx->status );
+
+    *delta = ctx->end - ctx->begin;
+    WaitForNextTask( 1, ctx->worker_id );
+
+    return tic == toc;
+  description: null
+text: |
+  Let ``U` and `V`` be two tasks with distinct home schedulers.  Let :math:`B`
+  be a time point measured by ``U`` right before a call to ${../if/send:/name}
+  which does satisfy the event condition of the waiting task ``V`` which is
+  scheduled on another processor.  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 task ``V``
+  waits for events, 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/event/req/perf-other-not-satisfied.yml b/spec/rtems/event/req/perf-other-not-satisfied.yml
new file mode 100644
index 0000000..134f10f
--- /dev/null
+++ b/spec/rtems/event/req/perf-other-not-satisfied.yml
@@ -0,0 +1,42 @@
+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: |
+    Send an event.  Do not satisfy the event condition.
+  code: |
+    ctx->status = rtems_event_send( ctx->worker_id, EVENT_OTHER );
+  description: null
+test-cleanup: null
+test-prepare: null
+test-setup: null
+test-teardown:
+  brief: |
+    Let the worker wait for the next set of events.  Discard samples
+    interrupted by a clock tick.
+  code: |
+    T_quiet_rsc_success( ctx->status );
+
+    Send( ctx, EVENT_END );
+
+    return tic == toc;
+  description: null
+text: |
+  While the execution environment is ${.:/environment}, while a task waits for
+  events, while the measurement sample is the runtime of exactly one successful
+  call to ${../if/send:/name} which does not satisfy the event condition of the
+  waiting task, when exactly ${../val/perf:/params/sample-count} samples are
+  collected, the ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/event/req/perf-other-preempt.yml b/spec/rtems/event/req/perf-other-preempt.yml
new file mode 100644
index 0000000..801a7c5
--- /dev/null
+++ b/spec/rtems/event/req/perf-other-preempt.yml
@@ -0,0 +1,47 @@
+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: |
+    Send two events.  Satisfy the event condition.
+  code: |
+    ctx->begin = T_tick();
+    ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
+  description: null
+test-cleanup: null
+test-prepare: 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/send:/name}
+  which does satisfy the event condition of the waiting task ``V`` which does
+  preempt 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 task ``V``
+  waits for events, 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/event/req/perf-other.yml b/spec/rtems/event/req/perf-other.yml
new file mode 100644
index 0000000..e81dcf0
--- /dev/null
+++ b/spec/rtems/event/req/perf-other.yml
@@ -0,0 +1,47 @@
+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: |
+    Send two events.  Satisfy the event condition.
+  code: |
+    ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
+  description: null
+test-cleanup: null
+test-prepare: null
+test-setup:
+  brief: |
+    Lower the worker priority.
+  code: |
+    SetPriority( ctx->worker_id, PRIO_LOW );
+  description: null
+test-teardown:
+  brief: |
+    Restore the worker priority.  Discard samples interrupted by a clock tick.
+  code: |
+    T_quiet_rsc_success( ctx->status );
+
+    SetPriority( ctx->worker_id, PRIO_HIGH );
+
+    return tic == toc;
+  description: null
+text: |
+  While the execution environment is ${.:/environment}, while a task waits for
+  events, while the measurement sample is the runtime of exactly one successful
+  call to ${../if/send:/name} which does satisfy the event condition of the
+  waiting task 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/event/val/perf.yml b/spec/rtems/event/val/perf.yml
index 64a8a01..522fa3e 100644
--- a/spec/rtems/event/val/perf.yml
+++ b/spec/rtems/event/val/perf.yml
@@ -13,6 +13,11 @@ test-brief: |
 test-cleanup: null
 test-context:
 - brief: |
+    This member provides a worker identifier.
+  description: null
+  member: |
+    rtems_id worker_id
+- brief: |
     This member provides a status code.
   description: null
   member: |
@@ -21,11 +26,71 @@ test-context-support: null
 test-description: null
 test-includes:
 - rtems.h
-test-local-includes: []
+test-local-includes:
+- tx-support.h
 test-prepare: null
-test-setup: null
+test-setup:
+  brief: |
+    Create a mutex and a worker task.
+  code: |
+    SetSelfPriority( PRIO_NORMAL );
+    ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+    StartTask( ctx->worker_id, Worker, ctx );
+  description: null
 test-stop: null
-test-support: null
+test-support: |
+  typedef ${.:/test-context-type} Context;
+
+  typedef enum {
+    EVENT_END = RTEMS_EVENT_0,
+    EVENT_OTHER = RTEMS_EVENT_1
+  } Event;
+
+  static void Send( const Context *ctx, rtems_event_set events )
+  {
+    SendEvents( ctx->worker_id, events );
+  }
+
+  static void Satisfy( void *arg )
+  {
+    Context *ctx;
+
+    ctx = arg;
+    ctx->begin = T_tick();
+    ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
+  }
+
+  static void Worker( rtems_task_argument arg )
+  {
+    Context *ctx;
+
+    ctx = (Context *) arg;
+
+    while ( true ) {
+      rtems_event_set   events;
+      rtems_status_code sc;
+      T_ticks           ticks;
+
+      sc = rtems_event_receive(
+        EVENT_END | EVENT_OTHER,
+        RTEMS_EVENT_ALL | RTEMS_WAIT,
+        RTEMS_NO_TIMEOUT,
+        &events
+      );
+      ticks = T_tick();
+      T_quiet_rsc_success( sc );
+
+      if ( ( events & EVENT_END ) != 0 ) {
+        ctx->end = ticks;
+      }
+    }
+  }
 test-target: testsuites/validation/tc-event-performance.c
-test-teardown: null
+test-teardown:
+  brief: |
+    Delete the worker task and the mutex.
+  code: |
+    DeleteTask( ctx->worker_id );
+    RestoreRunnerPriority();
+  description: null
 type: runtime-measurement-test
diff --git a/spec/rtems/message/req/perf-receive-try.yml b/spec/rtems/message/req/perf-receive-try.yml
new file mode 100644
index 0000000..8f82458
--- /dev/null
+++ b/spec/rtems/message/req/perf-receive-try.yml
@@ -0,0 +1,48 @@
+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: |
+    Try to receive a message.
+  code: |
+    uint64_t message;
+    size_t   size;
+
+    ctx->status = rtems_message_queue_receive(
+      ctx->queue_id,
+      &message,
+      &size,
+      RTEMS_NO_WAIT,
+      0
+    );
+  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( ctx->status, RTEMS_UNSATISFIED );
+
+    return tic == toc;
+  description: null
+text: |
+  While the execution environment is ${.:/environment}, while a message queue
+  is empty, while the measurement sample is the runtime of exactly one
+  unsatisfied call to ${../if/send:/name}, when exactly
+  ${../val/perf:/params/sample-count} samples are collected, the
+  ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/message/req/perf-receive-wait-forever.yml b/spec/rtems/message/req/perf-receive-wait-forever.yml
new file mode 100644
index 0000000..953d131
--- /dev/null
+++ b/spec/rtems/message/req/perf-receive-wait-forever.yml
@@ -0,0 +1,63 @@
+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: |
+    Receive a message.  Wait forever.
+  code: |
+    uint64_t message;
+    size_t   size;
+
+    ctx->status = rtems_message_queue_receive(
+      ctx->queue_id,
+      &message,
+      &size,
+      RTEMS_WAIT,
+      RTEMS_NO_TIMEOUT
+    );
+  description: null
+test-cleanup: null
+test-prepare: null
+test-setup:
+  brief: |
+    Schedule a message send.
+  code: |
+    SetPriority( ctx->worker_id, PRIO_LOW );
+    Send( ctx, EVENT_END | EVENT_SEND );
+  description: null
+test-teardown:
+  brief: |
+    Set the measured runtime.  Restore the worker priority.  Discard samples
+    interrupted by a clock tick.
+  code: |
+    T_quiet_rsc_success( ctx->status );
+
+    *delta = ctx->end - ctx->begin;
+    SetPriority( ctx->worker_id, PRIO_HIGH );
+
+    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/receive:/name} which blocks on the message queue with no timeout.
+  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 a message queue
+  is empty, 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/message/req/perf-receive-wait-timed.yml b/spec/rtems/message/req/perf-receive-wait-timed.yml
new file mode 100644
index 0000000..169113e
--- /dev/null
+++ b/spec/rtems/message/req/perf-receive-wait-timed.yml
@@ -0,0 +1,63 @@
+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: |
+    Receive a message.  Wait with a timeout.
+  code: |
+    uint64_t message;
+    size_t   size;
+
+    ctx->status = rtems_message_queue_receive(
+      ctx->queue_id,
+      &message,
+      &size,
+      RTEMS_WAIT,
+      UINT32_MAX
+    );
+  description: null
+test-cleanup: null
+test-prepare: null
+test-setup:
+  brief: |
+    Schedule a message send.
+  code: |
+    SetPriority( ctx->worker_id, PRIO_LOW );
+    Send( ctx, EVENT_END | EVENT_SEND );
+  description: null
+test-teardown:
+  brief: |
+    Set the measured runtime.  Restore the worker priority.  Discard samples
+    interrupted by a clock tick.
+  code: |
+    T_quiet_rsc_success( ctx->status );
+
+    *delta = ctx->end - ctx->begin;
+    SetPriority( ctx->worker_id, PRIO_HIGH );
+
+    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/receive:/name} which blocks on the message queue with a timeout.  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 a message queue
+  is empty, 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/message/req/perf-send-other-cpu.yml b/spec/rtems/message/req/perf-send-other-cpu.yml
new file mode 100644
index 0000000..5fc8b9d
--- /dev/null
+++ b/spec/rtems/message/req/perf-send-other-cpu.yml
@@ -0,0 +1,72 @@
+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: |
+    Send a message.
+  code: |
+    uint64_t message;
+
+    ctx->begin = T_tick();
+    ctx->status = rtems_message_queue_send(
+      ctx->queue_id,
+      &message,
+      sizeof( message )
+    );
+  description: null
+test-cleanup:
+  brief: |
+    Move worker to scheduler A.
+  code: |
+    SetScheduler( ctx->worker_id, SCHEDULER_A_ID, PRIO_HIGH );
+  description: null
+test-prepare:
+  brief: |
+    Move worker to scheduler B.
+  code: |
+    SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+  description: null
+test-setup:
+  brief: |
+    Let the worker wait on the message queue.
+  code: |
+    Send( ctx, EVENT_RECEIVE | EVENT_RECEIVE_END );
+    WaitForNextTask( 1, ctx->worker_id );
+  description: null
+test-teardown:
+  brief: |
+    Set the measured runtime.  Make sure the worker waits for the next event.
+    Discard samples interrupted by a clock tick.
+  code: |
+    T_quiet_rsc_success( ctx->status );
+
+    *delta = ctx->end - ctx->begin;
+    WaitForNextTask( 1, ctx->worker_id );
+
+    return tic == toc;
+  description: null
+text: |
+  Let ``U` and `V`` be two tasks with distinct home schedulers.  Let :math:`B`
+  be a time point measured by ``U`` right before a call to ${../if/send:/name}
+  which unblocks the waiting task ``V`` which is scheduled on another
+  processor.  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 a message queue
+  is empty, while only task ``V`` waits on the message queue, 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/message/req/perf-send-other.yml b/spec/rtems/message/req/perf-send-other.yml
new file mode 100644
index 0000000..53f9eee
--- /dev/null
+++ b/spec/rtems/message/req/perf-send-other.yml
@@ -0,0 +1,54 @@
+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: |
+    Send a message.
+  code: |
+    uint64_t message;
+
+    ctx->status = rtems_message_queue_send(
+      ctx->queue_id,
+      &message,
+      sizeof( message )
+    );
+  description: null
+test-cleanup: null
+test-prepare: null
+test-setup:
+  brief: |
+    Let the worker wait on the message queue.
+  code: |
+    Send( ctx, EVENT_RECEIVE );
+    SetPriority( ctx->worker_id, PRIO_LOW );
+  description: null
+test-teardown:
+  brief: |
+    Restore the worker priority.  Discard samples interrupted by a clock tick.
+  code: |
+    T_quiet_rsc_success( ctx->status );
+
+    SetPriority( ctx->worker_id, PRIO_HIGH );
+
+    return tic == toc;
+  description: null
+text: |
+  While the execution environment is ${.:/environment}, while a message queue
+  is empty, while exactly one task waits on the message queue, while the
+  measurement sample is the runtime of exactly one successful call to
+  ${../if/send:/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/message/req/perf-send-preempt.yml b/spec/rtems/message/req/perf-send-preempt.yml
new file mode 100644
index 0000000..210a1b5
--- /dev/null
+++ b/spec/rtems/message/req/perf-send-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: |
+    Send a message.
+  code: |
+    uint64_t message;
+
+    ctx->begin = T_tick();
+    ctx->status = rtems_message_queue_send(
+      ctx->queue_id,
+      &message,
+      sizeof( message )
+    );
+  description: null
+test-cleanup: null
+test-prepare: null
+test-setup:
+  brief: |
+    Let the worker wait on the message queue.
+  code: |
+    Send( ctx, EVENT_RECEIVE | EVENT_RECEIVE_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;
+
+    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/send:/name}
+  which unblocks the waiting task ``V`` which does preempt 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 a message queue
+  is empty, while only task ``V`` waits on the message queue, 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/message/req/perf-send.yml b/spec/rtems/message/req/perf-send.yml
new file mode 100644
index 0000000..7f0d93f
--- /dev/null
+++ b/spec/rtems/message/req/perf-send.yml
@@ -0,0 +1,52 @@
+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: |
+    Send a message.
+  code: |
+    uint64_t message;
+
+    ctx->status = rtems_message_queue_send(
+      ctx->queue_id,
+      &message,
+      sizeof( message )
+    );
+  description: null
+test-cleanup: null
+test-prepare: null
+test-setup: null
+test-teardown:
+  brief: |
+    Flush the message queue.  Discard samples interrupted by a clock tick.
+  code: |
+    rtems_status_code sc;
+    uint32_t          count;
+
+    T_quiet_rsc_success( ctx->status );
+
+    sc = rtems_message_queue_flush( ctx->queue_id, &count );
+    T_quiet_rsc_success( sc );
+    T_quiet_eq_u32( count, 1 );
+
+    return tic == toc;
+  description: null
+text: |
+  While the execution environment is ${.:/environment}, while a message queue
+  is empty, while no task waits on the message queue, while the measurement
+  sample is the runtime of exactly one successful call to ${../if/send:/name},
+  when exactly ${../val/perf:/params/sample-count} samples are collected, the
+  ${.:/limit-kind} shall be ${.:/limit-condition}.
+type: requirement
diff --git a/spec/rtems/message/val/perf.yml b/spec/rtems/message/val/perf.yml
index f612cdf..4237ebb 100644
--- a/spec/rtems/message/val/perf.yml
+++ b/spec/rtems/message/val/perf.yml
@@ -13,6 +13,16 @@ test-brief: |
 test-cleanup: null
 test-context:
 - brief: |
+    This member provides a message queue identifier.
+  description: null
+  member: |
+    rtems_id queue_id
+- brief: |
+    This member provides a worker identifier.
+  description: null
+  member: |
+    rtems_id worker_id
+- brief: |
     This member provides a status code.
   description: null
   member: |
@@ -21,11 +31,126 @@ test-context-support: null
 test-description: null
 test-includes:
 - rtems.h
-test-local-includes: []
+test-local-includes:
+- tx-support.h
 test-prepare: null
-test-setup: null
+test-setup:
+  brief: |
+    Create a message queue and a worker task.
+  code: |
+    rtems_status_code sc;
+
+    SetSelfPriority( PRIO_NORMAL );
+
+    sc = rtems_message_queue_construct( &config, &ctx->queue_id );
+    T_rsc_success( sc );
+
+    ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+    StartTask( ctx->worker_id, Worker, ctx );
+  description: null
 test-stop: null
-test-support: null
+test-support: |
+  #define MAXIMUM_PENDING_MESSAGES 1
+
+  #define MAXIMUM_MESSAGE_SIZE 8
+
+  typedef ${.:/test-context-type} Context;
+
+  typedef enum {
+    EVENT_END = RTEMS_EVENT_0,
+    EVENT_SEND = RTEMS_EVENT_1,
+    EVENT_SEND_END = RTEMS_EVENT_2,
+    EVENT_RECEIVE = RTEMS_EVENT_3,
+    EVENT_RECEIVE_END = RTEMS_EVENT_4
+  } Event;
+
+  static RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE )
+    storage_area[ MAXIMUM_PENDING_MESSAGES ];
+
+  rtems_message_queue_config config = {
+    .name = OBJECT_NAME,
+    .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES,
+    .maximum_message_size = MAXIMUM_MESSAGE_SIZE,
+    .storage_area = storage_area,
+    .storage_size = sizeof( storage_area )
+  };
+
+  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;
+
+    while ( true ) {
+      rtems_event_set   events;
+      rtems_status_code sc;
+      T_ticks           ticks;
+      uint64_t          message;
+
+      sc = rtems_event_receive(
+        RTEMS_ALL_EVENTS,
+        RTEMS_EVENT_ANY | RTEMS_WAIT,
+        RTEMS_NO_TIMEOUT,
+        &events
+      );
+      ticks = T_tick();
+      T_quiet_rsc_success( sc );
+
+      if ( ( events & EVENT_END ) != 0 ) {
+        ctx->end = ticks;
+      }
+
+      if ( ( events & EVENT_SEND ) != 0 ) {
+        message = 0;
+        sc = rtems_message_queue_send(
+          ctx->queue_id,
+          &message,
+          sizeof( message )
+        );
+        ticks = T_tick();
+        T_quiet_rsc_success( sc );
+
+        if ( ( events & EVENT_SEND_END ) != 0 ) {
+          ctx->end = ticks;
+        }
+      }
+
+      if ( ( events & EVENT_RECEIVE ) != 0 ) {
+        size_t size;
+
+        sc = rtems_message_queue_receive(
+          ctx->queue_id,
+          &message,
+          &size,
+          RTEMS_WAIT,
+          RTEMS_NO_TIMEOUT
+        );
+        ticks = T_tick();
+        T_quiet_rsc_success( sc );
+
+        if ( ( events & EVENT_RECEIVE_END ) != 0 ) {
+          ctx->end = ticks;
+        }
+      }
+    }
+  }
 test-target: testsuites/validation/tc-message-performance.c
-test-teardown: null
+test-teardown:
+  brief: |
+    Delete the worker task and the message queue.
+  code: |
+    rtems_status_code sc;
+
+    DeleteTask( ctx->worker_id );
+
+    sc = rtems_message_queue_delete( ctx->queue_id );
+    T_rsc_success( sc );
+
+    RestoreRunnerPriority();
+  description: null
 type: runtime-measurement-test
diff --git a/spec/rtems/sem/req/perf-mtx-pi-release-other-cpu.yml b/spec/rtems/sem/req/perf-mtx-pi-release-other-cpu.yml
index c8f2a71..792b509 100644
--- a/spec/rtems/sem/req/perf-mtx-pi-release-other-cpu.yml
+++ b/spec/rtems/sem/req/perf-mtx-pi-release-other-cpu.yml
@@ -54,13 +54,13 @@ test-teardown:
 text: |
   Let ``U` and `V`` be two tasks with distinct home schedulers.  Let :math:`B`
   be a time point measured by ``U`` right before a call to
-  ${../if/release:/name} which unblocks task ``V``.  Let :math:`E` be a time
-  point measured by ``V`` right after the first context switch after :math:`B`.
-  While the execution environment is While the execution environment is
-  ${.:/environment}, while the semaphore is a priority inheritance mutex, while
-  the measurement sample is the runtime of exactly one successful call to
-  ${../if/release:/name} which does unblock exactly one waiting task which is
-  scheduled on another processor, when exactly
+  ${../if/release:/name} which unblocks task ``V`` which is scheduled on
+  another processor.  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 semaphore is
+  a priority inheritance mutex, while exactly task ``V`` waits on the mutex,
+  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/sem/req/perf-mtx-pi-release-preempt.yml b/spec/rtems/sem/req/perf-mtx-pi-release-preempt.yml
index a86193e..070385d 100644
--- a/spec/rtems/sem/req/perf-mtx-pi-release-preempt.yml
+++ b/spec/rtems/sem/req/perf-mtx-pi-release-preempt.yml
@@ -41,12 +41,13 @@ test-teardown:
 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/release:/name} which unblocks task ``V``.  Let :math:`E` be a time
-  point measured by ``V`` right after the first context switch after :math:`B`.
-  While the execution environment is While the execution environment is
-  ${.:/environment}, while the semaphore is a priority inheritance mutex, while
-  the measurement sample is the runtime of exactly one successful call to
-  ${../if/release:/name} which does unblock exactly one waiting task which
-  preempts the caller, when exactly ${../val/perf:/params/sample-count} samples
-  are collected, the ${.:/limit-kind} shall be ${.:/limit-condition}.
+  ${../if/release:/name} which unblocks task ``V`` which does preempt 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 semaphore is
+  a priority inheritance mutex, while exactly task ``V`` waits for the mutex,
+  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/sem/req/perf-mtx-pi-wait-forever.yml b/spec/rtems/sem/req/perf-mtx-pi-wait-forever.yml
index b1e5ec9..a75d4ce 100644
--- a/spec/rtems/sem/req/perf-mtx-pi-wait-forever.yml
+++ b/spec/rtems/sem/req/perf-mtx-pi-wait-forever.yml
@@ -52,9 +52,10 @@ text: |
   be a time point measured by ``U`` right before a call to
   ${../if/obtain:/name} which blocks on the mutex with no timeout.  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 semaphore is a priority inheritance mutex, while
-  the measurement sample is :math:`E - B`, when exactly
-  ${../val/perf:/params/sample-count} samples are collected, the
+  switch after :math:`B`.
+  
+  While the execution environment is ${.:/environment}, while the semaphore is
+  a priority inheritance mutex, 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/sem/req/perf-mtx-pi-wait-timed.yml b/spec/rtems/sem/req/perf-mtx-pi-wait-timed.yml
index 56084c6..c335c66 100644
--- a/spec/rtems/sem/req/perf-mtx-pi-wait-timed.yml
+++ b/spec/rtems/sem/req/perf-mtx-pi-wait-timed.yml
@@ -52,9 +52,10 @@ text: |
   be a time point measured by ``U`` right before a call to
   ${../if/obtain:/name} which blocks on the mutex with a timeout.  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 semaphore is a priority inheritance mutex, while
-  the measurement sample is :math:`E - B`, when exactly
-  ${../val/perf:/params/sample-count} samples are collected, the
+  switch after :math:`B`.
+  
+  While the execution environment is ${.:/environment}, while the semaphore is
+  a priority inheritance mutex, 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



More information about the vc mailing list