summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-02-04 06:39:49 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-02-08 08:40:59 +0100
commitde8cc93c4b0ff828c9a03a7eacdf2de8afa831ae (patch)
treeca7c2a3efc94ae5322b7cc87eb7c97c54b2ce726
parentspec: Tweak construct errors (diff)
downloadrtems-central-de8cc93c4b0ff828c9a03a7eacdf2de8afa831ae.tar.bz2
spec: Specify barrier manager
-rw-r--r--spec/rtems/barrier/req/create.yml376
-rw-r--r--spec/rtems/barrier/req/delete.yml239
-rw-r--r--spec/rtems/barrier/req/release.yml303
-rw-r--r--spec/rtems/barrier/req/wait.yml425
4 files changed, 1343 insertions, 0 deletions
diff --git a/spec/rtems/barrier/req/create.yml b/spec/rtems/barrier/req/create.yml
new file mode 100644
index 00000000..73273049
--- /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 00000000..dd24f9cb
--- /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 00000000..60816618
--- /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 00000000..2b44f814
--- /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