From 51f9a65fce42a4d1cbed71738840d29f3a1257f6 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 10 Sep 2020 15:21:24 +0200 Subject: spec: Specify rtems_task_create_from_config() --- spec/if/acfg/max-thread-local-storage-size.yml | 30 ++ spec/if/acfg/tasks-created-from-config.yml | 27 ++ spec/if/impl/context/fp-size.yml | 11 + spec/if/impl/context/header.yml | 12 + spec/if/impl/cpu/all-tasks-are-fp.yml | 11 + spec/if/impl/cpu/stack-alignment.yml | 11 + spec/if/rtems/tasks/build.yml | 73 --- spec/if/rtems/tasks/config.yml | 62 ++- spec/if/rtems/tasks/create-from-config.yml | 92 ++++ spec/if/rtems/tasks/storage-alignment.yml | 21 + spec/if/rtems/tasks/storage-size.yml | 41 ++ spec/req/rtems/tasks/create-from-config-errors.yml | 500 +++++++++++++++++++++ spec/testsuites/validation-0.yml | 57 ++- 13 files changed, 843 insertions(+), 105 deletions(-) create mode 100644 spec/if/acfg/max-thread-local-storage-size.yml create mode 100644 spec/if/acfg/tasks-created-from-config.yml create mode 100644 spec/if/impl/context/fp-size.yml create mode 100644 spec/if/impl/context/header.yml create mode 100644 spec/if/impl/cpu/all-tasks-are-fp.yml create mode 100644 spec/if/impl/cpu/stack-alignment.yml delete mode 100644 spec/if/rtems/tasks/build.yml create mode 100644 spec/if/rtems/tasks/create-from-config.yml create mode 100644 spec/if/rtems/tasks/storage-alignment.yml create mode 100644 spec/if/rtems/tasks/storage-size.yml create mode 100644 spec/req/rtems/tasks/create-from-config-errors.yml diff --git a/spec/if/acfg/max-thread-local-storage-size.yml b/spec/if/acfg/max-thread-local-storage-size.yml new file mode 100644 index 00000000..1479bddc --- /dev/null +++ b/spec/if/acfg/max-thread-local-storage-size.yml @@ -0,0 +1,30 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +appl-config-option-type: integer +constraints: + max: ${../c/size_max:/name} + min: 0 +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +default-value: 0 +description: | + If the value of this configuration option is greater than zero, then it + defines the maximum thread-local storage size, otherwise the thread-local + storage size is defined by the linker depending on the thread-local storage + objects used by the application in the statically-linked executable. +enabled-by: true +index-entries: [] +interface-type: appl-config-option +links: +- role: appl-config-group-member + uid: group-classic +name: CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE +notes: | + This configuration option can be used to reserve space for the dynamic linking + of modules with thread-local storage objects. + + If the thread-local storage size defined by the thread-local storage + objects used by the application in the statically-linked executable is greater + than a non-zero value of this configuration option, then a fatal error will + occur during system initialization. +text: '' +type: interface diff --git a/spec/if/acfg/tasks-created-from-config.yml b/spec/if/acfg/tasks-created-from-config.yml new file mode 100644 index 00000000..e8863ac8 --- /dev/null +++ b/spec/if/acfg/tasks-created-from-config.yml @@ -0,0 +1,27 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +appl-config-option-type: integer +constraints: + max: ${max-tasks:/name} + min: 0 +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +default-value: 0 +description: | + The value of this configuration option defines the count of Classic API Tasks + which are created by ${../rtems/tasks/create-from-config:/name}. +enabled-by: true +index-entries: [] +interface-type: appl-config-option +links: +- role: appl-config-group-member + uid: group-classic +name: CONFIGURE_TASKS_CREATED_FROM_CONFIG +notes: | + By default, the calculation for the required memory in the RTEMS Workspace for + tasks assumes that all Classic API Tasks are created by + ${../rtems/tasks/create:/name}. This configuration option can be used to + reduce the required memory for the system-provided task storage + areas since tasks created by ${../rtems/tasks/create-from-config:/name} use a + user-provided task storage area. +text: '' +type: interface diff --git a/spec/if/impl/context/fp-size.yml b/spec/if/impl/context/fp-size.yml new file mode 100644 index 00000000..04a897f4 --- /dev/null +++ b/spec/if/impl/context/fp-size.yml @@ -0,0 +1,11 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +interface-type: unspecified-define +links: +- role: interface-placement + uid: header +name: CONTEXT_FP_SIZE +reference: null +type: interface diff --git a/spec/if/impl/context/header.yml b/spec/if/impl/context/header.yml new file mode 100644 index 00000000..aeca1f95 --- /dev/null +++ b/spec/if/impl/context/header.yml @@ -0,0 +1,12 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +brief: This header file defines interfaces of the Stack Handler. +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +interface-type: header-file +links: +- role: interface-placement + uid: /if/domains/implementation +path: rtems/score/context.h +prefix: cpukit/include +type: interface diff --git a/spec/if/impl/cpu/all-tasks-are-fp.yml b/spec/if/impl/cpu/all-tasks-are-fp.yml new file mode 100644 index 00000000..77a9ce1c --- /dev/null +++ b/spec/if/impl/cpu/all-tasks-are-fp.yml @@ -0,0 +1,11 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +interface-type: unspecified-define +links: +- role: interface-placement + uid: header +name: CPU_ALL_TASKS_ARE_FP +reference: null +type: interface diff --git a/spec/if/impl/cpu/stack-alignment.yml b/spec/if/impl/cpu/stack-alignment.yml new file mode 100644 index 00000000..ae6b754c --- /dev/null +++ b/spec/if/impl/cpu/stack-alignment.yml @@ -0,0 +1,11 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +interface-type: unspecified-define +links: +- role: interface-placement + uid: header +name: CPU_STACK_ALIGNMENT +reference: null +type: interface diff --git a/spec/if/rtems/tasks/build.yml b/spec/if/rtems/tasks/build.yml deleted file mode 100644 index 8d06585f..00000000 --- a/spec/if/rtems/tasks/build.yml +++ /dev/null @@ -1,73 +0,0 @@ -SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause -brief: | - Builds a task according to the task configuration. -copyrights: -- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) -definition: - default: - body: null - params: - - const ${config:/name} *${.:/params[0]/name} - - ${../types/id:/name} *${.:/params[1]/name} - return: ${../status/code:/name} - variants: [] -description: null -enabled-by: true -interface-type: function -links: -- role: interface-placement - uid: header -- role: interface-ingroup - uid: group -name: rtems_task_build -notes: null -params: -- description: is the task configuration. - dir: null - name: config -- description: | - is the pointer to an object identifier variable. The identifier of the new - task object will be stored in this variable, in case of a successful - operation. - dir: out - name: id -return: - return: null - return-values: - - description: | - The requested operation was successful. - value: ${../status/successful:/name} - - description: | - The ${.:/params[1]/name} parameter was ${/if/c/null:/name}. - value: ${../status/invalid-address:/name} - - description: | - The task name was invalid. - value: ${../status/invalid-name:/name} - - description: | - The initial task priority was invalid. - value: ${../status/invalid-priority:/name} - - description: | - The multiprocessing support was not configured. - value: ${../status/mp-not-configured:/name} - - description: | - There was no inactive task object available to build a new task. - value: ${../status/too-many:/name} - - description: | - In multiprocessing configurations, there was no inactive global object - available to build a new task. - value: ${../status/too-many:/name} - - description: | - The provided task storage area was too small. The task storage area - includes the task stack, the thread-local storage, and the floating point - context. - value: ${../status/unsatisfied:/name} - - description: | - One of the task create extensions failed to create the new task. - value: ${../status/unsatisfied:/name} - - description: | - In SMP configurations, the non-preemption mode was not supported. - value: ${../status/unsatisfied:/name} - - description: | - In SMP configurations, the interrupt level mode was not supported. - value: ${../status/unsatisfied:/name} -type: interface diff --git a/spec/if/rtems/tasks/config.yml b/spec/if/rtems/tasks/config.yml index a1d4480f..91943ff1 100644 --- a/spec/if/rtems/tasks/config.yml +++ b/spec/if/rtems/tasks/config.yml @@ -1,12 +1,14 @@ SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause brief: | - This structure defines a task configuration used to build a task. + This structure defines a task configuration used to build a task. This + structure defines the configuration of a task created by + ${create-from-config:/name}. copyrights: - Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) definition: - default: brief: | - This member is the name of the task. + This member defines the name of the task. definition: ${../types/name:/name} ${.:name} description: null kind: member @@ -14,7 +16,7 @@ definition: variants: [] - default: brief: | - This member is the initial priority of the task. + This member defines the initial priority of the task. definition: ${priority:/name} ${.:name} description: null kind: member @@ -22,32 +24,58 @@ definition: variants: [] - default: brief: | - This member is task stack area begin address for the task. + This member shall point to the task storage area begin. definition: void *${.:name} - description: null + description: | + The task storage area will contain the task stack, the thread-local + storage, and the floating-point context on architectures with a separate + floating-point context. + + There are no alignment requirements for the task storage area. To avoid + memory waste, use the ${storage-alignment:/name} variable attribute to + enforce the recommended alignment of the task storage area. kind: member - name: stack_area + name: storage_area variants: [] - default: brief: | - This member is task stack area size in bytes for the task. - definition: ${/if/c/size_t:/name} ${.:name} - description: null + This member defines size of the task storage area in bytes. + definition: ${../../c/size_t:/name} ${.:name} + description: | + Use the ${storage-size:/name} macro to determine the recommended task + storage area size. kind: member - name: stack_size + name: storage_size variants: [] - default: brief: | - This member is the function to free the task stack area if the task gets - deleted. + This member defines the maximum thread-local storage size supported by the + task storage area. + definition: ${../../c/size_t:/name} ${.:name} + description: | + If the value is less than the actual thread-local storage size, then the + task creation by ${create-from-config:/name} fails. + + If the is less than the task storage area size, then the task creation by + ${create-from-config:/name} fails. + kind: member + name: maximum_thread_local_storage_size + variants: [] +- default: + brief: | + This member defines the optional handler to free the task storage area. definition: void ( *${.:name} )( void * ) - description: null + description: | + It is called when the task creation aborts due to a failed task create + extension or the task is deleted. It is called from task context under + protection of the object allocator lock. It is allowed to call free() in + this handler. The handler may be ${../../c/null:/name}. kind: member - name: stack_free + name: storage_free variants: [] - default: brief: | - This member is set of initial modes of the task. + This member defines the initial modes of the task. definition: ${../modes/mode:/name} ${.:name} description: null kind: member @@ -55,11 +83,11 @@ definition: variants: [] - default: brief: | - This member is set of attributes of the task. + This member defines the attributes of the task. definition: ${../attr/attribute:/name} ${.:name} description: null kind: member - name: attribute_set + name: attributes variants: [] definition-kind: typedef-only description: null diff --git a/spec/if/rtems/tasks/create-from-config.yml b/spec/if/rtems/tasks/create-from-config.yml new file mode 100644 index 00000000..f592686e --- /dev/null +++ b/spec/if/rtems/tasks/create-from-config.yml @@ -0,0 +1,92 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +brief: | + Creates a task from the specified the task configuration. +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +definition: + default: + body: null + params: + - const ${config:/name} *${.:/params[0]/name} + - ${../types/id:/name} *${.:/params[1]/name} + return: ${../status/code:/name} + variants: [] +description: null +enabled-by: true +interface-type: function +links: +- role: interface-placement + uid: header +- role: interface-ingroup + uid: group +name: rtems_task_create_from_config +notes: | + In contrast to tasks created by ${create:/name}, the tasks created by this + directive use a user-provided task storage area. The task storage area + contains the task stack, the thread-local storage, and the floating-point + context on architectures with a separate floating-point context. + + It is not recommended to mix ${create:/name} and ${.:/name} in an + application. This directive is intended for applications which do not want + to use the RTEMS Workspace and instead statically allocate all operating + system resources. The stack space estimate done by + assumes that all tasks are created by ${create:/name}. The estimate can be + adjusted to take user-provided task storage areas into account through the + ${../../acfg/tasks-created-from-config:/name} application configuration + option or a custom task stack allocator, see + ${../../acfg/task-stack-allocator:/name}. +params: +- description: is the task configuration. + dir: null + name: config +- description: | + is the pointer to an object identifier variable. The identifier of the + created task object will be stored in this variable, in case of a + successful operation. + dir: out + name: id +return: + return: null + return-values: + - description: | + The requested operation was successful. + value: ${../status/successful:/name} + - description: | + The ${.:/params[1]/name} parameter was ${/if/c/null:/name}. + value: ${../status/invalid-address:/name} + - description: | + The task name was invalid. + value: ${../status/invalid-name:/name} + - description: | + The initial task priority was invalid. + value: ${../status/invalid-priority:/name} + - description: | + The thread-local storage size is greater than the maximum thread-local + storage size specified in the task configuration. The thread-local + storage size is determined by the thread-local variables used by the + application and ${../../acfg/max-thread-local-storage-size:/name}. + value: ${../status/invalid-size:/name} + - description: | + The task storage area was too small to provide a task stack of the + configured minimum size, see ${../../acfg/min-task-stack-size:/name}. + The task storage area contains the task stack, the thread-local storage, + and the floating-point context on architectures with a separate + floating-point context. + value: ${../status/invalid-size:/name} + - description: | + There was no inactive task object available to create a task. + value: ${../status/too-many:/name} + - description: | + In multiprocessing configurations, there was no inactive global object + available to create a global task. + value: ${../status/too-many:/name} + - description: | + One of the task create extensions failed during the task creation. + value: ${../status/unsatisfied:/name} + - description: | + In SMP configurations, the non-preemption mode was not supported. + value: ${../status/unsatisfied:/name} + - description: | + In SMP configurations, the interrupt level mode was not supported. + value: ${../status/unsatisfied:/name} +type: interface diff --git a/spec/if/rtems/tasks/storage-alignment.yml b/spec/if/rtems/tasks/storage-alignment.yml new file mode 100644 index 00000000..50b64991 --- /dev/null +++ b/spec/if/rtems/tasks/storage-alignment.yml @@ -0,0 +1,21 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +brief: | + This variable attribute defines the recommended alignment of a task storage + area. +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +definition: + default: | + ${../basedefs/aligned:/name}( ${../../impl/cpu/stack-alignment:/name} ) + variants: [] +description: null +enabled-by: true +interface-type: define +links: +- role: interface-placement + uid: header +- role: interface-ingroup + uid: group +name: RTEMS_TASK_STORAGE_ALIGNMENT +notes: null +type: interface diff --git a/spec/if/rtems/tasks/storage-size.yml b/spec/if/rtems/tasks/storage-size.yml new file mode 100644 index 00000000..3ae85838 --- /dev/null +++ b/spec/if/rtems/tasks/storage-size.yml @@ -0,0 +1,41 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +brief: | + Returns the recommended task storage area size for the specified size and task + attributes. +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +definition: + default: | + ( ( ${.:/params[0]/name} ) + + ( ( ( ${.:/params[1]/name} ) & ${../attr/floating-point:/name} ) != 0 ? + ${../../impl/context/fp-size:/name} : 0 ) ) + variants: + - definition: | + ( ( ${.:/params[0]/name} ) + ${../../impl/context/fp-size:/name} ) + enabled-by: + - ${../../impl/cpu/all-tasks-are-fp:/name} == ${../basedefs/true:/name} +description: null +enabled-by: true +interface-type: macro +links: +- role: interface-placement + uid: header +- role: interface-ingroup + uid: group +name: RTEMS_TASK_STORAGE_SIZE +notes: null +params: +- description: | + is the size dedicated to the task stack and thread-local storage in bytes. + dir: null + name: _size +- description: | + is the attribute set of the task using the storage area. + dir: null + name: _attributes +return: + return: | + The recommended task storage area size calculated from the input parameters + is returned. + return-values: [] +type: interface diff --git a/spec/req/rtems/tasks/create-from-config-errors.yml b/spec/req/rtems/tasks/create-from-config-errors.yml new file mode 100644 index 00000000..8802e422 --- /dev/null +++ b/spec/req/rtems/tasks/create-from-config-errors.yml @@ -0,0 +1,500 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +enabled-by: true +functional-type: action +links: +- role: interface-function + uid: /if/rtems/tasks/create-from-config +post-conditions: +- name: Status + states: + - name: Ok + test-code: | + T_rsc_success( ctx->status ); + T_eq_ptr( ctx->id, &ctx->id_value ); + T_ne_u32( ctx->id_value, 0xffffffff ); + + sc = rtems_task_delete( ctx->id_value ); + T_rsc_success( sc ); + text: | + The status shall be RTEMS_SUCCESSFUL. The value of the object identifier + referenced by the id parameter shall identify the created task. + - name: InvAddress + test-code: | + T_rsc( ctx->status, RTEMS_INVALID_ADDRESS ); + T_null( ctx->id ); + T_eq_u32( ctx->id_value, 0xffffffff ); + text: | + The status shall be RTEMS_INVALID_ADDRESS. + - name: InvName + test-code: | + T_rsc( ctx->status, RTEMS_INVALID_NAME ); + T_eq_u32( ctx->id_value, 0xffffffff ); + text: | + The status shall be RTEMS_INVALID_NAME. If the id parameter is not NULL, + then the value of the object identifier referenced by the id parameter + shall be unchanged. + - name: InvPrio + test-code: | + T_rsc( ctx->status, RTEMS_INVALID_PRIORITY ); + T_eq_u32( ctx->id_value, 0xffffffff ); + text: | + The status shall be RTEMS_INVALID_PRIORITY. If the id parameter is not + NULL, then the value of the object identifier referenced by the id + parameter shall be unchanged. + - name: InvSize + test-code: | + T_rsc( ctx->status, RTEMS_INVALID_SIZE ); + T_eq_u32( ctx->id_value, 0xffffffff ); + text: | + The status shall be RTEMS_INVALID_SIZE. If the id parameter is not NULL, + then the value of the object identifier referenced by the id parameter + shall be unchanged. + - name: TooMany + test-code: | + T_rsc( ctx->status, RTEMS_TOO_MANY ); + T_eq_u32( ctx->id_value, 0xffffffff ); + text: | + The status shall be RTEMS_TOO_MANY. If the id parameter is not NULL, + then the value of the object identifier referenced by the id parameter + shall be unchanged. + - name: Unsatisfied + test-code: | + T_rsc( ctx->status, RTEMS_UNSATISFIED ); + T_eq_u32( ctx->id_value, 0xffffffff ); + text: | + The status shall be RTEMS_UNSATISFIED. If the id parameter is not NULL, + then the value of the object identifier referenced by the id parameter + shall be unchanged. + test-epilogue: null + test-prologue: | + rtems_status_code sc; +pre-conditions: +- name: Id + states: + - name: Id + test-code: | + ctx->id = &ctx->id_value; + text: | + The id parameter shall reference an object identifier value. + - name: 'Null' + test-code: | + ctx->id = NULL; + text: | + The id parameter shall be NULL. + test-epilogue: null + test-prologue: null +- name: Name + states: + - name: Valid + test-code: | + ctx->config.name = rtems_build_name( 'N', 'A', 'M', 'E' ); + text: | + The name of the task configuration shall be valid. + - name: Inv + test-code: | + ctx->config.name = 0; + text: | + The name of the task configuration shall be invalid. + test-epilogue: null + test-prologue: null +- name: Prio + states: + - name: Valid + test-code: | + ctx->config.initial_priority = 254; + text: | + The initial priority of the task configuration shall be valid. + - name: Zero + test-code: | + ctx->config.initial_priority = 0; + text: | + The initial priority of the task configuration shall be zero. + - name: Inv + test-code: | + ctx->config.initial_priority = 0xffffffff; + text: | + The initial priority of the task configuration shall be invalid. + test-epilogue: null + test-prologue: null +- name: Tasks + states: + - name: Avail + test-code: | + /* Nothing to do */ + text: | + There shall be at least one inactive task object available. + - name: None + test-code: | + create_extension_status = ctx->create_extension_status; + ctx->create_extension_status = true; + + while ( true ) { + rtems_status_code sc; + rtems_id id; + + sc = rtems_task_create_from_config( &valid_task_config, &id ); + + if ( sc == RTEMS_SUCCESSFUL ) { + Objects_Control *obj; + const Objects_Information *info; + + info = _Objects_Get_information_id( id ); + T_quiet_assert_not_null( info ); + obj = _Objects_Get_no_protection( id, info ); + T_quiet_assert_not_null( obj ); + _Chain_Append_unprotected( &ctx->tasks, &obj->Node ); + } else { + T_quiet_rsc( sc, RTEMS_TOO_MANY ); + break; + } + } + + ctx->create_extension_status = create_extension_status; + text: | + There shall be no inactive task object available. + test-epilogue: null + test-prologue: | + bool create_extension_status; +- name: TLS + states: + - name: Enough + test-code: | + ctx->config.maximum_thread_local_storage_size = MAX_TLS_SIZE; + text: | + The maximum thread-local storage size of the task configuration shall be + greater than or equal to the thread-local storage size. + - name: Small + test-code: | + ctx->config.maximum_thread_local_storage_size = 0; + text: | + The maximum thread-local storage size of the task configuration shall be + less than the thread-local storage size. + test-epilogue: null + test-prologue: null +- name: Stack + states: + - name: Enough + test-code: | + ctx->stack_size = RTEMS_MINIMUM_STACK_SIZE; + text: | + The task stack size of the task configuration shall be greater than or + equal to the configured minimum size. + - name: Small + test-code: | + ctx->stack_size = 0; + text: | + The task stack size of the task configuration shall be less than to the + configured minimum size. + test-epilogue: null + test-prologue: null +- name: Ext + states: + - name: Ok + test-code: | + ctx->create_extension_status = true; + text: | + None of the task create extensions shall fail. + - name: Err + test-code: | + ctx->create_extension_status = false; + text: | + At least one of the task create extensions shall fail. + test-epilogue: null + test-prologue: null +- name: Preempt + states: + - name: 'Yes' + test-code: | + ctx->config.initial_modes &= ~RTEMS_PREEMPT_MASK; + ctx->config.initial_modes |= RTEMS_PREEMPT; + text: | + The preemptible mode in the initial modes of the task configuration shall + be set to preemptible. + - name: 'No' + test-code: | + ctx->config.initial_modes &= ~RTEMS_PREEMPT_MASK; + ctx->config.initial_modes |= RTEMS_NO_PREEMPT; + text: | + The preemptible mode in the initial modes of the task configuration shall + be set to non-preemptible. + test-epilogue: null + test-prologue: null +rationale: null +references: [] +requirement-type: functional +skip-reasons: {} +test-action: | + ctx->config.storage_size = RTEMS_TASK_STORAGE_SIZE( + ctx->config.maximum_thread_local_storage_size + ctx->stack_size, + ctx->config.attributes + ); + ctx->status = rtems_task_create_from_config( &ctx->config, ctx->id ); +test-brief: null +test-cleanup: | + Chain_Node *node; + + while ( ( node = _Chain_Get_unprotected( &ctx->tasks ) ) ) { + Objects_Control *obj; + rtems_status_code sc; + + obj = (Objects_Control *) node; + sc = rtems_task_delete( obj->id ); + T_quiet_rsc_success( sc ); + } +test-context: +- brief: null + description: null + member: rtems_status_code status +- brief: null + description: null + member: rtems_task_config config +- brief: null + description: null + member: rtems_id *id +- brief: null + description: null + member: rtems_id id_value +- brief: null + description: null + member: bool create_extension_status +- brief: null + description: null + member: size_t stack_size +- brief: null + description: null + member: rtems_id extension_id +- brief: null + description: null + member: Chain_Control tasks +test-context-support: null +test-description: null +test-header: null +test-includes: +- rtems.h +- rtems/score/chainimpl.h +- rtems/score/objectimpl.h +- string.h +test-local-includes: [] +test-prepare: | + ctx->id_value = 0xffffffff; + memset( &ctx->config, 0, sizeof( ctx->config ) ); +test-setup: + brief: null + code: | + rtems_status_code sc; + int var; + + var = tls_variable; + RTEMS_OBFUSCATE_VARIABLE( var ); + tls_variable = var; + + sc = rtems_extension_create( + rtems_build_name( 'T', 'C', 'F', 'C' ), + &extensions, + &ctx->extension_id + ); + T_rsc_success( sc ); + + _Chain_Initialize_empty( &ctx->tasks ); + description: null +test-stop: null +test-support: | + static _Thread_local int tls_variable; + + #define MAX_TLS_SIZE 128 + + RTEMS_TASK_STORAGE_ALIGNMENT static char task_storage[ + RTEMS_TASK_STORAGE_SIZE( + MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_FLOATING_POINT + ) + ]; + + static const rtems_task_config valid_task_config = { + .name = rtems_build_name( 'T', 'A', 'S', 'K' ), + .initial_priority = 1, + .storage_area = task_storage, + .storage_size = sizeof( task_storage ), + .maximum_thread_local_storage_size = MAX_TLS_SIZE, + .initial_modes = RTEMS_DEFAULT_MODES, + .attributes = RTEMS_DEFAULT_MODES + }; + + static bool ThreadCreate( rtems_tcb *executing, rtems_tcb *created ) + { + (void) executing; + (void) created; + + return + ReqRtemsTasksCreateFromConfigErrors_Instance.create_extension_status; + } + + static const rtems_extensions_table extensions = { + .thread_create = ThreadCreate + }; +test-target: testsuites/validation/tc-tasks-create-from-config-errors.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 + pre-conditions: + Id: + - Id + Name: + - Valid + Prio: + - Valid + Tasks: + - Avail + TLS: + - Enough + Stack: + - Enough + Ext: + - Ok + Preempt: all +- enabled-by: true + post-conditions: + Status: InvAddress + pre-conditions: + Id: + - 'Null' + Name: all + Prio: all + Tasks: all + TLS: all + Stack: all + Ext: all + Preempt: all +- enabled-by: true + post-conditions: + Status: InvName + pre-conditions: + Id: + - Id + Name: + - Inv + Prio: all + Tasks: all + TLS: all + Stack: all + Ext: all + Preempt: all +- enabled-by: true + post-conditions: + Status: InvPrio + pre-conditions: + Id: + - Id + Name: + - Valid + Prio: + - Zero + - Inv + Tasks: all + TLS: all + Stack: all + Ext: all + Preempt: all +- enabled-by: true + post-conditions: + Status: TooMany + pre-conditions: + Id: + - Id + Name: + - Valid + Prio: + - Valid + Tasks: + - None + TLS: all + Stack: all + Ext: all + Preempt: all +- enabled-by: true + post-conditions: + Status: InvSize + pre-conditions: + Id: + - Id + Name: + - Valid + Prio: + - Valid + Tasks: + - Avail + TLS: + - Small + Stack: all + Ext: all + Preempt: all +- enabled-by: true + post-conditions: + Status: InvSize + pre-conditions: + Id: + - Id + Name: + - Valid + Prio: + - Valid + Tasks: + - Avail + TLS: + - Enough + Stack: + - Small + Ext: all + Preempt: all +- enabled-by: true + post-conditions: + Status: Unsatisfied + pre-conditions: + Id: + - Id + Name: + - Valid + Prio: + - Valid + Tasks: + - Avail + TLS: + - Enough + Stack: + - Enough + Ext: + - Err + Preempt: all +- enabled-by: RTEMS_SMP + post-conditions: + Status: Unsatisfied + pre-conditions: + Id: + - Id + Name: + - Valid + Prio: + - Valid + Tasks: + - Avail + TLS: + - Enough + Stack: + - Enough + Ext: + - Ok + Preempt: + - 'No' +type: requirement diff --git a/spec/testsuites/validation-0.yml b/spec/testsuites/validation-0.yml index 3822bf9d..0a20e76d 100644 --- a/spec/testsuites/validation-0.yml +++ b/spec/testsuites/validation-0.yml @@ -4,9 +4,12 @@ copyrights: enabled-by: true links: [] test-brief: | - This test suite contains a collection of unrelated test cases. + This general purpose validation test suite provides enough resources to run + basic tests for all specified managers and functions. test-code: | - static char runner_task_stack[ RTEMS_MINIMUM_STACK_SIZE ]; + #include + + const char rtems_test_name[] = "Validation0"; static char buffer[ 512 ]; @@ -24,7 +27,7 @@ test-code: | }; static const T_config test_config = { - .name = "Validation0", + .name = rtems_test_name, .buf = buffer, .buf_size = sizeof( buffer ), .putchar = rtems_put_char, @@ -34,36 +37,54 @@ test-code: | .actions = actions }; - static void Init( rtems_task_argument arg ) + static void runner_task( rtems_task_argument arg ) { int exit_code; (void) arg; + rtems_test_begin( rtems_test_name, TEST_STATE ); T_register(); exit_code = T_main( &test_config ); + + if ( exit_code == 0 ) { + rtems_test_end( rtems_test_name ); + } + rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, (uint32_t) exit_code ); } + #define MAX_TLS_SIZE 64 + #define ATTRIBUTES RTEMS_FLOATING_POINT + + RTEMS_TASK_STORAGE_ALIGNMENT static char runner_task_storage[ + RTEMS_TASK_STORAGE_SIZE( + MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, + ATTRIBUTES + ) + ]; + + static const rtems_task_config runner_task_config = { + .name = rtems_build_name( 'R', 'U', 'N', ' ' ), + .initial_priority = 1, + .storage_area = runner_task_storage, + .storage_size = sizeof( runner_task_storage ), + .maximum_thread_local_storage_size = MAX_TLS_SIZE, + .initial_modes = RTEMS_DEFAULT_MODES, + .attributes = ATTRIBUTES + }; + static void init_runner_task(void) { - static const rtems_task_config task_config = { - .name = rtems_build_name('R', 'U', 'N', ' '), - .initial_priority = 1, - .stack_area = runner_task_stack, - .stack_size = sizeof( runner_task_stack ), - .initial_modes = RTEMS_DEFAULT_MODES, - .attribute_set = RTEMS_DEFAULT_ATTRIBUTES - }; rtems_id id; rtems_status_code sc; - sc = rtems_task_build( &task_config, &id ); + sc = rtems_task_create_from_config( &runner_task_config, &id ); if ( sc != RTEMS_SUCCESSFUL ) { rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, 1 ); } - sc = rtems_task_start( id, Init, 0 ); + sc = rtems_task_start( id, runner_task, 0 ); if ( sc != RTEMS_SUCCESSFUL ) { rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, 1 ); } @@ -107,6 +128,8 @@ test-code: | #define CONFIGURE_IDLE_TASK_BODY _CPU_Thread_Idle_body + #if defined(RTEMS_SMP) + #define CONFIGURE_SCHEDULER_EDF_SMP #include @@ -128,10 +151,14 @@ test-code: | RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \ RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL) + #endif /* RTEMS_SMP */ + #define CONFIGURE_INIT #include -test-description: null +test-description: | + In SMP configurations, up to three scheduler instances using the SMP EDF + scheduler are provided using up to four processors. test-includes: - rtems.h - rtems/bspIo.h -- cgit v1.2.3