diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-05-10 07:51:52 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-05-17 08:06:17 +0200 |
commit | a55de0c4d32bfc161802bb4f16c6abd48c993bbe (patch) | |
tree | b234ff8087f9264b74601ce4d7f30647e6ae3910 /spec/rtems/task/req | |
parent | spec: Add spec for rtems_timer_server_fire_when() (diff) | |
download | rtems-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.yml | 236 | ||||
-rw-r--r-- | spec/rtems/task/req/get-priority.yml | 338 | ||||
-rw-r--r-- | spec/rtems/task/req/get-scheduler.yml | 161 | ||||
-rw-r--r-- | spec/rtems/task/req/is-suspended.yml | 158 | ||||
-rw-r--r-- | spec/rtems/task/req/iterate-done.yml | 16 | ||||
-rw-r--r-- | spec/rtems/task/req/iterate-start.yml | 15 | ||||
-rw-r--r-- | spec/rtems/task/req/iterate-stop.yml | 18 | ||||
-rw-r--r-- | spec/rtems/task/req/iterate-visit.yml | 20 | ||||
-rw-r--r-- | spec/rtems/task/req/restart.yml | 361 | ||||
-rw-r--r-- | spec/rtems/task/req/resume.yml | 158 | ||||
-rw-r--r-- | spec/rtems/task/req/self.yml | 16 | ||||
-rw-r--r-- | spec/rtems/task/req/set-affinity.yml | 277 | ||||
-rw-r--r-- | spec/rtems/task/req/set-priority.yml | 278 | ||||
-rw-r--r-- | spec/rtems/task/req/set-scheduler.yml | 983 | ||||
-rw-r--r-- | spec/rtems/task/req/start.yml | 422 | ||||
-rw-r--r-- | spec/rtems/task/req/storage-alignment.yml | 16 | ||||
-rw-r--r-- | spec/rtems/task/req/storage-size.yml | 158 | ||||
-rw-r--r-- | spec/rtems/task/req/suspend.yml | 158 |
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 |