[rtems-central commit] spec: Specify barrier manager

Sebastian Huber sebh at rtems.org
Mon Feb 8 07:53:59 UTC 2021


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Feb  4 06:39:49 2021 +0100

spec: Specify barrier manager

---

 spec/rtems/barrier/req/create.yml  | 376 ++++++++++++++++++++++++++++++++
 spec/rtems/barrier/req/delete.yml  | 239 +++++++++++++++++++++
 spec/rtems/barrier/req/release.yml | 303 ++++++++++++++++++++++++++
 spec/rtems/barrier/req/wait.yml    | 425 +++++++++++++++++++++++++++++++++++++
 4 files changed, 1343 insertions(+)

diff --git a/spec/rtems/barrier/req/create.yml b/spec/rtems/barrier/req/create.yml
new file mode 100644
index 0000000..7327304
--- /dev/null
+++ b/spec/rtems/barrier/req/create.yml
@@ -0,0 +1,376 @@
+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/create
+post-conditions:
+- name: Status
+  states:
+  - name: Ok
+    test-code: |
+      T_rsc_success( ctx->status );
+    text: |
+      The return status of ${../if/create:/name} shall be
+      ${../../status/if/success:/name}.
+  - name: InvName
+    test-code: |
+      T_rsc( ctx->status, RTEMS_INVALID_NAME );
+    text: |
+      The return status of ${../if/create:/name} shall be
+      ${../../status/if/invalid-name:/name}.
+  - name: InvAddr
+    test-code: |
+      T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+    text: |
+      The return status of ${../if/create:/name} shall be
+      ${../../status/if/invalid-address:/name}.
+  - name: InvNum
+    test-code: |
+      T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
+    text: |
+      The return status of ${../if/create:/name} shall be
+      ${../../status/if/invalid-number:/name}.
+  - name: TooMany
+    test-code: |
+      T_rsc( ctx->status, RTEMS_TOO_MANY );
+    text: |
+      The return status of ${../if/create:/name} shall be
+      ${../../status/if/too-many:/name}.
+  test-epilogue: null
+  test-prologue: null
+- name: Name
+  states:
+  - name: Valid
+    test-code: |
+      id = 0;
+      sc = rtems_barrier_ident( NAME, &id );
+      T_rsc_success( sc );
+      T_eq_u32( id, ctx->id_value );
+    text: |
+      The unique object name shall identify the barrier.
+  - name: Invalid
+    test-code: |
+      sc = rtems_barrier_ident( NAME, &id );
+      T_rsc( sc, RTEMS_INVALID_NAME );
+    text: |
+      The unique object name shall not identify the barrier.
+  test-epilogue: null
+  test-prologue: |
+    rtems_status_code sc;
+    rtems_id          id;
+- name: Class
+  states:
+  - name: NoObj
+    test-code: |
+      /* Not applicable */
+    text: |
+      The barrier class is not applicable since there was no barrier created.
+  - name: Manual
+    test-code: |
+      sc = rtems_barrier_wait( ctx->id_value, RTEMS_NO_TIMEOUT );
+      T_rsc_success( sc );
+
+      ++ctx->release_expected;
+      T_eq_u32( ctx->release_done, ctx->release_expected );
+    text: |
+      The class of the barrier shall be manual release.
+  - name: Auto
+    test-code: |
+      sc = rtems_barrier_wait( ctx->id_value, RTEMS_NO_TIMEOUT );
+      T_rsc_success( sc );
+
+      T_eq_u32( ctx->release_done, ctx->release_expected );
+    text: |
+      The class of the barrier shall be automatic release.
+  test-epilogue: null
+  test-prologue: |
+    rtems_status_code sc;
+- name: IdValue
+  states:
+  - name: Assigned
+    test-code: |
+      T_eq_ptr( ctx->id, &ctx->id_value );
+      T_ne_u32( ctx->id_value, INVALID_ID );
+    text: |
+      The value of the object identifier variable shall be equal to the object
+      identifier of the barrier created by the ${../if/create:/name} call.
+  - name: Unchanged
+    test-code: |
+      T_eq_u32( ctx->id_value, INVALID_ID );
+    text: |
+      The value of the object identifier variable shall be unchanged by the
+      ${../if/create:/name} call.
+  test-epilogue: null
+  test-prologue: null
+pre-conditions:
+- name: Name
+  states:
+  - name: Valid
+    test-code: |
+      ctx->name = NAME;
+    text: |
+      The ${../if/create:/params[0]/name} parameter shall be valid.
+  - name: Invalid
+    test-code: |
+      ctx->name = 0;
+    text: |
+      The ${../if/create:/params[0]/name} parameter shall be invalid.
+  test-epilogue: null
+  test-prologue: null
+- name: Class
+  states:
+  - name: Default
+    test-code: |
+      /* Nothing to do */
+    text: |
+      The ${../if/create:/params[1]/name} parameter shall specify the default
+      class.
+  - name: Manual
+    test-code: |
+      ctx->attribute_set |= RTEMS_BARRIER_MANUAL_RELEASE;
+    text: |
+      The ${../if/create:/params[1]/name} parameter shall specify the manual
+      release class.
+  - name: Auto
+    test-code: |
+      ctx->attribute_set |= RTEMS_BARRIER_AUTOMATIC_RELEASE;
+    text: |
+      The ${../if/create:/params[1]/name} parameter shall specify the
+      automatic release class.
+  test-epilogue: null
+  test-prologue: null
+- name: MaxWait
+  states:
+  - name: Zero
+    test-code: |
+      ctx->maximum_waiters = 0;
+    text: |
+      The ${../if/create:/params[2]/name} parameter shall be zero.
+  - name: Positive
+    test-code: |
+      ctx->maximum_waiters = 1;
+    text: |
+      The ${../if/create:/params[2]/name} parameter shall be positive.
+  test-epilogue: null
+  test-prologue: null
+- name: Id
+  states:
+  - name: Valid
+    test-code: |
+      ctx->id = &ctx->id_value;
+    text: |
+      The ${../if/create:/params[3]/name} parameter shall reference an object
+      identifier value.
+  - name: 'Null'
+    test-code: |
+      ctx->id = NULL;
+    text: |
+      The ${../if/create:/params[3]/name} parameter shall be
+      ${/c/if/null:/name}.
+  test-epilogue: null
+  test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+  ctx->status = rtems_barrier_create(
+    ctx->name,
+    ctx->attribute_set,
+    ctx->maximum_waiters,
+    ctx->id
+  );
+test-brief: null
+test-cleanup: |
+  if ( ctx->id_value != INVALID_ID ) {
+    rtems_status_code sc;
+
+    sc = rtems_barrier_delete( ctx->id_value );
+    T_rsc_success( sc );
+
+    ctx->id_value = INVALID_ID;
+  }
+test-context:
+- brief: null
+  description: null
+  member: |
+    rtems_id worker_id
+- brief: null
+  description: null
+  member: |
+    rtems_id id_value
+- brief: null
+  description: null
+  member: |
+    uint32_t release_done
+- brief: null
+  description: null
+  member: |
+    uint32_t release_expected
+- brief: null
+  description: null
+  member: |
+    rtems_name name
+- brief: null
+  description: null
+  member: |
+    rtems_attribute attribute_set
+- brief: null
+  description: null
+  member: |
+    uint32_t maximum_waiters
+- brief: null
+  description: null
+  member: |
+    rtems_id *id
+- brief: null
+  description: null
+  member: |
+    rtems_status_code status
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+- string.h
+test-local-includes: []
+test-prepare: null
+test-setup:
+  brief: null
+  code: |
+    rtems_status_code sc;
+
+    memset( ctx, 0, sizeof( *ctx ) );
+    ctx->id_value = INVALID_ID;
+
+    sc = rtems_task_create(
+      rtems_build_name( 'W', 'O', 'R', 'K' ),
+      PRIO_LOW,
+      RTEMS_MINIMUM_STACK_SIZE,
+      RTEMS_DEFAULT_MODES,
+      RTEMS_DEFAULT_ATTRIBUTES,
+      &ctx->worker_id
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_task_start( ctx->worker_id, Worker, (rtems_task_argument) ctx );
+    T_assert_rsc_success( sc );
+  description: null
+test-stop: null
+test-support: |
+  #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+  #define INVALID_ID 0xffffffff
+
+  typedef RtemsBarrierReqCreate_Context Context;
+
+  typedef enum {
+    PRIO_NORMAL = 1,
+    PRIO_LOW
+  } Priorities;
+
+  static void Worker( rtems_task_argument arg )
+  {
+    Context *ctx;
+
+    ctx = (Context *) arg;
+
+    while ( true ) {
+      rtems_status_code sc;
+      uint32_t          released;
+
+      ++ctx->release_done;
+
+      released = 0;
+      sc = rtems_barrier_release( ctx->id_value, &released );
+      T_rsc_success( sc );
+      T_eq_u32( released, 1 );
+    }
+  }
+test-target: testsuites/validation/tc-barrier-create.c
+test-teardown:
+  brief: null
+  code: |
+    rtems_status_code sc;
+
+    if ( ctx->worker_id != 0 ) {
+      sc = rtems_task_delete( ctx->worker_id );
+      T_rsc_success( sc );
+    }
+  description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+  post-conditions:
+    Status: InvName
+    Name: Invalid
+    Class: NoObj
+    IdValue: Unchanged
+  pre-conditions:
+    Name:
+    - Invalid
+    Id: all
+    Class: all
+    MaxWait: all
+- enabled-by: true
+  post-conditions:
+    Status: InvAddr
+    Name: Invalid
+    Class: NoObj
+    IdValue: Unchanged
+  pre-conditions:
+    Name:
+    - Valid
+    Id:
+    - 'Null'
+    Class: all
+    MaxWait: all
+- enabled-by: true
+  post-conditions:
+    Status: Ok
+    Name: Valid
+    Class: Manual
+    IdValue: Assigned
+  pre-conditions:
+    Name:
+    - Valid
+    Id:
+    - Valid
+    Class:
+    - Default
+    - Manual
+    MaxWait: all
+- enabled-by: true
+  post-conditions:
+    Status: InvNum
+    Name: Invalid
+    Class: NoObj
+    IdValue: Unchanged
+  pre-conditions:
+    Name:
+    - Valid
+    Id:
+    - Valid
+    Class:
+    - Auto
+    MaxWait:
+    - Zero
+- enabled-by: true
+  post-conditions:
+    Status: Ok
+    Name: Valid
+    Class: Auto
+    IdValue: Assigned
+  pre-conditions:
+    Name:
+    - Valid
+    Id:
+    - Valid
+    Class:
+    - Auto
+    MaxWait:
+    - Positive
+type: requirement
diff --git a/spec/rtems/barrier/req/delete.yml b/spec/rtems/barrier/req/delete.yml
new file mode 100644
index 0000000..dd24f9c
--- /dev/null
+++ b/spec/rtems/barrier/req/delete.yml
@@ -0,0 +1,239 @@
+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/delete
+post-conditions:
+- name: Status
+  states:
+  - name: Ok
+    test-code: |
+      ctx->barrier_id = 0;
+      T_rsc_success( ctx->status );
+    text: |
+      The return status of ${../if/delete:/name} shall be
+      ${../../status/if/success:/name}.
+  - name: InvId
+    test-code: |
+      T_rsc( ctx->status, RTEMS_INVALID_ID );
+    text: |
+      The return status of ${../if/create:/name} shall be
+      ${../../status/if/invalid-id:/name}.
+  test-epilogue: null
+  test-prologue: null
+- name: Id
+  states:
+  - name: Valid
+    test-code: |
+      id = 0;
+      sc = rtems_barrier_ident( NAME, &id );
+      T_rsc_success( sc );
+      T_eq_u32( id, ctx->barrier_id );
+    text: |
+      The unique object name shall identify the barrier.
+  - name: Invalid
+    test-code: |
+      sc = rtems_barrier_ident( NAME, &id );
+      T_rsc( sc, RTEMS_INVALID_NAME );
+    text: |
+      The unique object name shall not identify the barrier.
+  test-epilogue: null
+  test-prologue: |
+    rtems_status_code sc;
+    rtems_id          id;
+- name: Flush
+  states:
+  - name: 'Yes'
+    test-code: |
+      ++ctx->wait_expected;
+      T_eq_u32( ctx->wait_done, ctx->wait_expected );
+    text: |
+      Tasks waiting at the barrier shall be unblocked.
+  - name: 'No'
+    test-code: |
+      T_eq_u32( ctx->wait_done, ctx->wait_expected );
+    text: |
+      Tasks waiting at the barrier shall remain blocked.
+  test-epilogue: null
+  test-prologue: null
+pre-conditions:
+- name: Id
+  states:
+  - name: Valid
+    test-code: |
+      ctx->id = ctx->barrier_id;
+    text: |
+      The ${../if/create:/params[0]/name} parameter shall be associated with
+      the barrier.
+  - name: Invalid
+    test-code: |
+      ctx->id = 0;
+    text: |
+      The ${../if/create:/params[0]/name} parameter shall be invalid.
+  test-epilogue: null
+  test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+  ctx->status = rtems_barrier_delete( ctx->id );
+test-brief: null
+test-cleanup: |
+  if ( ctx->barrier_id != 0 ) {
+    rtems_status_code sc;
+
+    sc = rtems_barrier_delete( ctx->barrier_id );
+    T_rsc_success( sc );
+  }
+test-context:
+- brief: null
+  description: null
+  member: |
+    rtems_id worker_id
+- brief: null
+  description: null
+  member: |
+    rtems_id barrier_id
+- brief: null
+  description: null
+  member: |
+    uint32_t wait_done
+- brief: null
+  description: null
+  member: |
+    uint32_t wait_expected
+- brief: null
+  description: null
+  member: |
+    rtems_id id
+- brief: null
+  description: null
+  member: |
+    rtems_status_code status
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+- string.h
+test-local-includes: []
+test-prepare: |
+  rtems_status_code   sc;
+  rtems_task_priority prio;
+
+  prio = 0;
+  sc = rtems_task_set_priority( ctx->worker_id, PRIO_HIGH, &prio );
+  T_rsc_success( sc );
+  T_true( prio == PRIO_LOW || prio == PRIO_HIGH );
+test-setup:
+  brief: null
+  code: |
+    rtems_status_code   sc;
+    rtems_task_priority prio;
+
+    memset( ctx, 0, sizeof( *ctx ) );
+
+    prio = 0;
+    sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio );
+    T_rsc_success( sc );
+    T_eq_u32( prio, PRIO_HIGH );
+
+    sc = rtems_task_create(
+      rtems_build_name( 'W', 'O', 'R', 'K' ),
+      PRIO_LOW,
+      RTEMS_MINIMUM_STACK_SIZE,
+      RTEMS_DEFAULT_MODES,
+      RTEMS_DEFAULT_ATTRIBUTES,
+      &ctx->worker_id
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_task_start( ctx->worker_id, Worker, (rtems_task_argument) ctx );
+    T_assert_rsc_success( sc );
+  description: null
+test-stop: null
+test-support: |
+  #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+  typedef RtemsBarrierReqDelete_Context Context;
+
+  typedef enum {
+    PRIO_HIGH = 1,
+    PRIO_NORMAL,
+    PRIO_LOW
+  } Priorities;
+
+  static void Worker( rtems_task_argument arg )
+  {
+    Context *ctx;
+
+    ctx = (Context *) arg;
+
+    while ( true ) {
+      rtems_status_code   sc;
+      rtems_task_priority prio;
+
+      T_eq_u32( ctx->barrier_id, 0 );
+
+      sc = rtems_barrier_create(
+        NAME,
+        RTEMS_DEFAULT_ATTRIBUTES,
+        0,
+        &ctx->barrier_id
+      );
+      T_rsc_success( sc );
+
+      sc = rtems_barrier_wait(
+        ctx->barrier_id,
+        RTEMS_NO_TIMEOUT
+      );
+      T_rsc( sc, RTEMS_OBJECT_WAS_DELETED );
+
+      ++ctx->wait_done;
+
+      prio = 0;
+      sc = rtems_task_set_priority( RTEMS_SELF, PRIO_LOW, &prio );
+      T_rsc_success( sc );
+      T_eq_u32( prio, PRIO_HIGH );
+    }
+  }
+test-target: testsuites/validation/tc-barrier-delete.c
+test-teardown:
+  brief: null
+  code: |
+    rtems_status_code   sc;
+    rtems_task_priority prio;
+
+    prio = 0;
+    sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio );
+    T_rsc_success( sc );
+    T_eq_u32( prio, PRIO_NORMAL );
+
+    if ( ctx->worker_id != 0 ) {
+      sc = rtems_task_delete( ctx->worker_id );
+      T_rsc_success( sc );
+    }
+  description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+  post-conditions:
+    Status: Ok
+    Id: Invalid
+    Flush: 'Yes'
+  pre-conditions:
+    Id:
+    - Valid
+- enabled-by: true
+  post-conditions:
+    Status: InvId
+    Id: Valid
+    Flush: 'No'
+  pre-conditions:
+    Id:
+    - Invalid
+type: requirement
diff --git a/spec/rtems/barrier/req/release.yml b/spec/rtems/barrier/req/release.yml
new file mode 100644
index 0000000..6081661
--- /dev/null
+++ b/spec/rtems/barrier/req/release.yml
@@ -0,0 +1,303 @@
+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/release
+post-conditions:
+- name: Status
+  states:
+  - name: Ok
+    test-code: |
+      T_rsc_success( ctx->status );
+    text: |
+      The return status of ${../if/release:/name} shall be
+      ${../../status/if/success:/name}.
+  - name: InvId
+    test-code: |
+      T_rsc( ctx->status, RTEMS_INVALID_ID );
+    text: |
+      The return status of ${../if/release:/name} shall be
+      ${../../status/if/invalid-id:/name}.
+  - name: InvAddr
+    test-code: |
+      T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+    text: |
+      The return status of ${../if/release:/name} shall be
+      ${../../status/if/invalid-address:/name}.
+  test-epilogue: null
+  test-prologue: null
+- name: Released
+  states:
+  - name: Valid
+    test-code: |
+      T_eq_u32( ctx->released_value, ctx->waiting_tasks );
+    text: |
+      The value of the variable for the number of released tasks shall equal
+      the number of tasks released by the ${../if/release} call.
+  - name: Unchanged
+    test-code: |
+      T_eq_u32( ctx->released_value, RELEASED_INVALID_VALUE );
+    text: |
+      The value of variable for the number of released tasks shall be unchanged
+      by the ${../if/release} call.
+  test-epilogue: null
+  test-prologue: null
+pre-conditions:
+- name: Barrier
+  states:
+  - name: NoObj
+    test-code: |
+      ctx->id = 0xffffffff;
+    text: |
+      The ${../if/create:/params[0]/name} parameter shall be invalid.
+  - name: Manual
+    test-code: |
+      ctx->id = ctx->manual_release_id;
+    text: |
+      The ${../if/create:/params[0]/name} parameter shall be associated with a
+      manual release barrier.
+  - name: Auto
+    test-code: |
+      ctx->id = ctx->auto_release_id;
+    text: |
+      The ${../if/create:/params[0]/name} parameter shall be associated with an
+      automatic release barrier.
+  test-epilogue: null
+  test-prologue: null
+- name: Released
+  states:
+  - name: Valid
+    test-code: |
+      ctx->released = &ctx->released_value;
+    text: |
+      The ${../if/create:/params[1]/name} parameter shall reference an integer variable.
+  - name: 'Null'
+    test-code: |
+      ctx->released = NULL;
+    text: |
+      The ${../if/create:/params[1]/name} parameter shall be
+      ${/c/if/null:/name}.
+  test-epilogue: null
+  test-prologue: |
+    ctx->released_value = RELEASED_INVALID_VALUE;
+- name: Waiting
+  states:
+  - name: Zero
+    test-code: |
+      ctx->waiting_tasks = 0;
+    text: |
+      The number of tasks waiting at the barrier shall be zero.
+  - name: Positive
+    test-code: |
+      ctx->waiting_tasks = 1;
+      SendEvents( ctx->worker_id, EVENT_WAIT );
+    text: |
+      The number of tasks waiting at the barrier shall be positive.
+  test-epilogue: null
+  test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+  ctx->status = rtems_barrier_release( ctx->id, ctx->released );
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: null
+  description: null
+  member: |
+    rtems_id worker_id
+- brief: null
+  description: null
+  member: |
+    rtems_id manual_release_id
+- brief: null
+  description: null
+  member: |
+    rtems_id auto_release_id
+- brief: null
+  description: null
+  member: |
+    uint32_t waiting_tasks
+- brief: null
+  description: null
+  member: |
+    uint32_t released_value
+- brief: null
+  description: null
+  member: |
+    rtems_id id
+- brief: null
+  description: null
+  member: |
+    uint32_t *released
+- brief: null
+  description: null
+  member: |
+    rtems_status_code status
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+- string.h
+test-local-includes: []
+test-prepare: null
+test-setup:
+  brief: null
+  code: |
+    rtems_status_code   sc;
+    rtems_task_priority prio;
+
+    memset( ctx, 0, sizeof( *ctx ) );
+
+    prio = 0;
+    sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio );
+    T_rsc_success( sc );
+    T_eq_u32( prio, PRIO_HIGH );
+
+    sc = rtems_task_create(
+      rtems_build_name( 'W', 'O', 'R', 'K' ),
+      PRIO_HIGH,
+      RTEMS_MINIMUM_STACK_SIZE,
+      RTEMS_DEFAULT_MODES,
+      RTEMS_DEFAULT_ATTRIBUTES,
+      &ctx->worker_id
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_task_start(
+      ctx->worker_id,
+      Worker,
+      (rtems_task_argument) ctx
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_barrier_create(
+      NAME,
+      RTEMS_BARRIER_MANUAL_RELEASE,
+      0,
+      &ctx->manual_release_id
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_barrier_create(
+      NAME,
+      RTEMS_BARRIER_AUTOMATIC_RELEASE,
+      2,
+      &ctx->auto_release_id
+    );
+    T_assert_rsc_success( sc );
+  description: null
+test-stop: null
+test-support: |
+  #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+  #define EVENT_WAIT RTEMS_EVENT_0
+
+  #define RELEASED_INVALID_VALUE 0xffffffff
+
+  typedef RtemsBarrierReqRelease_Context Context;
+
+  typedef enum {
+    PRIO_HIGH = 1,
+    PRIO_NORMAL
+  } Priorities;
+
+  static void SendEvents( rtems_id id, rtems_event_set events )
+  {
+    rtems_status_code sc;
+
+    sc = rtems_event_send( id, events );
+    T_rsc_success( sc );
+  }
+
+  static void Worker( rtems_task_argument arg )
+  {
+    Context *ctx;
+
+    ctx = (Context *) arg;
+
+    while ( true ) {
+      rtems_status_code sc;
+      rtems_event_set   events;
+
+      events = 0;
+      sc = rtems_event_receive(
+        RTEMS_ALL_EVENTS,
+        RTEMS_EVENT_ANY | RTEMS_WAIT,
+        RTEMS_NO_TIMEOUT,
+        &events
+      );
+      T_rsc_success( sc );
+
+      if ( ( events & EVENT_WAIT ) != 0 ) {
+        sc = rtems_barrier_wait( ctx->id, RTEMS_NO_TIMEOUT );
+        T_rsc_success( sc );
+      }
+    }
+  }
+test-target: testsuites/validation/tc-barrier-release.c
+test-teardown:
+  brief: null
+  code: |
+    rtems_status_code   sc;
+    rtems_task_priority prio;
+
+    prio = 0;
+    sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio );
+    T_rsc_success( sc );
+    T_eq_u32( prio, PRIO_NORMAL );
+
+    if ( ctx->worker_id != 0 ) {
+      sc = rtems_task_delete( ctx->worker_id );
+      T_rsc_success( sc );
+    }
+
+    if ( ctx->manual_release_id != 0 ) {
+      sc = rtems_barrier_delete( ctx->manual_release_id );
+      T_rsc_success( sc );
+    }
+
+    if ( ctx->auto_release_id != 0 ) {
+      sc = rtems_barrier_delete( ctx->auto_release_id );
+      T_rsc_success( sc );
+    }
+  description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+  post-conditions:
+    Status: InvAddr
+    Released: Unchanged
+  pre-conditions:
+    Barrier: all
+    Released:
+    - 'Null'
+    Waiting: N/A
+- enabled-by: true
+  post-conditions:
+    Status: InvId
+    Released: Unchanged
+  pre-conditions:
+    Barrier:
+    - NoObj
+    Released:
+    - Valid
+    Waiting: N/A
+- enabled-by: true
+  post-conditions:
+    Status: Ok
+    Released: Valid
+  pre-conditions:
+    Barrier:
+    - Manual
+    - Auto
+    Released:
+    - Valid
+    Waiting: all
+type: requirement
diff --git a/spec/rtems/barrier/req/wait.yml b/spec/rtems/barrier/req/wait.yml
new file mode 100644
index 0000000..2b44f81
--- /dev/null
+++ b/spec/rtems/barrier/req/wait.yml
@@ -0,0 +1,425 @@
+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/wait
+post-conditions:
+- name: Status
+  states:
+  - name: Ok
+    test-code: |
+      T_rsc_success( ctx->status );
+    text: |
+      The return status of ${../if/wait:/name} shall be
+      ${../../status/if/success:/name}.
+  - name: InvId
+    test-code: |
+      T_rsc( ctx->status, RTEMS_INVALID_ID );
+    text: |
+      The return status of ${../if/wait:/name} shall be
+      ${../../status/if/invalid-id:/name}.
+  - name: Timeout
+    test-code: |
+      T_rsc( ctx->status, RTEMS_TIMEOUT );
+    text: |
+      The return status of ${../if/wait:/name} shall be
+      ${../../status/if/timeout:/name}.
+  - name: ObjDel
+    test-code: |
+      T_rsc( ctx->status, RTEMS_OBJECT_WAS_DELETED );
+    text: |
+      The return status of ${../if/wait:/name} shall be
+      ${../../status/if/object-was-deleted:/name}.
+  - name: NoReturn
+    test-code: |
+      T_rsc_success( ctx->status );
+    text: |
+      The call to ${../if/wait:/name} shall not return to the calling task.
+  test-epilogue: null
+  test-prologue: null
+pre-conditions:
+- name: Barrier
+  states:
+  - name: NoObj
+    test-code: |
+      ctx->id = 0xffffffff;
+    text: |
+      The ${../if/create:/params[0]/name} parameter shall be invalid.
+  - name: Manual
+    test-code: |
+      ctx->id = ctx->manual_release_id;
+    text: |
+      The ${../if/create:/params[0]/name} parameter shall be associated with a
+      manual release barrier.
+  - name: Auto
+    test-code: |
+      ctx->id = ctx->auto_release_id;
+    text: |
+      The ${../if/create:/params[0]/name} parameter shall be associated with an
+      automatic release barrier.
+  test-epilogue: null
+  test-prologue: null
+- name: Timeout
+  states:
+  - name: Ticks
+    test-code: |
+      ctx->timeout = 2;
+    text: |
+      The ${../if/create:/params[1]/name} parameter shall be a clock tick
+      interval.
+  - name: Forever
+    test-code: |
+      ctx->timeout = RTEMS_NO_TIMEOUT;
+    text: |
+      The ${../if/create:/params[1]/name} parameter shall be
+      ${../../type/if/no-timeout:/name}.
+  test-epilogue: null
+  test-prologue: null
+- name: Satisfy
+  states:
+  - name: Never
+    test-code: |
+      if ( ctx->timeout == RTEMS_NO_TIMEOUT ) {
+        SendEvents( ctx->low_worker_id, EVENT_CHECK_TIMER | EVENT_RELEASE );
+      }
+    text: |
+      While the calling task waits at the barrier, the barrier shall not be
+      released or deleted.
+  - name: Wait
+    test-code: |
+      SendEvents( ctx->high_worker_id, EVENT_WAIT );
+    text: |
+      Calling the directive shall release the barrier.
+  - name: Release
+    test-code: |
+      SendEvents( ctx->low_worker_id, EVENT_RELEASE );
+    text: |
+      While the calling task waits at the barrier, the barrier shall be
+      released.
+  - name: Delete
+    test-code: |
+      SendEvents( ctx->low_worker_id, EVENT_DELETE );
+    text: |
+      While the calling task waits at the barrier, the barrier shall be
+      deleted.
+  test-epilogue: null
+  test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons:
+  NoWaitRelease: |
+    Manual release barriers cannot be released by calling the directive.
+test-action: |
+  ctx->status = rtems_barrier_wait( ctx->id, ctx->timeout );
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: null
+  description: null
+  member: |
+    rtems_id main_id
+- brief: null
+  description: null
+  member: |
+    rtems_id high_worker_id
+- brief: null
+  description: null
+  member: |
+    rtems_id low_worker_id
+- brief: null
+  description: null
+  member: |
+    rtems_id manual_release_id
+- brief: null
+  description: null
+  member: |
+    rtems_id auto_release_id
+- brief: null
+  description: null
+  member: |
+    rtems_id id
+- brief: null
+  description: null
+  member: |
+    rtems_interval timeout
+- brief: null
+  description: null
+  member: |
+    rtems_status_code status
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+- string.h
+test-local-includes: []
+test-prepare: null
+test-setup:
+  brief: null
+  code: |
+    rtems_status_code   sc;
+    rtems_task_priority prio;
+
+    memset( ctx, 0, sizeof( *ctx ) );
+    ctx->main_id = rtems_task_self();
+
+    prio = 0;
+    sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio );
+    T_rsc_success( sc );
+    T_eq_u32( prio, PRIO_HIGH );
+
+    sc = rtems_task_create(
+      rtems_build_name( 'W', 'O', 'R', 'K' ),
+      PRIO_HIGH,
+      RTEMS_MINIMUM_STACK_SIZE,
+      RTEMS_DEFAULT_MODES,
+      RTEMS_DEFAULT_ATTRIBUTES,
+      &ctx->high_worker_id
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_task_start(
+      ctx->high_worker_id,
+      Worker,
+      (rtems_task_argument) ctx
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_task_create(
+      rtems_build_name( 'W', 'O', 'R', 'K' ),
+      PRIO_LOW,
+      RTEMS_MINIMUM_STACK_SIZE,
+      RTEMS_DEFAULT_MODES,
+      RTEMS_DEFAULT_ATTRIBUTES,
+      &ctx->low_worker_id
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_task_start(
+      ctx->low_worker_id,
+      Worker,
+      (rtems_task_argument) ctx
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_barrier_create(
+      NAME,
+      RTEMS_BARRIER_MANUAL_RELEASE,
+      0,
+      &ctx->manual_release_id
+    );
+    T_assert_rsc_success( sc );
+
+    sc = rtems_barrier_create(
+      NAME,
+      RTEMS_BARRIER_AUTOMATIC_RELEASE,
+      2,
+      &ctx->auto_release_id
+    );
+    T_assert_rsc_success( sc );
+  description: null
+test-stop: null
+test-support: |
+  #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+  #define EVENT_CHECK_TIMER RTEMS_EVENT_0
+
+  #define EVENT_WAIT RTEMS_EVENT_1
+
+  #define EVENT_RELEASE RTEMS_EVENT_2
+
+  #define EVENT_DELETE RTEMS_EVENT_3
+
+  typedef RtemsBarrierReqWait_Context Context;
+
+  typedef enum {
+    PRIO_HIGH = 1,
+    PRIO_NORMAL,
+    PRIO_LOW
+  } Priorities;
+
+  static void SendEvents( rtems_id id, rtems_event_set events )
+  {
+    rtems_status_code sc;
+
+    sc = rtems_event_send( id, events );
+    T_rsc_success( sc );
+  }
+
+  static void Worker( rtems_task_argument arg )
+  {
+    Context *ctx;
+
+    ctx = (Context *) arg;
+
+    while ( true ) {
+      rtems_status_code sc;
+      rtems_event_set   events;
+
+      events = 0;
+      sc = rtems_event_receive(
+        RTEMS_ALL_EVENTS,
+        RTEMS_EVENT_ANY | RTEMS_WAIT,
+        RTEMS_NO_TIMEOUT,
+        &events
+      );
+      T_rsc_success( sc );
+
+      if ( ( events & EVENT_CHECK_TIMER ) != 0 ) {
+        T_eq_int(
+          T_get_thread_timer_state( ctx->main_id ),
+          T_THREAD_TIMER_INACTIVE
+        );
+      }
+
+      if ( ( events & EVENT_WAIT ) != 0 ) {
+        sc = rtems_barrier_wait( ctx->id, RTEMS_NO_TIMEOUT );
+        T_rsc_success( sc );
+      }
+
+      if ( ( events & EVENT_RELEASE ) != 0 ) {
+        uint32_t released;
+
+        sc = rtems_barrier_release( ctx->id, &released );
+        T_rsc_success( sc );
+      }
+
+      if ( ( events & EVENT_DELETE ) != 0 ) {
+        rtems_attribute     attribute_set;
+        uint32_t            maximum_waiters;
+        rtems_id           *id;
+        rtems_task_priority prio;
+
+        if ( ctx->id == ctx->manual_release_id ) {
+          attribute_set = RTEMS_BARRIER_MANUAL_RELEASE;
+          maximum_waiters = 0;
+          id = &ctx->manual_release_id;
+        } else {
+          attribute_set = RTEMS_BARRIER_AUTOMATIC_RELEASE;
+          maximum_waiters = 2;
+          id = &ctx->auto_release_id;
+        }
+
+        prio = 0;
+        sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio );
+        T_rsc_success( sc );
+        T_eq_u32( prio, PRIO_LOW );
+
+        sc = rtems_barrier_delete( ctx->id );
+        T_rsc_success( sc );
+
+        sc = rtems_barrier_create( NAME, attribute_set, maximum_waiters, id );
+        T_rsc_success( sc );
+
+        sc = rtems_task_set_priority( RTEMS_SELF, prio, &prio );
+        T_rsc_success( sc );
+        T_eq_u32( prio, PRIO_HIGH );
+      }
+    }
+  }
+test-target: testsuites/validation/tc-barrier-wait.c
+test-teardown:
+  brief: null
+  code: |
+    rtems_status_code   sc;
+    rtems_task_priority prio;
+
+    prio = 0;
+    sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio );
+    T_rsc_success( sc );
+    T_eq_u32( prio, PRIO_NORMAL );
+
+    if ( ctx->high_worker_id != 0 ) {
+      sc = rtems_task_delete( ctx->high_worker_id );
+      T_rsc_success( sc );
+    }
+
+    if ( ctx->low_worker_id != 0 ) {
+      sc = rtems_task_delete( ctx->low_worker_id );
+      T_rsc_success( sc );
+    }
+
+    if ( ctx->manual_release_id != 0 ) {
+      sc = rtems_barrier_delete( ctx->manual_release_id );
+      T_rsc_success( sc );
+    }
+
+    if ( ctx->auto_release_id != 0 ) {
+      sc = rtems_barrier_delete( ctx->auto_release_id );
+      T_rsc_success( sc );
+    }
+  description: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+  post-conditions:
+    Status: InvId
+  pre-conditions:
+    Barrier:
+    - NoObj
+    Timeout: N/A
+    Satisfy: N/A
+- enabled-by: true
+  post-conditions:
+    Status: Ok
+  pre-conditions:
+    Barrier:
+    - Manual
+    - Auto
+    Timeout: all
+    Satisfy:
+    - Release
+- enabled-by: true
+  post-conditions:
+    Status: Ok
+  pre-conditions:
+    Barrier:
+    - Auto
+    Timeout: all
+    Satisfy:
+    - Wait
+- enabled-by: true
+  post-conditions:
+    Status: NoReturn
+  pre-conditions:
+    Barrier:
+    - Manual
+    - Auto
+    Timeout:
+    - Forever
+    Satisfy:
+    - Never
+- enabled-by: true
+  post-conditions: NoWaitRelease
+  pre-conditions:
+    Barrier:
+    - Manual
+    Timeout: all
+    Satisfy:
+    - Wait
+- enabled-by: true
+  post-conditions:
+    Status: Timeout
+  pre-conditions:
+    Barrier:
+    - Manual
+    - Auto
+    Timeout:
+    - Ticks
+    Satisfy:
+    - Never
+- enabled-by: true
+  post-conditions:
+    Status: ObjDel
+  pre-conditions:
+    Barrier:
+    - Manual
+    - Auto
+    Timeout: all
+    Satisfy:
+    - Delete
+type: requirement



More information about the vc mailing list