[rtems-central commit] spec: Specify rtems_task_create_from_config()

Sebastian Huber sebh at rtems.org
Fri Sep 11 15:25:42 UTC 2020


Module:    rtems-central
Branch:    master
Commit:    51f9a65fce42a4d1cbed71738840d29f3a1257f6
Changeset: http://git.rtems.org/rtems-central/commit/?id=51f9a65fce42a4d1cbed71738840d29f3a1257f6

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Sep 10 15:21:24 2020 +0200

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(-)

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 0000000..1479bdd
--- /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 0000000..e8863ac
--- /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 0000000..04a897f
--- /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 0000000..aeca1f9
--- /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 0000000..77a9ce1
--- /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 0000000..ae6b754
--- /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 8d06585..0000000
--- 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 a1d4480..91943ff 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 0000000..f592686
--- /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 <rtems/confdefs.h>
+  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 0000000..50b6499
--- /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 0000000..3ae8583
--- /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 0000000..8802e42
--- /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 3822bf9..0a20e76 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 <rtems/test-info.h>
+
+  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 <rtems/scheduler.h>
@@ -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 <rtems/confdefs.h>
-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



More information about the vc mailing list