diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-11-25 17:54:12 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-11-26 08:37:10 +0100 |
commit | 64942a060989e9d5e7195710ff29809e8c9d2524 (patch) | |
tree | e90b24e557d44ced96bf2550636670a9e735e227 /spec/rtems/task | |
parent | spec: Reduce sample count (diff) | |
download | rtems-central-64942a060989e9d5e7195710ff29809e8c9d2524.tar.bz2 |
spec: Add performance requirements
Diffstat (limited to 'spec/rtems/task')
-rw-r--r-- | spec/rtems/task/req/perf-construct.yml | 3 | ||||
-rw-r--r-- | spec/rtems/task/req/perf-restart-preempt.yml | 59 | ||||
-rw-r--r-- | spec/rtems/task/req/perf-restart-self.yml | 53 | ||||
-rw-r--r-- | spec/rtems/task/req/perf-restart.yml | 53 | ||||
-rw-r--r-- | spec/rtems/task/req/perf-set-scheduler-move.yml | 55 | ||||
-rw-r--r-- | spec/rtems/task/req/perf-set-scheduler-nop.yml | 43 | ||||
-rw-r--r-- | spec/rtems/task/req/perf-set-scheduler-other.yml | 59 | ||||
-rw-r--r-- | spec/rtems/task/req/perf-set-scheduler-preempt.yml | 81 | ||||
-rw-r--r-- | spec/rtems/task/req/perf-start-preempt.yml | 56 | ||||
-rw-r--r-- | spec/rtems/task/req/perf-start.yml | 50 | ||||
-rw-r--r-- | 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 83ed57de..da8414c1 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 00000000..c0cb7cae --- /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 00000000..36bd1e93 --- /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 00000000..1efb9ce3 --- /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 00000000..201a5b0a --- /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 00000000..82377457 --- /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 00000000..fd62875d --- /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 00000000..9333c02b --- /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 00000000..363a76a1 --- /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 00000000..d92f5092 --- /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 c8056b3b..f299b8b0 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 |