summaryrefslogtreecommitdiffstats
path: root/spec/rtems/task/req
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-05-10 07:51:52 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-05-17 08:06:17 +0200
commita55de0c4d32bfc161802bb4f16c6abd48c993bbe (patch)
treeb234ff8087f9264b74601ce4d7f30647e6ae3910 /spec/rtems/task/req
parentspec: Add spec for rtems_timer_server_fire_when() (diff)
downloadrtems-central-a55de0c4d32bfc161802bb4f16c6abd48c993bbe.tar.bz2
spec: Specify task manager directives
Diffstat (limited to 'spec/rtems/task/req')
-rw-r--r--spec/rtems/task/req/get-affinity.yml236
-rw-r--r--spec/rtems/task/req/get-priority.yml338
-rw-r--r--spec/rtems/task/req/get-scheduler.yml161
-rw-r--r--spec/rtems/task/req/is-suspended.yml158
-rw-r--r--spec/rtems/task/req/iterate-done.yml16
-rw-r--r--spec/rtems/task/req/iterate-start.yml15
-rw-r--r--spec/rtems/task/req/iterate-stop.yml18
-rw-r--r--spec/rtems/task/req/iterate-visit.yml20
-rw-r--r--spec/rtems/task/req/restart.yml361
-rw-r--r--spec/rtems/task/req/resume.yml158
-rw-r--r--spec/rtems/task/req/self.yml16
-rw-r--r--spec/rtems/task/req/set-affinity.yml277
-rw-r--r--spec/rtems/task/req/set-priority.yml278
-rw-r--r--spec/rtems/task/req/set-scheduler.yml983
-rw-r--r--spec/rtems/task/req/start.yml422
-rw-r--r--spec/rtems/task/req/storage-alignment.yml16
-rw-r--r--spec/rtems/task/req/storage-size.yml158
-rw-r--r--spec/rtems/task/req/suspend.yml158
18 files changed, 3789 insertions, 0 deletions
diff --git a/spec/rtems/task/req/get-affinity.yml b/spec/rtems/task/req/get-affinity.yml
new file mode 100644
index 00000000..9327fe87
--- /dev/null
+++ b/spec/rtems/task/req/get-affinity.yml
@@ -0,0 +1,236 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/get-affinity
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/get-affinity:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvAddr
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ text: |
+ The return status of ${../if/get-affinity:/name} shall be
+ ${../../status/if/invalid-address:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/get-affinity:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: InvSize
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_SIZE );
+ text: |
+ The return status of ${../if/get-affinity:/name} shall be
+ ${../../status/if/invalid-size:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: CPUSetObj
+ states:
+ - name: Set
+ test-code: |
+ CPU_ZERO( &set );
+
+ cpu_max = rtems_scheduler_get_processor_maximum();
+
+ /* We need the online processors */
+ if ( cpu_max > 4 ) {
+ cpu_max = 4;
+ }
+
+ for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) {
+ CPU_SET( (int) cpu_index, &set );
+ }
+
+ T_eq_int( CPU_CMP( &ctx->cpuset_obj, &set ), 0 );
+ text: |
+ The value of the object referenced by the
+ ${../if/get-affinity:/params[2]/name} parameter shall be set to the
+ processor affinity set of the task specified by the
+ ${../if/get-affinity:/params[0]/name} parameter at some point during the
+ call after the return of the ${../if/get-affinity:/name} call.
+ - name: Nop
+ test-code: |
+ CPU_ZERO( &set );
+ T_eq_int( CPU_CMP( &ctx->cpuset_obj, &set ), 0 );
+ text: |
+ Objects referenced by the ${../if/get-affinity:/params[2]/name}
+ parameter in past calls to ${../if/get-affinity:/name} shall
+ not be accessed by the ${../if/get-affinity:/name} call.
+ test-epilogue: null
+ test-prologue: |
+ cpu_set_t set;
+ uint32_t cpu_index;
+ uint32_t cpu_max;
+pre-conditions:
+- name: Id
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->id = INVALID_ID;
+ text: |
+ While the ${../if/get-affinity:/params[0]/name} parameter is not
+ associated with a task.
+ - name: Task
+ test-code: |
+ ctx->id = RTEMS_SELF;
+ text: |
+ While the ${../if/get-affinity:/params[0]/name} parameter is
+ associated with a task.
+ test-epilogue: null
+ test-prologue: null
+- name: CPUSetSize
+ states:
+ - name: Valid
+ test-code: |
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj );
+ text: |
+ While the ${../if/get-affinity:/params[1]/name} parameter is an integral
+ multiple of the size of long, while the
+ ${../if/get-affinity:/params[1]/name} parameter specifies a processor set
+ which is large enough to contain the processor affinity set of the task.
+ - name: TooSmall
+ test-code: |
+ ctx->cpusetsize = 0;
+ text: |
+ While the ${../if/get-affinity:/params[1]/name} parameter is an integral
+ multiple of the size of long, while the
+ ${../if/get-affinity:/params[1]/name} parameter specifies a processor set
+ which is not large enough to contain the processor affinity set of the
+ task.
+ - name: Askew
+ test-code: |
+ ctx->cpusetsize = SIZE_MAX;
+ text: |
+ While the ${../if/get-affinity:/params[1]/name} parameter is not an
+ integral multiple of the size of long.
+ test-epilogue: null
+ test-prologue: null
+- name: CPUSet
+ states:
+ - name: Valid
+ test-code: |
+ ctx->cpuset = &ctx->cpuset_obj;
+ text: |
+ While the ${../if/get-affinity:/params[2]/name} parameter references an
+ object of type ${/c/if/cpu_set_t:/name}.
+ - name: 'Null'
+ test-code: |
+ ctx->cpuset = NULL;
+ text: |
+ While the ${../if/get-affinity:/params[2]/name} parameter is equal to
+ ${/c/if/null:/name}.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ ctx->status = rtems_task_get_affinity(
+ ctx->id,
+ ctx->cpusetsize,
+ ctx->cpuset
+ );
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This member provides the object referenced by the
+ ${../if/get-affinity:/params[2]/name} parameter.
+ description: null
+ member: |
+ cpu_set_t cpuset_obj
+- brief: |
+ This member contains the return value of the ${../if/get-affinity:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/get-affinity:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id id
+- brief: |
+ This member specifies if the ${../if/get-affinity:/params[1]/name}
+ parameter value.
+ description: null
+ member: |
+ size_t cpusetsize
+- brief: |
+ This member specifies if the ${../if/get-affinity:/params[2]/name}
+ parameter value.
+ description: null
+ member: |
+ cpu_set_t *cpuset
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+test-local-includes:
+- tx-support.h
+test-prepare: |
+ CPU_ZERO( &ctx->cpuset_obj );
+test-setup: null
+test-stop: null
+test-support: null
+test-target: testsuites/validation/tc-task-get-affinity.c
+test-teardown: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ CPUSetObj: Set
+ pre-conditions:
+ Id:
+ - Task
+ CPUSetSize:
+ - Valid
+ CPUSet:
+ - Valid
+- enabled-by: true
+ post-conditions:
+ Status: InvAddr
+ CPUSetObj: Nop
+ pre-conditions:
+ Id: all
+ CPUSetSize: all
+ CPUSet:
+ - 'Null'
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ CPUSetObj: Nop
+ pre-conditions:
+ Id:
+ - Invalid
+ CPUSetSize: all
+ CPUSet:
+ - Valid
+- enabled-by: true
+ post-conditions:
+ Status: InvSize
+ CPUSetObj: Nop
+ pre-conditions:
+ Id:
+ - Task
+ CPUSetSize:
+ - TooSmall
+ - Askew
+ CPUSet:
+ - Valid
+type: requirement
diff --git a/spec/rtems/task/req/get-priority.yml b/spec/rtems/task/req/get-priority.yml
new file mode 100644
index 00000000..445662af
--- /dev/null
+++ b/spec/rtems/task/req/get-priority.yml
@@ -0,0 +1,338 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/get-priority
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/get-priority:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvAddr
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ text: |
+ The return status of ${../if/get-priority:/name} shall be
+ ${../../status/if/invalid-address:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/get-priority:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: NotDef
+ test-code: |
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ text: |
+ The return status of ${../if/get-priority:/name} shall be
+ ${../../status/if/not-defined:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: PriorityObj
+ states:
+ - name: Set
+ test-code: |
+ T_eq_u32( ctx->priority_obj, PRIO_DEFAULT );
+ text: |
+ The value of the object referenced by the
+ ${../if/get-priority:/params[1]/name} parameter shall be set to the
+ object identifier of the ${/glossary/scheduler-home:/term} of the task
+ specified by the ${../if/get-priority:/params[0]/name} parameter at some
+ point during the call after the return of the
+ ${../if/get-priority:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_u32( ctx->priority_obj, PRIO_INVALID );
+ text: |
+ Objects referenced by the ${../if/get-priority:/params[1]/name}
+ parameter in past calls to ${../if/get-priority:/name} shall
+ not be accessed by the ${../if/get-priority:/name} call.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: TaskId
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->task_id = INVALID_ID;
+ text: |
+ While the ${../if/get-priority:/params[0]/name} parameter is not
+ associated with a task.
+ - name: Task
+ test-code: |
+ ctx->task_id = RTEMS_SELF;
+ text: |
+ While the ${../if/get-priority:/params[0]/name} parameter is
+ associated with a task.
+ test-epilogue: null
+ test-prologue: null
+- name: SchedulerId
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->scheduler_id = INVALID_ID;
+ text: |
+ While the ${../if/get-priority:/params[1]/name} parameter is not
+ associated with a scheduler.
+ - name: Scheduler
+ test-code: |
+ ctx->scheduler_id = ctx->scheduler_a_id;
+ text: |
+ While the ${../if/get-priority:/params[1]/name} parameter is associated
+ with a scheduler.
+ test-epilogue: null
+ test-prologue: null
+- name: Scheduler
+ states:
+ - name: Eligible
+ test-code: |
+ ctx->scheduler_id = ctx->scheduler_a_id;
+ text: |
+ While the ${../if/get-priority:/params[1]/name} parameter is associated
+ with an ${/glossary/scheduler-eligible:/term} of the task specified by
+ ${../if/get-priority:/params[0]/name}.
+ - name: Ineligible
+ test-code: |
+ ctx->scheduler_id = ctx->scheduler_b_id;
+ text: |
+ While the ${../if/get-priority:/params[1]/name} parameter is associated
+ with an ${/glossary/scheduler-ineligible:/term} of the task specified by
+ ${../if/get-priority:/params[0]/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: Priority
+ states:
+ - name: Valid
+ test-code: |
+ ctx->priority = &ctx->priority_obj;
+ text: |
+ While the ${../if/get-priority:/params[2]/name} parameter references an
+ object of type ${../../type/if/priority:/name}.
+ - name: 'Null'
+ test-code: |
+ ctx->priority = NULL;
+ text: |
+ While the ${../if/get-priority:/params[2]/name} parameter is equal to
+ ${/c/if/null:/name}.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons:
+ NoOtherScheduler: |
+ Where the system was built with SMP support disabled, exactly one scheduler
+ is present in an application.
+test-action: |
+ ctx->status = rtems_task_get_priority(
+ ctx->task_id,
+ ctx->scheduler_id,
+ ctx->priority
+ );
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This member contains the scheduler A identifier.
+ description: null
+ member: |
+ rtems_id scheduler_a_id
+- brief: |
+ This member contains the scheduler B identifier.
+ description: null
+ member: |
+ rtems_id scheduler_b_id
+- brief: |
+ This member provides the object referenced by the
+ ${../if/get-priority:/params[2]/name} parameter.
+ description: null
+ member: |
+ rtems_task_priority priority_obj
+- brief: |
+ This member contains the return value of the ${../if/get-priority:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/get-priority:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id task_id
+- brief: |
+ This member specifies if the ${../if/get-priority:/params[1]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id scheduler_id
+- brief: |
+ This member specifies if the ${../if/get-priority:/params[2]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id *priority
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+test-local-includes:
+- ts-config.h
+- tx-support.h
+test-prepare: |
+ ctx->priority_obj = PRIO_INVALID;
+test-setup:
+ brief: null
+ code: |
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_A_NAME,
+ &ctx->scheduler_a_id
+ );
+ T_rsc_success( sc );
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_B_NAME,
+ &ctx->scheduler_b_id
+ );
+ T_rsc_success( sc );
+ #endif
+ description: null
+test-stop: null
+test-support: null
+test-target: testsuites/validation/tc-task-get-priority.c
+test-teardown: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ PriorityObj: Set
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Scheduler:
+ - Eligible
+ Priority:
+ - Valid
+- enabled-by: true
+ post-conditions:
+ Status: InvAddr
+ PriorityObj: Nop
+ pre-conditions:
+ TaskId:
+ - Invalid
+ SchedulerId:
+ - Invalid
+ Scheduler: N/A
+ Priority:
+ - 'Null'
+- enabled-by: true
+ post-conditions:
+ Status: InvAddr
+ PriorityObj: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Invalid
+ Scheduler: N/A
+ Priority:
+ - 'Null'
+- enabled-by: true
+ post-conditions:
+ Status: InvAddr
+ PriorityObj: Nop
+ pre-conditions:
+ TaskId:
+ - Invalid
+ SchedulerId:
+ - Scheduler
+ Scheduler: N/A
+ Priority:
+ - 'Null'
+- enabled-by: true
+ post-conditions:
+ Status: InvAddr
+ PriorityObj: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Scheduler:
+ - Eligible
+ Priority:
+ - 'Null'
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ PriorityObj: Nop
+ pre-conditions:
+ TaskId: all
+ SchedulerId:
+ - Invalid
+ Scheduler: N/A
+ Priority:
+ - Valid
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ PriorityObj: Nop
+ pre-conditions:
+ TaskId:
+ - Invalid
+ SchedulerId:
+ - Scheduler
+ Scheduler: N/A
+ Priority:
+ - Valid
+- enabled-by: true
+ post-conditions: NoOtherScheduler
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Scheduler:
+ - Ineligible
+ Priority: all
+- enabled-by: RTEMS_SMP
+ post-conditions:
+ Status: NotDef
+ PriorityObj: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Scheduler:
+ - Ineligible
+ Priority:
+ - Valid
+- enabled-by: RTEMS_SMP
+ post-conditions:
+ Status: InvAddr
+ PriorityObj: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Scheduler:
+ - Ineligible
+ Priority:
+ - 'Null'
+type: requirement
diff --git a/spec/rtems/task/req/get-scheduler.yml b/spec/rtems/task/req/get-scheduler.yml
new file mode 100644
index 00000000..3a35a0e0
--- /dev/null
+++ b/spec/rtems/task/req/get-scheduler.yml
@@ -0,0 +1,161 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/get-scheduler
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/get-scheduler:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvAddr
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ text: |
+ The return status of ${../if/get-scheduler:/name} shall be
+ ${../../status/if/invalid-address:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/get-scheduler:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: SchedulerIDObj
+ states:
+ - name: Set
+ test-code: |
+ T_eq_u32( ctx->scheduler_id_obj, 0x0f010001 );
+ text: |
+ The value of the object referenced by the
+ ${../if/get-scheduler:/params[1]/name} parameter shall be set to the
+ object identifier of the ${/glossary/scheduler-home:/term} of the task
+ specified by the ${../if/get-scheduler:/params[0]/name} parameter at some
+ point during the call after the return of the
+ ${../if/get-scheduler:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_u32( ctx->scheduler_id_obj, INVALID_ID );
+ text: |
+ Objects referenced by the ${../if/get-scheduler:/params[1]/name}
+ parameter in past calls to ${../if/get-scheduler:/name} shall
+ not be accessed by the ${../if/get-scheduler:/name} call.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Id
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->id = INVALID_ID;
+ text: |
+ While the ${../if/get-scheduler:/params[0]/name} parameter is not
+ associated with a task.
+ - name: Task
+ test-code: |
+ ctx->id = RTEMS_SELF;
+ text: |
+ While the ${../if/get-scheduler:/params[0]/name} parameter is
+ associated with a task.
+ test-epilogue: null
+ test-prologue: null
+- name: SchedulerID
+ states:
+ - name: Valid
+ test-code: |
+ ctx->scheduler_id = &ctx->scheduler_id_obj;
+ text: |
+ While the ${../if/get-scheduler:/params[1]/name} parameter references an
+ object of type ${../../type/if/id:/name}.
+ - name: 'Null'
+ test-code: |
+ ctx->scheduler_id = NULL;
+ text: |
+ While the ${../if/get-scheduler:/params[1]/name} parameter is equal to
+ ${/c/if/null:/name}.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ ctx->status = rtems_task_get_scheduler( ctx->id, ctx->scheduler_id );
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This member provides the object referenced by the
+ ${../if/get-scheduler:/params[1]/name} parameter.
+ description: null
+ member: |
+ rtems_id scheduler_id_obj
+- brief: |
+ This member contains the return value of the ${../if/get-scheduler:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/get-scheduler:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id id
+- brief: |
+ This member specifies if the ${../if/get-scheduler:/params[1]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id *scheduler_id
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+test-local-includes:
+- tx-support.h
+test-prepare: |
+ ctx->scheduler_id_obj = INVALID_ID;
+test-setup: null
+test-stop: null
+test-support: null
+test-target: testsuites/validation/tc-task-get-scheduler.c
+test-teardown: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ SchedulerIDObj: Set
+ pre-conditions:
+ Id:
+ - Task
+ SchedulerID:
+ - Valid
+- enabled-by: true
+ post-conditions:
+ Status: InvAddr
+ SchedulerIDObj: Nop
+ pre-conditions:
+ Id: all
+ SchedulerID:
+ - 'Null'
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ SchedulerIDObj: Nop
+ pre-conditions:
+ Id:
+ - Invalid
+ SchedulerID:
+ - Valid
+type: requirement
diff --git a/spec/rtems/task/req/is-suspended.yml b/spec/rtems/task/req/is-suspended.yml
new file mode 100644
index 00000000..c5ee5424
--- /dev/null
+++ b/spec/rtems/task/req/is-suspended.yml
@@ -0,0 +1,158 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/is-suspended
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/is-suspended:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/is-suspended:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: AlrdySus
+ test-code: |
+ T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
+ text: |
+ The return status of ${../if/is-suspended:/name} shall be
+ ${../../status/if/already-suspended:/name}.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Id
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->id = INVALID_ID;
+ text: |
+ While the ${../if/is-suspended:/params[0]/name} parameter is not
+ associated with a task.
+ - name: Task
+ test-code: |
+ ctx->id = ctx->worker_id;
+ text: |
+ While the ${../if/is-suspended:/params[0]/name} parameter is
+ associated with a task.
+ test-epilogue: null
+ test-prologue: null
+- name: Suspended
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->suspend = true;
+ text: |
+ While the task specified by the ${../if/is-suspended:/params[0]/name}
+ parameter is suspended.
+ - name: 'No'
+ test-code: |
+ ctx->suspend = false;
+ text: |
+ While the task specified by the ${../if/is-suspended:/params[0]/name}
+ parameter is not suspended.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_is_suspended( ctx->id );
+
+ if ( ctx->suspend ) {
+ ResumeTask( ctx->worker_id );
+ }
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This member contains the identifier of a task.
+ description: null
+ member: |
+ rtems_id worker_id
+- brief: |
+ If this member is true, then the worker is suspended before the
+ ${../if/is-suspended:/name} call.
+ description: null
+ member: |
+ bool suspend
+- brief: |
+ This member contains the return value of the ${../if/is-suspended:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/is-suspended:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id id
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+test-local-includes:
+- tx-support.h
+test-prepare: null
+test-setup:
+ brief: null
+ code: |
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+ description: null
+test-stop: null
+test-support: |
+ static void Worker( rtems_task_argument arg )
+ {
+ while ( true ) {
+ /* Do nothing */
+ }
+ }
+test-target: testsuites/validation/tc-task-is-suspended.c
+test-teardown:
+ brief: null
+ code: |
+ DeleteTask( ctx->worker_id );
+ description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ pre-conditions:
+ Id:
+ - Task
+ Suspended:
+ - 'No'
+- enabled-by: true
+ post-conditions:
+ Status: AlrdySus
+ pre-conditions:
+ Id:
+ - Task
+ Suspended:
+ - 'Yes'
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ pre-conditions:
+ Id:
+ - Invalid
+ Suspended: N/A
+type: requirement
diff --git a/spec/rtems/task/req/iterate-done.yml b/spec/rtems/task/req/iterate-done.yml
new file mode 100644
index 00000000..19e3e528
--- /dev/null
+++ b/spec/rtems/task/req/iterate-done.yml
@@ -0,0 +1,16 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: interface-function
+ uid: ../if/iterate
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While an iteration over all tasks was started by calling
+ ${../if/iterate:/name}, while no task exists which was not visited, the
+ iteration shall stop and then the object allocator lock shall be released.
+type: requirement
diff --git a/spec/rtems/task/req/iterate-start.yml b/spec/rtems/task/req/iterate-start.yml
new file mode 100644
index 00000000..c08e8108
--- /dev/null
+++ b/spec/rtems/task/req/iterate-start.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: interface-function
+ uid: ../if/iterate
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ When ${../if/iterate:/name} is called, the calling task shall obtain the
+ object allocator lock and then start an iteration over all tasks.
+type: requirement
diff --git a/spec/rtems/task/req/iterate-stop.yml b/spec/rtems/task/req/iterate-stop.yml
new file mode 100644
index 00000000..aa982635
--- /dev/null
+++ b/spec/rtems/task/req/iterate-stop.yml
@@ -0,0 +1,18 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: interface-function
+ uid: ../if/iterate
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While an iteration over all tasks was started by calling
+ ${../if/iterate:/name}, when the function specified by the
+ ${../if/iterate:/params[0]/name} returns ${/c/if/true:/name} during the
+ iteration, the iteration shall stop and the object allocator lock shall be
+ released.
+type: requirement
diff --git a/spec/rtems/task/req/iterate-visit.yml b/spec/rtems/task/req/iterate-visit.yml
new file mode 100644
index 00000000..0539aa70
--- /dev/null
+++ b/spec/rtems/task/req/iterate-visit.yml
@@ -0,0 +1,20 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: interface-function
+ uid: ../if/iterate
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While an iteration over all tasks was started by calling
+ ${../if/iterate:/name}, while a task exists which was not visited, the task
+ shall be visited by calling the function specified by the
+ ${../if/iterate:/params[0]/name} parameter of the ${../if/iterate:/name} with
+ the ${/glossary/tcb:/term} of the task as the first parameter and the second
+ parameter specified by the ${../if/iterate:/params[0]/name} parameter of the
+ ${../if/iterate:/name} call.
+type: requirement
diff --git a/spec/rtems/task/req/restart.yml b/spec/rtems/task/req/restart.yml
new file mode 100644
index 00000000..7e533504
--- /dev/null
+++ b/spec/rtems/task/req/restart.yml
@@ -0,0 +1,361 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/restart
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/restart:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/restart:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: IncStat
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ text: |
+ The return status of ${../if/restart:/name} shall be
+ ${../../status/if/incorrect-state:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: Argument
+ states:
+ - name: Set
+ test-code: |
+ T_eq_u32( ctx->actual_argument, ctx->argument );
+ T_eq_u32( ctx->counter, 2 );
+ text: |
+ The entry point argument of the task specified by the
+ ${../if/restart:/params[0]/name} parameter shall be set to the value
+ specified by the ${../if/restart:/params[1]/name} parameter before the task
+ is unblocked by the ${../if/restart:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_u32( ctx->actual_argument, 0 );
+
+ if ( ctx->start ) {
+ T_eq_u32( ctx->counter, 1 );
+ } else {
+ T_eq_u32( ctx->counter, 0 );
+ }
+ text: |
+ No entry point argument of a task shall be modified by the
+ ${../if/restart:/name} call.
+ test-epilogue: null
+ test-prologue: null
+- name: Unblock
+ states:
+ - name: 'Yes'
+ test-code: |
+ if ( ctx->suspend ) {
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_UNBLOCK
+ );
+ } else {
+ T_eq_sz( ctx->scheduler_log.header.recorded, 2 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_BLOCK
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 1 ].operation,
+ T_SCHEDULER_UNBLOCK
+ );
+ }
+ text: |
+ The task specified by the ${../if/restart:/params[0]/name} parameter shall
+ be unblocked by the ${../if/restart:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ text: |
+ No task shall be unblocked by the ${../if/restart:/name} call.
+ test-epilogue: null
+ test-prologue: null
+- name: RestartExtensions
+ states:
+ - name: 'Yes'
+ test-code: |
+ T_eq_u32( ctx->restart_extension_calls, 1 );
+ text: |
+ The thread restart user extensions shall be invoked by the
+ ${../if/restart:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_u32( ctx->restart_extension_calls, 0 );
+ text: |
+ The thread restart user extensions shall not be invoked by the
+ ${../if/restart:/name} call.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Id
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->id = INVALID_ID;
+ text: |
+ While the ${../if/restart:/params[0]/name} parameter is not associated with
+ a task.
+ - name: Task
+ test-code: |
+ ctx->id = ctx->worker_id;
+ text: |
+ While the ${../if/restart:/params[0]/name} parameter is associated with a
+ task.
+ test-epilogue: null
+ test-prologue: null
+- name: Argument
+ states:
+ - name: Pointer
+ test-code: |
+ ctx->argument = (rtems_task_argument) ctx;
+ text: |
+ While the entry point argument specified by the
+ ${../if/restart:/params[1]/name} parameter is a pointer.
+ - name: Number
+ test-code: |
+ ctx->argument = UINT32_C( 0x87654321 );
+ text: |
+ While the entry point argument specified by the
+ ${../if/restart:/params[1]/name} parameter is a 32-bit number.
+ test-epilogue: null
+ test-prologue: null
+- name: Dormant
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->start = false;
+ text: |
+ While the task specified by the ${../if/restart:/params[0]/name} parameter
+ is dormant.
+ - name: 'No'
+ test-code: |
+ ctx->start = true;
+ text: |
+ While the task specified by the ${../if/restart:/params[0]/name} parameter
+ is not dormant.
+ test-epilogue: null
+ test-prologue: null
+- name: Suspended
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->suspend = true;
+ text: |
+ While the task specified by the ${../if/restart:/params[0]/name} parameter
+ is suspended.
+ - name: 'No'
+ test-code: |
+ ctx->suspend = false;
+ text: |
+ While the task specified by the ${../if/restart:/params[0]/name} parameter
+ is not suspended.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ T_scheduler_log *log;
+
+ if ( ctx->start ) {
+ StartTask( ctx->worker_id, Worker, 0 );
+ Yield();
+ }
+
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->restart_extension_calls = 0;
+
+ log = T_scheduler_record_2( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_task_restart( ctx->id, ctx->argument );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+
+ Yield();
+test-brief: null
+test-cleanup: |
+ DeleteTask( ctx->worker_id );
+test-context:
+- brief: |
+ This member provides the scheduler operation records.
+ description: null
+ member: |
+ T_scheduler_log_2 scheduler_log
+- brief: |
+ This member contains the identifier of a task.
+ description: null
+ member: |
+ rtems_id worker_id
+- brief: |
+ This member contains the identifier of the test user extensions.
+ description: null
+ member: |
+ rtems_id extension_id
+- brief: |
+ This member contains the count of thread restart extension calls.
+ description: null
+ member: |
+ uint32_t restart_extension_calls
+- brief: |
+ This member contains the actual argument passed to the entry point.
+ description: null
+ member: |
+ rtems_task_argument actual_argument
+- brief: |
+ This member contains the entry point counter.
+ description: null
+ member: |
+ uint32_t counter
+- brief: |
+ If this member is true, then the worker is started before the
+ ${../if/restart:/name} call.
+ description: null
+ member: |
+ bool start
+- brief: |
+ If this member is true, then the worker is suspended before the
+ ${../if/restart:/name} call.
+ description: null
+ member: |
+ bool suspend
+- brief: |
+ This member contains the return value of the ${../if/restart:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/restart:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id id
+- brief: |
+ This member specifies if the ${../if/restart:/params[1]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_task_argument argument
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+- rtems/test-scheduler.h
+test-local-includes:
+- tx-support.h
+test-prepare: |
+ ctx->actual_argument = 0;
+ ctx->counter = 0;
+ ctx->worker_id = CreateTask( "WORK", PRIO_DEFAULT );
+test-setup:
+ brief: null
+ code: |
+ rtems_status_code sc;
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'E', 'S', 'T' ),
+ &extensions,
+ &ctx->extension_id
+ );
+ T_rsc_success( sc );
+ description: null
+test-stop: null
+test-support: |
+ typedef RtemsTaskReqRestart_Context Context;
+
+ static void Worker( rtems_task_argument arg )
+ {
+ Context *ctx;
+
+ ctx = &RtemsTaskReqRestart_Instance;
+
+ while ( true ) {
+ ctx->actual_argument += arg;
+ ++ctx->counter;
+ Yield();
+ }
+ }
+
+ static void ThreadRestart( rtems_tcb *executing, rtems_tcb *restarted )
+ {
+ (void) executing;
+ (void) restarted;
+
+ ++RtemsTaskReqRestart_Instance.restart_extension_calls;
+ }
+
+ static const rtems_extensions_table extensions = {
+ .thread_restart = ThreadRestart
+ };
+test-target: testsuites/validation/tc-task-restart.c
+test-teardown:
+ brief: null
+ code: |
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->extension_id );
+ T_rsc_success( sc );
+ description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Argument: Set
+ Unblock: 'Yes'
+ RestartExtensions: 'Yes'
+ pre-conditions:
+ Id:
+ - Task
+ Argument: all
+ Dormant:
+ - 'No'
+ Suspended: all
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ Argument: Nop
+ Unblock: Nop
+ RestartExtensions: Nop
+ pre-conditions:
+ Id:
+ - Invalid
+ Argument: all
+ Dormant: N/A
+ Suspended: N/A
+- enabled-by: true
+ post-conditions:
+ Status: IncStat
+ Argument: Nop
+ Unblock: Nop
+ RestartExtensions: Nop
+ pre-conditions:
+ Id:
+ - Task
+ Argument: all
+ Dormant:
+ - 'Yes'
+ Suspended: all
+type: requirement
diff --git a/spec/rtems/task/req/resume.yml b/spec/rtems/task/req/resume.yml
new file mode 100644
index 00000000..c3378254
--- /dev/null
+++ b/spec/rtems/task/req/resume.yml
@@ -0,0 +1,158 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/resume
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/resume:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/resume:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: IncStat
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ text: |
+ The return status of ${../if/resume:/name} shall be
+ ${../../status/if/incorrect-state:/name}.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Id
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->id = INVALID_ID;
+ text: |
+ While the ${../if/resume:/params[0]/name} parameter is not
+ associated with a task.
+ - name: Task
+ test-code: |
+ ctx->id = ctx->worker_id;
+ text: |
+ While the ${../if/resume:/params[0]/name} parameter is
+ associated with a task.
+ test-epilogue: null
+ test-prologue: null
+- name: Suspended
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->suspend = true;
+ text: |
+ While the task specified by the ${../if/resume:/params[0]/name}
+ parameter is suspended.
+ - name: 'No'
+ test-code: |
+ ctx->suspend = false;
+ text: |
+ While the task specified by the ${../if/resume:/params[0]/name}
+ parameter is not suspended.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_resume( ctx->id );
+
+ if ( ctx->suspend && ctx->status != RTEMS_SUCCESSFUL ) {
+ ResumeTask( ctx->worker_id );
+ }
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This member contains the identifier of a task.
+ description: null
+ member: |
+ rtems_id worker_id
+- brief: |
+ If this member is true, then the worker is suspended before the
+ ${../if/resume:/name} call.
+ description: null
+ member: |
+ bool suspend
+- brief: |
+ This member contains the return value of the ${../if/resume:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/resume:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id id
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+test-local-includes:
+- tx-support.h
+test-prepare: null
+test-setup:
+ brief: null
+ code: |
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+ description: null
+test-stop: null
+test-support: |
+ static void Worker( rtems_task_argument arg )
+ {
+ while ( true ) {
+ /* Do nothing */
+ }
+ }
+test-target: testsuites/validation/tc-task-resume.c
+test-teardown:
+ brief: null
+ code: |
+ DeleteTask( ctx->worker_id );
+ description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ pre-conditions:
+ Id:
+ - Task
+ Suspended:
+ - 'Yes'
+- enabled-by: true
+ post-conditions:
+ Status: IncStat
+ pre-conditions:
+ Id:
+ - Task
+ Suspended:
+ - 'No'
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ pre-conditions:
+ Id:
+ - Invalid
+ Suspended: N/A
+type: requirement
diff --git a/spec/rtems/task/req/self.yml b/spec/rtems/task/req/self.yml
new file mode 100644
index 00000000..1fe477d8
--- /dev/null
+++ b/spec/rtems/task/req/self.yml
@@ -0,0 +1,16 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by:
+ not: RTEMS_SMP
+links:
+- role: interface-function
+ uid: ../if/self
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The ${../if/self:/name} directive call shall return the object identifier of
+ the calling task.
+type: requirement
diff --git a/spec/rtems/task/req/set-affinity.yml b/spec/rtems/task/req/set-affinity.yml
new file mode 100644
index 00000000..570f0a92
--- /dev/null
+++ b/spec/rtems/task/req/set-affinity.yml
@@ -0,0 +1,277 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/set-affinity
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/set-affinity:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvAddr
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ text: |
+ The return status of ${../if/set-affinity:/name} shall be
+ ${../../status/if/invalid-address:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/set-affinity:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: InvNum
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
+ text: |
+ The return status of ${../if/set-affinity:/name} shall be
+ ${../../status/if/invalid-number:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: SetAffinity
+ states:
+ - name: 'Yes'
+ test-code: |
+ #if defined(RTEMS_SMP)
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_SET_AFFINITY
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].set_affinity.status,
+ STATUS_SUCCESSFUL
+ );
+ #else
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ #endif
+ text: |
+ The affinity set of the task specified by the
+ ${../if/set-affinity:/params[0]/name} parameter shall be set with respect
+ to the ${/glossary/scheduler-home:/term} of the task at some point during
+ the ${../if/set-affinity:/name} call.
+ - name: Nop
+ test-code: |
+ #if defined(RTEMS_SMP)
+ if ( ctx->scheduler_log.header.recorded == 1 ) {
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_SET_AFFINITY
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].set_affinity.status,
+ STATUS_INVALID_NUMBER
+ );
+ } else {
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ }
+ #else
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ #endif
+ text: |
+ No task affinity shall be modified by the ${../if/set-affinity:/name}
+ call.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Id
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->id = INVALID_ID;
+ text: |
+ While the ${../if/set-affinity:/params[0]/name} parameter is not
+ associated with a task.
+ - name: Task
+ test-code: |
+ ctx->id = RTEMS_SELF;
+ text: |
+ While the ${../if/set-affinity:/params[0]/name} parameter is
+ associated with a task.
+ test-epilogue: null
+ test-prologue: null
+- name: CPUSetKind
+ states:
+ - name: Askew
+ test-code: |
+ ctx->cpusetsize = SIZE_MAX;
+ text: |
+ While the ${../if/set-affinity:/params[1]/name} parameter is not an
+ integral multiple of the size of long.
+ - name: Huge
+ test-code: |
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj );
+ CPU_ZERO( &ctx->cpuset_obj[ 0 ] );
+ text: |
+ While the ${../if/set-affinity:/params[1]/name} parameter is an integral
+ multiple of the size of long, while the
+ ${../if/set-affinity:/params[1]/name} and
+ ${../if/set-affinity:/params[2]/name} parameter specify a processor set
+ which exceeds the implementation limits.
+ - name: Supported
+ test-code: |
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] );
+ text: |
+ While the ${../if/set-affinity:/params[1]/name} parameter is an integral
+ multiple of the size of long, while the
+ ${../if/set-affinity:/params[1]/name} and
+ ${../if/set-affinity:/params[2]/name} parameter specify a processor set
+ which is an affinity set supported by the
+ ${/glossary/scheduler-home:/term} of the task specified by the
+ ${../if/set-affinity:/params[0]/name} parameter at some point during the
+ ${../if/set-affinity:/name} call.
+ - name: Unsupported
+ test-code: |
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] );
+ CPU_CLR( 0, &ctx->cpuset_obj[ 0 ] );
+ text: |
+ While the ${../if/set-affinity:/params[1]/name} parameter is an integral
+ multiple of the size of long, while the
+ ${../if/set-affinity:/params[1]/name} and
+ ${../if/set-affinity:/params[2]/name} parameter specify a processor set
+ which is an affinity set not supported by the
+ ${/glossary/scheduler-home:/term} of the task specified by the
+ ${../if/set-affinity:/params[0]/name} parameter at some point during the
+ ${../if/set-affinity:/name} call.
+ test-epilogue: null
+ test-prologue: null
+- name: CPUSet
+ states:
+ - name: Valid
+ test-code: |
+ ctx->cpuset = &ctx->cpuset_obj[ 0 ];
+ text: |
+ While the ${../if/set-affinity:/params[2]/name} parameter references an
+ object of type ${/c/if/cpu_set_t:/name}.
+ - name: 'Null'
+ test-code: |
+ ctx->cpuset = NULL;
+ text: |
+ While the ${../if/set-affinity:/params[2]/name} parameter is equal to
+ ${/c/if/null:/name}.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ T_scheduler_log *log;
+
+ log = T_scheduler_record_2( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_task_set_affinity(
+ ctx->id,
+ ctx->cpusetsize,
+ ctx->cpuset
+ );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This member provides the scheduler operation records.
+ description: null
+ member: |
+ T_scheduler_log_2 scheduler_log;
+- brief: |
+ This member provides the object referenced by the
+ ${../if/set-affinity:/params[2]/name} parameter.
+ description: null
+ member: |
+ cpu_set_t cpuset_obj[ 2 ]
+- brief: |
+ This member contains the return value of the ${../if/set-affinity:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/set-affinity:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id id
+- brief: |
+ This member specifies if the ${../if/set-affinity:/params[1]/name}
+ parameter value.
+ description: null
+ member: |
+ size_t cpusetsize
+- brief: |
+ This member specifies if the ${../if/set-affinity:/params[2]/name}
+ parameter value.
+ description: null
+ member: |
+ cpu_set_t *cpuset
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+- rtems/test-scheduler.h
+test-local-includes:
+- tx-support.h
+test-prepare: |
+ CPU_FILL_S( sizeof( ctx->cpuset_obj ), &ctx->cpuset_obj[ 0 ] );
+test-setup: null
+test-stop: null
+test-support: null
+test-target: testsuites/validation/tc-task-set-affinity.c
+test-teardown: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ SetAffinity: 'Yes'
+ pre-conditions:
+ Id:
+ - Task
+ CPUSetKind:
+ - Supported
+ CPUSet:
+ - Valid
+- enabled-by: true
+ post-conditions:
+ Status: InvAddr
+ SetAffinity: Nop
+ pre-conditions:
+ Id: all
+ CPUSetKind: N/A
+ CPUSet:
+ - 'Null'
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ SetAffinity: Nop
+ pre-conditions:
+ Id:
+ - Invalid
+ CPUSetKind: N/A
+ CPUSet:
+ - Valid
+- enabled-by: true
+ post-conditions:
+ Status: InvNum
+ SetAffinity: Nop
+ pre-conditions:
+ Id:
+ - Task
+ CPUSetKind:
+ - Askew
+ - Huge
+ - Unsupported
+ CPUSet:
+ - Valid
+type: requirement
diff --git a/spec/rtems/task/req/set-priority.yml b/spec/rtems/task/req/set-priority.yml
new file mode 100644
index 00000000..9713ae65
--- /dev/null
+++ b/spec/rtems/task/req/set-priority.yml
@@ -0,0 +1,278 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/set-priority
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/set-priority:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvAddr
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ text: |
+ The return status of ${../if/set-priority:/name} shall be
+ ${../../status/if/invalid-address:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/set-priority:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: InvPrio
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
+ text: |
+ The return status of ${../if/set-priority:/name} shall be
+ ${../../status/if/invalid-priority:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: Priority
+ states:
+ - name: Set
+ test-code: |
+ T_eq_u32( GetPriority( ctx->worker_id ), PRIO_HIGH );
+ text: |
+ The ${/glossary/priority-real:/term} of the task specified by the
+ ${../if/set-priority:/params[0]/name} parameter shall be set to the value
+ specified by the ${../if/set-priority:/params[1]/name} parameter at some
+ point during the ${../if/set-priority:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_u32( GetPriority( ctx->worker_id ), PRIO_LOW );
+ text: |
+ No ${/glossary/priority-real:/term} of a task shall be modified by the
+ ${../if/set-priority:/name} call.
+ test-epilogue: null
+ test-prologue: null
+- name: OldPriorityObj
+ states:
+ - name: Set
+ test-code: |
+ T_eq_u32( ctx->old_priority_obj, PRIO_LOW );
+ text: |
+ The value of the object referenced by the
+ ${../if/set-priority:/params[2]/name} parameter shall be set after the
+ return of the ${../if/set-priority:/name} call to the
+ ${/glossary/priority-current:/term} of the task specified by the
+ ${../if/set-priority:/params[0]/name} parameter at some point during the
+ call and before the ${/glossary/priority-real:/term} is modified by the
+ call if it is modified by the call.
+ - name: Nop
+ test-code: |
+ T_eq_u32( ctx->old_priority_obj, PRIO_INVALID );
+ text: |
+ Objects referenced by the ${../if/set-priority:/params[2]/name}
+ parameter in past calls to ${../if/set-priority:/name} shall
+ not be accessed by the ${../if/set-priority:/name} call.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Id
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->id = INVALID_ID;
+ text: |
+ While the ${../if/set-priority:/params[0]/name} parameter is not
+ associated with a task.
+ - name: Task
+ test-code: |
+ ctx->id = ctx->worker_id;
+ text: |
+ While the ${../if/set-priority:/params[0]/name} parameter is
+ associated with a task.
+ test-epilogue: null
+ test-prologue: null
+- name: NewPriority
+ states:
+ - name: Current
+ test-code: |
+ ctx->new_priority = RTEMS_CURRENT_PRIORITY;
+ text: |
+ While the value of the ${../if/set-priority:/params[1]/name} parameter is
+ equal to ${../if/current-priority:/name}.
+ - name: Valid
+ test-code: |
+ ctx->new_priority = PRIO_HIGH;
+ text: |
+ While the value of the ${../if/set-priority:/params[1]/name} parameter is
+ not equal to ${../if/current-priority:/name}, while the value of the
+ ${../if/set-priority:/params[1]/name} parameter is a valid
+ ${/glossary/priority-task:/term} with respect to the
+ ${/glossary/scheduler-home:/term} of the task specified by the
+ ${../if/set-priority:/params[0]/name} parameter at some point during the
+ ${../if/set-priority:/name} call.
+ - name: Invalid
+ test-code: |
+ ctx->new_priority = PRIO_INVALID;
+ text: |
+ While the value of the ${../if/set-priority:/params[1]/name} parameter is
+ not equal to ${../if/current-priority:/name}, while the value of the
+ ${../if/set-priority:/params[1]/name} parameter is an invalid
+ ${/glossary/priority-task:/term} with respect to the
+ ${/glossary/scheduler-home:/term} of the task specified by the
+ ${../if/set-priority:/params[0]/name} parameter at some point during the
+ ${../if/set-priority:/name} call.
+ test-epilogue: null
+ test-prologue: null
+- name: OldPriority
+ states:
+ - name: Valid
+ test-code: |
+ ctx->old_priority = &ctx->old_priority_obj;
+ text: |
+ While the ${../if/set-priority:/params[2]/name} parameter references an
+ object of type ${../../type/if/priority:/name}.
+ - name: 'Null'
+ test-code: |
+ ctx->old_priority = NULL;
+ text: |
+ While the ${../if/set-priority:/params[2]/name} parameter is equal to
+ ${/c/if/null:/name}.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ ctx->status = rtems_task_set_priority(
+ ctx->id,
+ ctx->new_priority,
+ ctx->old_priority
+ );
+test-brief: null
+test-cleanup: |
+ DeleteTask( ctx->worker_id );
+test-context:
+- brief: |
+ This member contains the worker task identifier.
+ description: null
+ member: |
+ rtems_id worker_id
+- brief: |
+ This member provides the object referenced by the
+ ${../if/set-priority:/params[2]/name} parameter.
+ description: null
+ member: |
+ rtems_task_priority old_priority_obj
+- brief: |
+ This member contains the return value of the ${../if/set-priority:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/set-priority:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id id
+- brief: |
+ This member specifies if the ${../if/set-priority:/params[1]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_task_priority new_priority
+- brief: |
+ This member specifies if the ${../if/set-priority:/params[2]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_task_priority *old_priority
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+test-local-includes:
+- tx-support.h
+test-prepare:
+ ctx->old_priority_obj = PRIO_INVALID;
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+test-setup: null
+test-stop: null
+test-support: null
+test-target: testsuites/validation/tc-task-set-priority.c
+test-teardown: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Priority: Nop
+ OldPriorityObj: Set
+ pre-conditions:
+ Id:
+ - Task
+ NewPriority:
+ - Current
+ OldPriority:
+ - Valid
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Priority: Set
+ OldPriorityObj: Set
+ pre-conditions:
+ Id:
+ - Task
+ NewPriority:
+ - Valid
+ OldPriority:
+ - Valid
+- enabled-by: true
+ post-conditions:
+ Status: InvAddr
+ Priority: Nop
+ OldPriorityObj: Nop
+ pre-conditions:
+ Id:
+ - Task
+ NewPriority: all
+ OldPriority:
+ - 'Null'
+- enabled-by: true
+ post-conditions:
+ Status: InvAddr
+ Priority: Nop
+ OldPriorityObj: Nop
+ pre-conditions:
+ Id:
+ - Invalid
+ NewPriority: N/A
+ OldPriority:
+ - 'Null'
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ Priority: Nop
+ OldPriorityObj: Nop
+ pre-conditions:
+ Id:
+ - Invalid
+ NewPriority: all
+ OldPriority:
+ - Valid
+- enabled-by: true
+ post-conditions:
+ Status: InvPrio
+ Priority: Nop
+ OldPriorityObj: Set
+ pre-conditions:
+ Id:
+ - Task
+ NewPriority:
+ - Invalid
+ OldPriority:
+ - Valid
+type: requirement
diff --git a/spec/rtems/task/req/set-scheduler.yml b/spec/rtems/task/req/set-scheduler.yml
new file mode 100644
index 00000000..94e9ff6b
--- /dev/null
+++ b/spec/rtems/task/req/set-scheduler.yml
@@ -0,0 +1,983 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/set-scheduler
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/set-scheduler:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvAddr
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ text: |
+ The return status of ${../if/set-scheduler:/name} shall be
+ ${../../status/if/invalid-address:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/set-scheduler:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: InvPrio
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
+ text: |
+ The return status of ${../if/set-scheduler:/name} shall be
+ ${../../status/if/invalid-priority:/name}.
+ - name: InUse
+ test-code: |
+ T_rsc( ctx->status, RTEMS_RESOURCE_IN_USE );
+ text: |
+ The return status of ${../if/set-scheduler:/name} shall be
+ ${../../status/if/resource-in-use:/name}.
+ - name: Unsat
+ test-code: |
+ T_rsc( ctx->status, RTEMS_UNSATISFIED );
+ text: |
+ The return status of ${../if/set-scheduler:/name} shall be
+ ${../../status/if/unsatisfied:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: Scheduler
+ states:
+ - name: Set
+ test-code: |
+ T_eq_u32( ctx->new_scheduler, ctx->scheduler_to_set_id );
+ text: |
+ The ${/glossary/scheduler-home:/term} of the task specified by the
+ ${../if/set-scheduler:/params[0]/name} parameter shall be set to the
+ scheduler specified by the ${../if/set-scheduler:/params[1]/name}
+ parameter at some point during the ${../if/set-scheduler:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_u32( ctx->new_scheduler, ctx->scheduler_a_id );
+ text: |
+ No ${/glossary/scheduler-home:/term} of a task shall be modified by the
+ ${../if/set-scheduler:/name} call.
+ test-epilogue: null
+ test-prologue: null
+- name: Priority
+ states:
+ - name: Set
+ test-code: |
+ if ( ctx->scheduler_to_set_id == ctx->scheduler_a_id ) {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_VERY_LOW );
+ T_eq_u32( ctx->new_priority[ 1 ], PRIO_INVALID );
+ } else {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_INVALID );
+ T_eq_u32( ctx->new_priority[ 1 ], PRIO_VERY_LOW );
+ }
+ text: |
+ The ${/glossary/priority-real:/term} of the task specified by the
+ ${../if/set-scheduler:/params[0]/name} parameter shall be set to the
+ priority specified by the ${../if/set-scheduler:/params[2]/name}
+ parameter at some point during the ${../if/set-scheduler:/name} call.
+ - name: Nop
+ test-code: |
+ if ( ctx->blocked ) {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_HIGH );
+ } else {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_LOW );
+ }
+
+ T_eq_u32( ctx->new_priority[ 1 ], PRIO_INVALID );
+ text: |
+ No task priority shall be modified by the ${../if/set-scheduler:/name}
+ call.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: TaskId
+ states:
+ - name: Task
+ test-code: |
+ ctx->task_id = ctx->worker_id[ 0 ];
+ text: |
+ While the ${../if/set-scheduler:/params[0]/name} parameter is
+ associated with a task.
+ - name: Invalid
+ test-code: |
+ ctx->task_id = INVALID_ID;
+ text: |
+ While the ${../if/set-scheduler:/params[0]/name} parameter is not
+ associated with a task.
+ test-epilogue: null
+ test-prologue: null
+- name: Scheduler
+ states:
+ - name: Home
+ test-code: |
+ ctx->scheduler_to_set_id = ctx->scheduler_a_id;
+ text: |
+ While the scheduler specified by the
+ ${../if/set-scheduler:/params[1]/name} parameter is the
+ ${/glossary/scheduler-home:/term} of the task specified by the
+ ${../if/set-scheduler:/params[0]/name} parameter.
+ - name: Other
+ test-code: |
+ ctx->scheduler_to_set_id = ctx->scheduler_b_id;
+ text: |
+ While the scheduler specified by the
+ ${../if/set-scheduler:/params[1]/name} parameter is not the
+ ${/glossary/scheduler-home:/term} of the task specified by the
+ ${../if/set-scheduler:/params[0]/name} parameter.
+ test-epilogue: null
+ test-prologue: null
+- name: SchedulerHasCPU
+ states:
+ - name: 'Yes'
+ test-code: |
+ /* Already set by Scheduler pre-condition */
+ text: |
+ While the scheduler specified by the
+ ${../if/set-scheduler:/params[1]/name} parameter owns at least one
+ processor.
+ - name: 'No'
+ test-code: |
+ ctx->scheduler_to_set_id = ctx->scheduler_d_id;
+ text: |
+ While the scheduler specified by the
+ ${../if/set-scheduler:/params[1]/name} parameter owns no processor.
+ test-epilogue: null
+ test-prologue: null
+- name: SchedulerId
+ states:
+ - name: Scheduler
+ test-code: |
+ ctx->scheduler_id = ctx->scheduler_to_set_id;
+ text: |
+ While the ${../if/set-scheduler:/params[1]/name} parameter is
+ associated with a scheduler.
+ - name: Invalid
+ test-code: |
+ ctx->scheduler_id = INVALID_ID;
+ text: |
+ While the ${../if/set-scheduler:/params[1]/name} parameter is not
+ associated with a scheduler.
+ test-epilogue: null
+ test-prologue: null
+- name: Priority
+ states:
+ - name: Valid
+ test-code: |
+ ctx->priority = PRIO_VERY_LOW;
+ text: |
+ While the ${/glossary/priority-task:/term} specified by the
+ ${../if/set-scheduler:/params[2]/name} parameter is valid with respect to
+ the scheduler specified by the ${../if/set-scheduler:/params[1]/name}
+ parameter.
+ - name: Invalid
+ test-code: |
+ ctx->priority = PRIO_INVALID;
+ text: |
+ While the ${/glossary/priority-task:/term} specified by the
+ ${../if/set-scheduler:/params[2]/name} parameter is invalid with respect
+ to the scheduler specified by the ${../if/set-scheduler:/params[1]/name}
+ parameter.
+ test-epilogue: null
+ test-prologue: null
+- name: HomePriority
+ states:
+ - name: Real
+ test-code: |
+ ctx->additional_home_priority = false;
+ text: |
+ While the ${/glossary/priority-current:/term} of the task specified by
+ the ${../if/set-scheduler:/params[0]/name} parameter consists only of the
+ ${/glossary/priority-real:/term}.
+ - name: More
+ test-code: |
+ ctx->additional_home_priority = true;
+ text: |
+ While the ${/glossary/priority-current:/term} of the task specified by
+ the ${../if/set-scheduler:/params[0]/name} parameter consists of more
+ than the ${/glossary/priority-real:/term}.
+ test-epilogue: null
+ test-prologue: null
+- name: EligiblePriorities
+ states:
+ - name: OnlyOne
+ test-code: |
+ ctx->second_eligible_scheduler = false;
+ text: |
+ While the set of ${/glossary/priority-eligible:/plural} of the task
+ specified by the ${../if/set-scheduler:/params[0]/name} parameter
+ consists of exactly the ${/glossary/priority-current:/term}.
+ - name: More
+ test-code: |
+ ctx->second_eligible_scheduler = true;
+ text: |
+ While the set of ${/glossary/priority-eligible:/plural} of the task
+ specified by the ${../if/set-scheduler:/params[0]/name} parameter
+ consists of more than the ${/glossary/priority-current:/term}.
+ test-epilogue: null
+ test-prologue: null
+- name: Pinned
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->pinned = true;
+ text: |
+ While the task specified by the ${../if/set-scheduler:/params[0]/name}
+ parameter is pinned.
+ - name: 'No'
+ test-code: |
+ ctx->pinned = false;
+ text: |
+ While the task specified by the ${../if/set-scheduler:/params[0]/name}
+ parameter is not pinned.
+ test-epilogue: null
+ test-prologue: null
+- name: TaskState
+ states:
+ - name: Ready
+ test-code: |
+ ctx->blocked = false;
+ ctx->enqueued = false;
+ text: |
+ While the task specified by the ${../if/set-scheduler:/params[0]/name}
+ parameter is ready.
+ - name: Blocked
+ test-code: |
+ ctx->blocked = true;
+ ctx->enqueued = false;
+ text: |
+ While the task specified by the ${../if/set-scheduler:/params[0]/name}
+ parameter is blocked, while the task specified by the
+ ${../if/set-scheduler:/params[0]/name} parameter is not enqueued on a
+ ${/glossary/waitqueue:/term}.
+ - name: Enqueued
+ test-code: |
+ ctx->blocked = true;
+ ctx->enqueued = true;
+ text: |
+ While the task specified by the ${../if/set-scheduler:/params[0]/name}
+ parameter is blocked, while the task specified by the
+ ${../if/set-scheduler:/params[0]/name} parameter is enqueued on a
+ ${/glossary/waitqueue:/term}.
+ test-epilogue: null
+ test-prologue: null
+- name: AffinitySupported
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->affinity_supported = true;
+ text: |
+ While the affinity set of the task specified by the
+ ${../if/set-scheduler:/params[0]/name} parameter is supported by the
+ scheduler specified by the ${../if/set-scheduler:/params[1]/name}
+ parameter.
+ - name: 'No'
+ test-code: |
+ ctx->affinity_supported = false;
+ text: |
+ While the affinity set of the task specified by the
+ ${../if/set-scheduler:/params[0]/name} parameter is not supported by the
+ scheduler specified by the ${../if/set-scheduler:/params[1]/name}
+ parameter.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons:
+ OnlyOneCPU: |
+ Where the system was built with SMP support disabled, exactly one scheduler
+ is present in an application using exactly one processor.
+ HomeScheduler: |
+ The ${/glossary/scheduler-home:/term} of a task owns always at least one
+ processor and the affinity set of the task is always supported its home
+ scheduler.
+test-action: |
+ rtems_status_code sc;
+
+ if ( ctx->additional_home_priority || ctx->second_eligible_scheduler ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_OBTAIN_MUTEX_A );
+
+ if ( ctx->additional_home_priority ) {
+ SendEvents( ctx->worker_id[ 1 ], EVENT_OBTAIN_MUTEX_A );
+ }
+
+ if ( ctx->second_eligible_scheduler ) {
+ SendEvents(
+ ctx->worker_id[ 2 ],
+ EVENT_RUNNER_SYNC_0 | EVENT_OBTAIN_MUTEX_A
+ );
+ ReceiveAllEvents( EVENT_RUNNER_SYNC_0 );
+ WaitForExecutionStop( ctx->worker_id[ 2 ] );
+ }
+ }
+
+ if ( ctx->blocked && ctx->enqueued ) {
+ ObtainMutex( ctx->mutex_id[ 1 ] );
+ SendEvents( ctx->worker_id[ 0 ], EVENT_OBTAIN_MUTEX_B );
+ }
+
+ if ( !ctx->affinity_supported ) {
+ SetAffinityOne( ctx->worker_id[ 0 ], 0 );
+ }
+
+ if ( ctx->pinned ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_PIN );
+ }
+
+ if ( !ctx->blocked ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_SET_LOW_PRIO );
+ }
+
+ ctx->status = rtems_task_set_scheduler(
+ ctx->task_id,
+ ctx->scheduler_id,
+ ctx->priority
+ );
+
+ ctx->new_scheduler = GetScheduler( ctx->worker_id[ 0 ] );
+
+ if ( ctx->pinned ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_UNPIN );
+ }
+
+ if ( !ctx->affinity_supported ) {
+ SetAffinityAll( ctx->worker_id[ 0 ] );
+ }
+
+ if ( ctx->blocked && ctx->enqueued ) {
+ ReleaseMutex( ctx->mutex_id[ 1 ] );
+ SendEvents( ctx->worker_id[ 0 ], EVENT_RELEASE_MUTEX_B );
+ }
+
+ if ( ctx->additional_home_priority || ctx->second_eligible_scheduler ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_RELEASE_MUTEX_A );
+
+ if ( ctx->additional_home_priority ) {
+ SendEvents( ctx->worker_id[ 1 ], EVENT_RELEASE_MUTEX_A );
+ }
+
+ if ( ctx->second_eligible_scheduler ) {
+ SendEvents(
+ ctx->worker_id[ 2 ],
+ EVENT_RELEASE_MUTEX_A | EVENT_RUNNER_SYNC_1
+ );
+ ReceiveAllEvents( EVENT_RUNNER_SYNC_1 );
+ }
+ }
+
+ sc = rtems_task_get_priority(
+ ctx->worker_id[ 0 ],
+ ctx->scheduler_a_id,
+ &ctx->new_priority[ 0 ]
+ );
+
+ if ( sc == RTEMS_NOT_DEFINED ) {
+ ctx->new_priority[ 0 ] = PRIO_INVALID;
+ } else {
+ T_rsc_success( sc );
+ }
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_task_get_priority(
+ ctx->worker_id[ 0 ],
+ ctx->scheduler_b_id,
+ &ctx->new_priority[ 1 ]
+ );
+
+ if ( sc == RTEMS_NOT_DEFINED ) {
+ ctx->new_priority[ 1 ] = PRIO_INVALID;
+ } else {
+ T_rsc_success( sc );
+ }
+ #else
+ ctx->new_priority[ 1 ] = PRIO_INVALID;
+ #endif
+
+ if ( ctx->status == RTEMS_SUCCESSFUL ) {
+ SetScheduler( ctx->worker_id[ 0 ], ctx->scheduler_a_id, PRIO_HIGH );
+ } else if ( !ctx->blocked ) {
+ SetPriority( ctx->worker_id[ 0 ], PRIO_HIGH );
+ }
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This member contains the runner task identifier.
+ description: null
+ member: |
+ rtems_id runner_id
+- brief: |
+ This member contains the scheduler A identifier.
+ description: null
+ member: |
+ rtems_id scheduler_a_id
+- brief: |
+ This member contains the scheduler B identifier.
+ description: null
+ member: |
+ rtems_id scheduler_b_id
+- brief: |
+ This member contains the scheduler D identifier.
+ description: null
+ member: |
+ rtems_id scheduler_d_id
+- brief: |
+ This member contains the worker task identifiers.
+ description: null
+ member: |
+ rtems_id worker_id[ 3 ]
+- brief: |
+ This member contains the mutex identifiers.
+ description: null
+ member: |
+ rtems_id mutex_id[ 2 ]
+- brief: |
+ If this member is true, then the task shall have an additional
+ priority for the home scheduler.
+ description: null
+ member: |
+ bool additional_home_priority
+- brief: |
+ If this member is true, then the task shall have a second eligible
+ scheduler.
+ description: null
+ member: |
+ bool second_eligible_scheduler
+- brief: |
+ If this member is true, then the task shall be pinned to a processor.
+ description: null
+ member: |
+ bool pinned
+- brief: |
+ If this member is true, then the task shall be blocked.
+ description: null
+ member: |
+ bool blocked
+- brief: |
+ If this member is true, then the task shall be enqueued on a thread queue.
+ description: null
+ member: |
+ bool enqueued
+- brief: |
+ This member specifies the scheduler identifier to set.
+ description: null
+ member: |
+ rtems_id scheduler_to_set_id
+- brief: |
+ If this member is true, then the affinity of the task shall be supported by
+ the scheduler.
+ description: null
+ member: |
+ bool affinity_supported
+- brief: |
+ This member contains the return value of the ${../if/set-scheduler:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/set-scheduler:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id task_id
+- brief: |
+ This member specifies if the ${../if/set-scheduler:/params[1]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id scheduler_id
+- brief: |
+ This member specifies if the ${../if/set-scheduler:/params[2]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_task_priority priority
+- brief: |
+ This member contains the identifier of the new scheduler.
+ description: null
+ member: |
+ rtems_id new_scheduler;
+- brief: |
+ This member contains the new priorities of the task.
+ description: null
+ member: |
+ rtems_task_priority new_priority[ 2 ]
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+- rtems/score/threadimpl.h
+test-local-includes:
+- ts-config.h
+- tx-support.h
+test-prepare: null
+test-setup:
+ brief: null
+ code: |
+ rtems_status_code sc;
+ size_t i;
+
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->runner_id = rtems_task_self();
+ SetSelfPriority( PRIO_NORMAL );
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_A_NAME,
+ &ctx->scheduler_a_id
+ );
+ T_rsc_success( sc );
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->mutex_id ); ++i ) {
+ ctx->mutex_id[ i ] = CreateMutex();
+ }
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_id ); ++i ) {
+ ctx->worker_id[ i ] = CreateTask( "WORK", PRIO_HIGH - i );
+ StartTask( ctx->worker_id[ i ], Worker, ctx );
+ }
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_B_NAME, &ctx->scheduler_b_id );
+ T_rsc_success( sc );
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_D_NAME, &ctx->scheduler_d_id );
+ T_rsc_success( sc );
+
+ SetScheduler( ctx->worker_id[ 2 ], ctx->scheduler_b_id, PRIO_NORMAL );
+ #else
+ ctx->scheduler_b_id = INVALID_ID;
+ #endif
+ description: null
+test-stop: null
+test-support: |
+ typedef RtemsTaskReqSetScheduler_Context Context;
+
+ #define EVENT_OBTAIN_MUTEX_A RTEMS_EVENT_0
+
+ #define EVENT_RELEASE_MUTEX_A RTEMS_EVENT_1
+
+ #define EVENT_OBTAIN_MUTEX_B RTEMS_EVENT_2
+
+ #define EVENT_RELEASE_MUTEX_B RTEMS_EVENT_3
+
+ #define EVENT_PIN RTEMS_EVENT_4
+
+ #define EVENT_UNPIN RTEMS_EVENT_5
+
+ #define EVENT_SET_LOW_PRIO RTEMS_EVENT_6
+
+ #define EVENT_RUNNER_SYNC_0 RTEMS_EVENT_7
+
+ #define EVENT_RUNNER_SYNC_1 RTEMS_EVENT_8
+
+ static void Worker( rtems_task_argument arg )
+ {
+ Context *ctx;
+ Thread_Control *executing;
+
+ ctx = (Context *) arg;
+ executing = _Thread_Get_executing();
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+
+ if ( ( events & EVENT_RUNNER_SYNC_0 ) != 0 ) {
+ SendEvents( ctx->runner_id, EVENT_RUNNER_SYNC_0 );
+ }
+
+ if ( ( events & EVENT_OBTAIN_MUTEX_A ) != 0 ) {
+ ObtainMutex( ctx->mutex_id[ 0 ] );
+ }
+
+ if ( ( events & EVENT_RELEASE_MUTEX_A ) != 0 ) {
+ ReleaseMutex( ctx->mutex_id[ 0 ] );
+ }
+
+ if ( ( events & EVENT_OBTAIN_MUTEX_B ) != 0 ) {
+ ObtainMutex( ctx->mutex_id[ 1 ] );
+ }
+
+ if ( ( events & EVENT_RELEASE_MUTEX_B ) != 0 ) {
+ ReleaseMutex( ctx->mutex_id[ 1 ] );
+ }
+
+ if ( ( events & EVENT_PIN ) != 0 ) {
+ _Thread_Pin( executing );
+ }
+
+ if ( ( events & EVENT_UNPIN ) != 0 ) {
+ _Thread_Unpin( executing, _Per_CPU_Get_snapshot() );
+ }
+
+ if ( ( events & EVENT_SET_LOW_PRIO ) != 0 ) {
+ SetSelfPriority( PRIO_LOW );
+ }
+
+ if ( ( events & EVENT_RUNNER_SYNC_1 ) != 0 ) {
+ SendEvents( ctx->runner_id, EVENT_RUNNER_SYNC_1 );
+ }
+ }
+ }
+test-target: testsuites/validation/tc-task-set-scheduler.c
+test-teardown:
+ brief: null
+ code: |
+ size_t i;
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_id ); ++i ) {
+ DeleteTask( ctx->worker_id[ i ] );
+ }
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->mutex_id ); ++i ) {
+ DeleteMutex( ctx->mutex_id[ i ] );
+ }
+
+ RestoreRunnerPriority();
+ description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ Scheduler: Set
+ Priority: Set
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Priority:
+ - Valid
+ HomePriority:
+ - Real
+ EligiblePriorities:
+ - OnlyOne
+ Pinned:
+ - 'No'
+ TaskState:
+ - Ready
+ - Blocked
+ Scheduler: all
+ SchedulerHasCPU:
+ - 'Yes'
+ AffinitySupported:
+ - 'Yes'
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Invalid
+ Priority: N/A
+ HomePriority: all
+ EligiblePriorities: all
+ Pinned: all
+ TaskState: all
+ Scheduler: N/A
+ SchedulerHasCPU: N/A
+ AffinitySupported: N/A
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Invalid
+ SchedulerId:
+ - Scheduler
+ Priority:
+ - Valid
+ HomePriority: N/A
+ EligiblePriorities: N/A
+ Pinned: N/A
+ TaskState: N/A
+ Scheduler: all
+ SchedulerHasCPU: all
+ AffinitySupported: all
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Invalid
+ SchedulerId:
+ - Invalid
+ Priority: N/A
+ HomePriority: N/A
+ EligiblePriorities: N/A
+ Pinned: N/A
+ TaskState: N/A
+ Scheduler: N/A
+ SchedulerHasCPU: N/A
+ AffinitySupported: N/A
+- enabled-by: true
+ post-conditions:
+ Status: InvPrio
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Invalid
+ SchedulerId:
+ - Scheduler
+ Priority:
+ - Invalid
+ HomePriority: N/A
+ EligiblePriorities: N/A
+ Pinned: N/A
+ TaskState: N/A
+ Scheduler: all
+ SchedulerHasCPU: all
+ AffinitySupported: all
+- enabled-by: true
+ post-conditions:
+ Status: InvPrio
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Priority:
+ - Invalid
+ HomePriority: all
+ EligiblePriorities: all
+ TaskState: all
+ Pinned: all
+ Scheduler: all
+ SchedulerHasCPU: all
+ AffinitySupported: all
+- enabled-by: true
+ post-conditions:
+ Status: InUse
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Priority:
+ - Valid
+ HomePriority: all
+ EligiblePriorities: all
+ TaskState:
+ - Enqueued
+ Pinned: all
+ Scheduler: all
+ SchedulerHasCPU: all
+ AffinitySupported: all
+- enabled-by: true
+ post-conditions:
+ Status: InUse
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Priority:
+ - Valid
+ HomePriority:
+ - More
+ EligiblePriorities: all
+ TaskState:
+ - Ready
+ - Blocked
+ Pinned: all
+ Scheduler: all
+ SchedulerHasCPU: all
+ AffinitySupported: all
+- enabled-by: true
+ post-conditions:
+ Status: InUse
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Priority:
+ - Valid
+ HomePriority:
+ - Real
+ EligiblePriorities:
+ - More
+ TaskState:
+ - Ready
+ - Blocked
+ Pinned: all
+ Scheduler: all
+ SchedulerHasCPU: all
+ AffinitySupported: all
+- enabled-by: true
+ post-conditions:
+ Status: InUse
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Priority:
+ - Valid
+ HomePriority:
+ - Real
+ EligiblePriorities:
+ - OnlyOne
+ Pinned:
+ - 'Yes'
+ TaskState:
+ - Ready
+ - Blocked
+ Scheduler: all
+ SchedulerHasCPU: all
+ AffinitySupported: all
+- enabled-by: true
+ post-conditions:
+ Status: Unsat
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Priority:
+ - Valid
+ HomePriority:
+ - Real
+ EligiblePriorities:
+ - OnlyOne
+ TaskState:
+ - Ready
+ - Blocked
+ Pinned:
+ - 'No'
+ Scheduler: all
+ SchedulerHasCPU:
+ - 'No'
+ AffinitySupported: all
+- enabled-by: true
+ post-conditions:
+ Status: Unsat
+ Scheduler: Nop
+ Priority: Nop
+ pre-conditions:
+ TaskId:
+ - Task
+ SchedulerId:
+ - Scheduler
+ Priority:
+ - Valid
+ HomePriority:
+ - Real
+ EligiblePriorities:
+ - OnlyOne
+ TaskState:
+ - Ready
+ - Blocked
+ Pinned:
+ - 'No'
+ Scheduler: all
+ SchedulerHasCPU:
+ - 'Yes'
+ AffinitySupported:
+ - 'No'
+- enabled-by: true
+ post-conditions: HomeScheduler
+ pre-conditions:
+ TaskId: all
+ SchedulerId: all
+ Priority: all
+ HomePriority: all
+ EligiblePriorities: all
+ Pinned: all
+ TaskState: all
+ Scheduler:
+ - Home
+ SchedulerHasCPU:
+ - 'No'
+ AffinitySupported: all
+- enabled-by: true
+ post-conditions: HomeScheduler
+ pre-conditions:
+ TaskId: all
+ SchedulerId: all
+ Priority: all
+ HomePriority: all
+ EligiblePriorities: all
+ Pinned: all
+ TaskState: all
+ Scheduler:
+ - Home
+ SchedulerHasCPU: all
+ AffinitySupported:
+ - 'No'
+- enabled-by:
+ not: RTEMS_SMP
+ post-conditions: OnlyOneCPU
+ pre-conditions:
+ TaskId: all
+ SchedulerId: all
+ Priority: all
+ HomePriority: all
+ EligiblePriorities:
+ - More
+ Pinned: all
+ TaskState: all
+ Scheduler: all
+ SchedulerHasCPU: all
+ AffinitySupported: all
+- enabled-by:
+ not: RTEMS_SMP
+ post-conditions: OnlyOneCPU
+ pre-conditions:
+ TaskId: all
+ SchedulerId: all
+ Priority: all
+ HomePriority: all
+ EligiblePriorities: all
+ Pinned: all
+ TaskState: all
+ Scheduler:
+ - Other
+ SchedulerHasCPU: all
+ AffinitySupported: all
+- enabled-by:
+ not: RTEMS_SMP
+ post-conditions: OnlyOneCPU
+ pre-conditions:
+ TaskId: all
+ SchedulerId: all
+ Priority: all
+ HomePriority: all
+ EligiblePriorities: all
+ Pinned:
+ - 'Yes'
+ TaskState: all
+ Scheduler: all
+ SchedulerHasCPU: all
+ AffinitySupported: all
+type: requirement
diff --git a/spec/rtems/task/req/start.yml b/spec/rtems/task/req/start.yml
new file mode 100644
index 00000000..74c9bf54
--- /dev/null
+++ b/spec/rtems/task/req/start.yml
@@ -0,0 +1,422 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/start
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/start:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvAddr
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ text: |
+ The return status of ${../if/start:/name} shall be
+ ${../../status/if/invalid-address:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/start:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: IncStat
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ text: |
+ The return status of ${../if/start:/name} shall be
+ ${../../status/if/incorrect-state:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: EntryPoint
+ states:
+ - name: Set
+ test-code: |
+ T_eq_u32( ctx->counter, 1 );
+ text: |
+ The entry point of the task specified by the
+ ${../if/start:/params[0]/name} parameter shall be set to the function
+ specified by the ${../if/start:/params[1]/name} parameter before the task
+ is unblocked by the ${../if/start:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_u32( ctx->counter, 0 );
+ text: |
+ No entry point of a task shall be modified by the ${../if/start:/name}
+ call.
+ test-epilogue: null
+ test-prologue: null
+- name: Argument
+ states:
+ - name: Set
+ test-code: |
+ T_eq_u32( ctx->actual_argument, ctx->argument );
+ text: |
+ The entry point argument of the task specified by the
+ ${../if/start:/params[0]/name} parameter shall be set to the value
+ specified by the ${../if/start:/params[2]/name} parameter before the task
+ is unblocked by the ${../if/start:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_u32( ctx->actual_argument, 0 );
+ text: |
+ No entry point argument of a task shall be modified by the
+ ${../if/start:/name} call.
+ test-epilogue: null
+ test-prologue: null
+- name: Unblock
+ states:
+ - name: 'Yes'
+ test-code: |
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_UNBLOCK
+ );
+ text: |
+ The task specified by the ${../if/start:/params[0]/name} parameter shall
+ be unblocked by the ${../if/start:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ text: |
+ No task shall be unblocked by the ${../if/start:/name} call.
+ test-epilogue: null
+ test-prologue: null
+- name: StartExtensions
+ states:
+ - name: 'Yes'
+ test-code: |
+ T_eq_u32( ctx->start_extension_calls, 1 );
+ text: |
+ The thread start user extensions shall be invoked by the
+ ${../if/start:/name} call.
+ - name: Nop
+ test-code: |
+ T_eq_u32( ctx->start_extension_calls, 0 );
+ text: |
+ The thread start user extensions shall not be invoked by the
+ ${../if/start:/name} call.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Id
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->id = INVALID_ID;
+ text: |
+ While the ${../if/start:/params[0]/name} parameter is not associated with
+ a task.
+ - name: Task
+ test-code: |
+ ctx->id = ctx->worker_id;
+ text: |
+ While the ${../if/start:/params[0]/name} parameter is associated with a
+ task.
+ test-epilogue: null
+ test-prologue: null
+- name: EntryPoint
+ states:
+ - name: Valid
+ test-code: |
+ ctx->entry_point = WorkerA;
+ text: |
+ While the task entry point specified by the
+ ${../if/start:/params[1]/name} parameter is valid.
+ - name: 'Null'
+ test-code: |
+ ctx->entry_point = NULL;
+ text: |
+ While the task entry point specified by the
+ ${../if/start:/params[1]/name} parameter is equal to ${/c/if/null:/name}.
+ test-epilogue: null
+ test-prologue: null
+- name: Argument
+ states:
+ - name: Pointer
+ test-code: |
+ ctx->argument = (rtems_task_argument) ctx;
+ text: |
+ While the entry point argument specified by the
+ ${../if/start:/params[2]/name} parameter is a pointer.
+ - name: Number
+ test-code: |
+ ctx->argument = UINT32_C( 0x87654321 );
+ text: |
+ While the entry point argument specified by the
+ ${../if/start:/params[2]/name} parameter is a 32-bit number.
+ test-epilogue: null
+ test-prologue: null
+- name: Dormant
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->start = false;
+ text: |
+ While the task specified by the ${../if/start:/params[0]/name} parameter
+ is dormant.
+ - name: 'No'
+ test-code: |
+ ctx->start = true;
+ text: |
+ While the task specified by the ${../if/start:/params[0]/name} parameter
+ is not dormant.
+ test-epilogue: null
+ test-prologue: null
+- name: Suspended
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->suspend = true;
+ text: |
+ While the task specified by the ${../if/start:/params[0]/name} parameter
+ is suspended.
+ - name: 'No'
+ test-code: |
+ ctx->suspend = false;
+ text: |
+ While the task specified by the ${../if/start:/params[0]/name} parameter
+ is not suspended.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ T_scheduler_log *log;
+
+ if ( ctx->start ) {
+ StartTask( ctx->worker_id, WorkerB, 0 );
+ }
+
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->start_extension_calls = 0;
+
+ log = T_scheduler_record_2( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_task_start( ctx->id, ctx->entry_point, ctx->argument );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+
+ Yield();
+test-brief: null
+test-cleanup: |
+ DeleteTask( ctx->worker_id );
+test-context:
+- brief: |
+ This member provides the scheduler operation records.
+ description: null
+ member: |
+ T_scheduler_log_2 scheduler_log
+- brief: |
+ This member contains the identifier of a task.
+ description: null
+ member: |
+ rtems_id worker_id
+- brief: |
+ This member contains the identifier of the test user extensions.
+ description: null
+ member: |
+ rtems_id extension_id
+- brief: |
+ This member contains the count of thread start extension calls.
+ description: null
+ member: |
+ uint32_t start_extension_calls
+- brief: |
+ This member contains the actual argument passed to the entry point.
+ description: null
+ member: |
+ rtems_task_argument actual_argument
+- brief: |
+ This member contains the entry point counter.
+ description: null
+ member: |
+ uint32_t counter
+- brief: |
+ If this member is true, then the worker is started before the
+ ${../if/start:/name} call.
+ description: null
+ member: |
+ bool start
+- brief: |
+ If this member is true, then the worker is suspended before the
+ ${../if/start:/name} call.
+ description: null
+ member: |
+ bool suspend
+- brief: |
+ This member contains the return value of the ${../if/start:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/start:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id id
+- brief: |
+ This member specifies if the ${../if/start:/params[1]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_task_entry entry_point
+- brief: |
+ This member specifies if the ${../if/start:/params[2]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_task_argument argument
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+- rtems/test-scheduler.h
+test-local-includes:
+- tx-support.h
+test-prepare: |
+ ctx->actual_argument = 0;
+ ctx->counter = 0;
+ ctx->worker_id = CreateTask( "WORK", PRIO_DEFAULT );
+test-setup:
+ brief: null
+ code: |
+ rtems_status_code sc;
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'E', 'S', 'T' ),
+ &extensions,
+ &ctx->extension_id
+ );
+ T_rsc_success( sc );
+ description: null
+test-stop: null
+test-support: |
+ typedef RtemsTaskReqStart_Context Context;
+
+ static void WorkerA( rtems_task_argument arg )
+ {
+ Context *ctx;
+
+ ctx = &RtemsTaskReqStart_Instance;
+
+ while ( true ) {
+ ctx->actual_argument += arg;
+ ++ctx->counter;
+ Yield();
+ }
+ }
+
+ static void WorkerB( rtems_task_argument arg )
+ {
+ Context *ctx;
+
+ ctx = &RtemsTaskReqStart_Instance;
+
+ while ( true ) {
+ ctx->actual_argument += arg;
+ Yield();
+ }
+ }
+
+ static void ThreadStart( rtems_tcb *executing, rtems_tcb *started )
+ {
+ (void) executing;
+ (void) started;
+
+ ++RtemsTaskReqStart_Instance.start_extension_calls;
+ }
+
+ static const rtems_extensions_table extensions = {
+ .thread_start = ThreadStart
+ };
+test-target: testsuites/validation/tc-task-start.c
+test-teardown:
+ brief: null
+ code: |
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->extension_id );
+ T_rsc_success( sc );
+ description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ EntryPoint: Set
+ Argument: Set
+ Unblock: 'Yes'
+ StartExtensions: 'Yes'
+ pre-conditions:
+ Id:
+ - Task
+ EntryPoint:
+ - Valid
+ Argument: all
+ Dormant:
+ - 'Yes'
+ Suspended: all
+- enabled-by: true
+ post-conditions:
+ Status: InvAddr
+ EntryPoint: Nop
+ Argument: Nop
+ Unblock: Nop
+ StartExtensions: Nop
+ pre-conditions:
+ Id: all
+ EntryPoint:
+ - 'Null'
+ Argument: all
+ Dormant: all
+ Suspended: all
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ EntryPoint: Nop
+ Argument: Nop
+ Unblock: Nop
+ StartExtensions: Nop
+ pre-conditions:
+ Id:
+ - Invalid
+ EntryPoint:
+ - Valid
+ Argument: all
+ Dormant: N/A
+ Suspended: N/A
+- enabled-by: true
+ post-conditions:
+ Status: IncStat
+ EntryPoint: Nop
+ Argument: Nop
+ Unblock: Nop
+ StartExtensions: Nop
+ pre-conditions:
+ Id:
+ - Task
+ EntryPoint:
+ - Valid
+ Argument: all
+ Dormant:
+ - 'No'
+ Suspended: all
+type: requirement
diff --git a/spec/rtems/task/req/storage-alignment.yml b/spec/rtems/task/req/storage-alignment.yml
new file mode 100644
index 00000000..f7f46f64
--- /dev/null
+++ b/spec/rtems/task/req/storage-alignment.yml
@@ -0,0 +1,16 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: true
+links:
+- role: interface-function
+ uid: ../if/storage-alignment
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ The ${../if/storage-alignment:/name} define shall expand to a constant
+ expression which evaluates to the value of
+ ${/score/stack/if/alignment:/name}.
+type: requirement
diff --git a/spec/rtems/task/req/storage-size.yml b/spec/rtems/task/req/storage-size.yml
new file mode 100644
index 00000000..70ed1c8f
--- /dev/null
+++ b/spec/rtems/task/req/storage-size.yml
@@ -0,0 +1,158 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/storage-size
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/suspend:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/suspend:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: AlrdySus
+ test-code: |
+ T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
+ text: |
+ The return status of ${../if/suspend:/name} shall be
+ ${../../status/if/already-suspended:/name}.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Id
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->id = INVALID_ID;
+ text: |
+ While the ${../if/suspend:/params[0]/name} parameter is not
+ associated with a task.
+ - name: Task
+ test-code: |
+ ctx->id = ctx->worker_id;
+ text: |
+ While the ${../if/suspend:/params[0]/name} parameter is
+ associated with a task.
+ test-epilogue: null
+ test-prologue: null
+- name: Suspended
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->suspend = true;
+ text: |
+ While the task specified by the ${../if/suspend:/params[0]/name}
+ parameter is suspended.
+ - name: 'No'
+ test-code: |
+ ctx->suspend = false;
+ text: |
+ While the task specified by the ${../if/suspend:/params[0]/name}
+ parameter is not suspended.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_suspend( ctx->id );
+
+ if ( ctx->suspend ) {
+ ResumeTask( ctx->worker_id );
+ }
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This member contains the identifier of a task.
+ description: null
+ member: |
+ rtems_id worker_id
+- brief: |
+ If this member is true, then the worker is suspended before the
+ ${../if/suspend:/name} call.
+ description: null
+ member: |
+ bool suspend
+- brief: |
+ This member contains the return value of the ${../if/suspend:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/suspend:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id id
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+test-local-includes:
+- tx-support.h
+test-prepare: null
+test-setup:
+ brief: null
+ code: |
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+ description: null
+test-stop: null
+test-support: |
+ static void Worker( rtems_task_argument arg )
+ {
+ while ( true ) {
+ /* Do nothing */
+ }
+ }
+test-target: testsuites/validation/tc-task-storage-size.c
+test-teardown:
+ brief: null
+ code: |
+ DeleteTask( ctx->worker_id );
+ description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ pre-conditions:
+ Id:
+ - Task
+ Suspended:
+ - 'No'
+- enabled-by: true
+ post-conditions:
+ Status: AlrdySus
+ pre-conditions:
+ Id:
+ - Task
+ Suspended:
+ - 'Yes'
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ pre-conditions:
+ Id:
+ - Invalid
+ Suspended: N/A
+type: requirement
diff --git a/spec/rtems/task/req/suspend.yml b/spec/rtems/task/req/suspend.yml
new file mode 100644
index 00000000..f5b342d1
--- /dev/null
+++ b/spec/rtems/task/req/suspend.yml
@@ -0,0 +1,158 @@
+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
+functional-type: action
+links:
+- role: interface-function
+ uid: ../if/suspend
+post-conditions:
+- name: Status
+ states:
+ - name: Ok
+ test-code: |
+ T_rsc_success( ctx->status );
+ text: |
+ The return status of ${../if/suspend:/name} shall be
+ ${../../status/if/successful:/name}.
+ - name: InvId
+ test-code: |
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ text: |
+ The return status of ${../if/suspend:/name} shall be
+ ${../../status/if/invalid-id:/name}.
+ - name: AlrdySus
+ test-code: |
+ T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
+ text: |
+ The return status of ${../if/suspend:/name} shall be
+ ${../../status/if/already-suspended:/name}.
+ test-epilogue: null
+ test-prologue: null
+pre-conditions:
+- name: Id
+ states:
+ - name: Invalid
+ test-code: |
+ ctx->id = INVALID_ID;
+ text: |
+ While the ${../if/suspend:/params[0]/name} parameter is not
+ associated with a task.
+ - name: Task
+ test-code: |
+ ctx->id = ctx->worker_id;
+ text: |
+ While the ${../if/suspend:/params[0]/name} parameter is
+ associated with a task.
+ test-epilogue: null
+ test-prologue: null
+- name: Suspended
+ states:
+ - name: 'Yes'
+ test-code: |
+ ctx->suspend = true;
+ text: |
+ While the task specified by the ${../if/suspend:/params[0]/name}
+ parameter is suspended.
+ - name: 'No'
+ test-code: |
+ ctx->suspend = false;
+ text: |
+ While the task specified by the ${../if/suspend:/params[0]/name}
+ parameter is not suspended.
+ test-epilogue: null
+ test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_suspend( ctx->id );
+
+ if ( ctx->suspend ) {
+ ResumeTask( ctx->worker_id );
+ }
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This member contains the identifier of a task.
+ description: null
+ member: |
+ rtems_id worker_id
+- brief: |
+ If this member is true, then the worker is suspended before the
+ ${../if/suspend:/name} call.
+ description: null
+ member: |
+ bool suspend
+- brief: |
+ This member contains the return value of the ${../if/suspend:/name}
+ call.
+ description: null
+ member: |
+ rtems_status_code status
+- brief: |
+ This member specifies if the ${../if/suspend:/params[0]/name}
+ parameter value.
+ description: null
+ member: |
+ rtems_id id
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+test-local-includes:
+- tx-support.h
+test-prepare: null
+test-setup:
+ brief: null
+ code: |
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+ description: null
+test-stop: null
+test-support: |
+ static void Worker( rtems_task_argument arg )
+ {
+ while ( true ) {
+ /* Do nothing */
+ }
+ }
+test-target: testsuites/validation/tc-task-suspend.c
+test-teardown:
+ brief: null
+ code: |
+ DeleteTask( ctx->worker_id );
+ description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Status: Ok
+ pre-conditions:
+ Id:
+ - Task
+ Suspended:
+ - 'No'
+- enabled-by: true
+ post-conditions:
+ Status: AlrdySus
+ pre-conditions:
+ Id:
+ - Task
+ Suspended:
+ - 'Yes'
+- enabled-by: true
+ post-conditions:
+ Status: InvId
+ pre-conditions:
+ Id:
+ - Invalid
+ Suspended: N/A
+type: requirement