diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-02-04 06:39:49 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-02-08 08:40:59 +0100 |
commit | de8cc93c4b0ff828c9a03a7eacdf2de8afa831ae (patch) | |
tree | ca7c2a3efc94ae5322b7cc87eb7c97c54b2ce726 | |
parent | spec: Tweak construct errors (diff) | |
download | rtems-central-de8cc93c4b0ff828c9a03a7eacdf2de8afa831ae.tar.bz2 |
spec: Specify barrier manager
-rw-r--r-- | spec/rtems/barrier/req/create.yml | 376 | ||||
-rw-r--r-- | spec/rtems/barrier/req/delete.yml | 239 | ||||
-rw-r--r-- | spec/rtems/barrier/req/release.yml | 303 | ||||
-rw-r--r-- | spec/rtems/barrier/req/wait.yml | 425 |
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 |