[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