[rtems-central commit] spec: New cases for /rtems/sem/req/obtain

Sebastian Huber sebh at rtems.org
Tue Apr 13 08:27:20 UTC 2021


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Apr 12 14:55:27 2021 +0200

spec: New cases for /rtems/sem/req/obtain

---

 spec/rtems/sem/req/obtain.yml          |  74 ++++++-
 spec/score/sem/req/seize-try.yml       |  20 +-
 spec/score/sem/req/seize-wait.yml      | 182 ++++++++++++++++
 spec/score/tq/req/enqueue-fifo.yml     |  47 +++--
 spec/score/tq/req/enqueue-priority.yml | 371 +++++++++++++++++++++++++++++++++
 5 files changed, 652 insertions(+), 42 deletions(-)

diff --git a/spec/rtems/sem/req/obtain.yml b/spec/rtems/sem/req/obtain.yml
index 7e14f57..62cee1b 100644
--- a/spec/rtems/sem/req/obtain.yml
+++ b/spec/rtems/sem/req/obtain.yml
@@ -18,14 +18,20 @@ post-conditions:
       ${../../status/if/invalid-id:/name}.
   - name: SemSeizeTry
     test-code: |
-      ${/score/sem/req/seize-try:/test-run}(
-        &ctx->tq_ctx,
-        TQClassicSemGetCount,
-        TQClassicSemSetCount
-      );
+      ctx->tq_sem_ctx.get_count = TQSemGetCountClassic;
+      ctx->tq_sem_ctx.set_count = TQSemSetCountClassic;
+      ${/score/sem/req/seize-try:/test-run}( &ctx->tq_sem_ctx );
     text: |
       The calling task shall try to seize the semaphore as specified by
       ${/score/sem/req/seize-try}.
+  - name: SemSeizeWait
+    test-code: |
+      ctx->tq_sem_ctx.get_count = TQSemGetCountClassic;
+      ctx->tq_sem_ctx.set_count = TQSemSetCountClassic;
+      ${/score/sem/req/seize-wait:/test-run}( &ctx->tq_sem_ctx );
+    text: |
+      The calling task shall wait to seize the semaphore as specified by
+      ${/score/sem/req/seize-wait}.
   test-epilogue: null
   test-prologue: |
     rtems_status_code sc;
@@ -49,11 +55,13 @@ pre-conditions:
   - name: FIFO
     test-code: |
       ctx->attribute_set |= RTEMS_FIFO;
+      ctx->tq_ctx.discipline = TQ_FIFO;
     text: |
       While the semaphore uses the FIFO task wait queue discipline.
   - name: Priority
     test-code: |
       ctx->attribute_set |= RTEMS_PRIORITY;
+      ctx->tq_ctx.discipline = TQ_PRIORITY;
     text: |
       While the semaphore uses the priority task wait queue discipline.
   test-epilogue: null
@@ -74,6 +82,32 @@ pre-conditions:
       with a semaphore.
   test-epilogue: null
   test-prologue: null
+- name: Wait
+  states:
+  - name: 'No'
+    test-code: |
+      ctx->tq_ctx.wait = TQ_NO_WAIT;
+    text: |
+      While the ${../if/obtain:/params[1]/name} parameter indicates the
+      ${../../option/if/no-wait} option.
+  - name: Timeout
+    test-code: |
+      ctx->tq_ctx.wait = TQ_WAIT_TICKS;
+    text: |
+      While the ${../if/obtain:/params[1]/name} parameter indicates the
+      ${../../option/if/wait:/name} option, while the
+      ${../if/obtain:/params[2]/name} parameter is not equal to
+      ${../../type/if/no-timeout:/name}.
+  - name: Forever
+    test-code: |
+      ctx->tq_ctx.wait = TQ_WAIT_FOREVER;
+    text: |
+      While the ${../if/obtain:/params[1]/name} parameter indicates the
+      ${../../option/if/wait:/name} option, while the
+      ${../if/obtain:/params[2]/name} parameter is equal to
+      ${../../type/if/no-timeout:/name}.
+  test-epilogue: null
+  test-prologue: null
 rationale: null
 references: []
 requirement-type: functional
@@ -100,7 +134,10 @@ test-context:
     This member contains the thread queue test context.
   description: null
   member: |
-    TQContext tq_ctx
+    union {
+      TQContext tq_ctx;
+      TQSemContext tq_sem_ctx;
+    }
 - brief: |
     This member specifies if the attribute set of the semaphore.
   description: null
@@ -115,16 +152,17 @@ test-includes:
 test-local-includes:
 - tx-support.h
 - tr-sem-seize-try.h
+- tr-sem-seize-wait.h
 - tx-thread-queue.h
 test-prepare: null
 test-setup:
   brief: null
   code: |
     memset( ctx, 0, sizeof( *ctx ) );
-    ctx->tq_ctx.enqueue = TQClassicSemEnqueue;
-    ctx->tq_ctx.dequeue_one = TQClassicSemDequeue;
-    ctx->tq_ctx.dequeue_all = TQClassicSemDequeue;
-    ctx->tq_ctx.convert_status = TQClassicConvertStatus;
+    ctx->tq_ctx.enqueue = TQEnqueueClassicSem;
+    ctx->tq_ctx.dequeue_one = TQDequeueClassicSem;
+    ctx->tq_ctx.dequeue_all = TQDequeueClassicSem;
+    ctx->tq_ctx.convert_status = TQConvertStatusClassic;
     TQInitialize( &ctx->tq_ctx );
   description: null
 test-stop: null
@@ -136,7 +174,7 @@ test-target: testsuites/validation/tc-sem-obtain.c
 test-teardown:
   brief: null
   code: |
-    TQDestory( &ctx->tq_ctx );
+    TQDestroy( &ctx->tq_ctx );
   description: null
 text: ${.:text-template}
 transition-map:
@@ -148,6 +186,7 @@ transition-map:
     Discipline: all
     Id:
     - Invalid
+    Wait: all
 - enabled-by: true
   post-conditions:
     Action: SemSeizeTry
@@ -156,4 +195,17 @@ transition-map:
     Discipline: all
     Id:
     - Valid
+    Wait:
+    - 'No'
+- enabled-by: true
+  post-conditions:
+    Action: SemSeizeWait
+  pre-conditions:
+    Class: all
+    Discipline: all
+    Id:
+    - Valid
+    Wait:
+    - Timeout
+    - Forever
 type: requirement
diff --git a/spec/score/sem/req/seize-try.yml b/spec/score/sem/req/seize-try.yml
index 724a000..5dbc5c8 100644
--- a/spec/score/sem/req/seize-try.yml
+++ b/spec/score/sem/req/seize-try.yml
@@ -55,9 +55,9 @@ references: []
 requirement-type: functional
 skip-reasons: {}
 test-action: |
-  ( *ctx->set_count )( ctx->tq_ctx, ctx->count_before );
-  ctx->status = TQEnqueue( ctx->tq_ctx, TQ_NO_WAIT );
-  ctx->count_after = ( *ctx->get_count )( ctx->tq_ctx );
+  TQSemSetCount( ctx->tq_ctx, ctx->count_before );
+  ctx->status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT );
+  ctx->count_after = TQSemGetCount( ctx->tq_ctx );
 test-brief: null
 test-cleanup: null
 test-context:
@@ -88,17 +88,7 @@ test-header:
       is the thread queue context.
     dir: inout
     name: tq_ctx
-    specifier: TQContext *${.:name}
-  - description: |
-      is the semaphore get count handler.
-    dir: null
-    name: get_count
-    specifier: uint32_t ( *${.:name} )( TQContext * )
-  - description: |
-      is the semaphore set count handler.
-    dir: null
-    name: set_count
-    specifier: void ( *${.:name} )( TQContext *, uint32_t )
+    specifier: TQSemContext *${.:name}
   target: testsuites/validation/tr-sem-seize-try.h
 test-includes: []
 test-local-includes:
@@ -111,7 +101,7 @@ test-support: |
 
   static Status_Control Status( const Context *ctx, Status_Control status )
   {
-    return TQConvertStatus( ctx->tq_ctx, status );
+    return TQConvertStatus( &ctx->tq_ctx->base, status );
   }
 test-target: testsuites/validation/tr-sem-seize-try.c
 test-teardown: null
diff --git a/spec/score/sem/req/seize-wait.yml b/spec/score/sem/req/seize-wait.yml
new file mode 100644
index 0000000..9b135ad
--- /dev/null
+++ b/spec/score/sem/req/seize-wait.yml
@@ -0,0 +1,182 @@
+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: []
+post-conditions:
+- name: Status
+  states:
+  - name: Ok
+    test-code: |
+      status = TQEnqueue( &ctx->tq_ctx->base, ctx->tq_ctx->base.wait );
+      T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
+    text: |
+      The return status of the directive call shall be derived from
+      ${../../status/if/successful:/name}.
+  - name: Enqueued
+    test-code: |
+      if ( ctx->tq_ctx->base.discipline == TQ_FIFO ) {
+        ${../../tq/req/enqueue-fifo:/test-run}( &ctx->tq_ctx->base );
+      } else {
+        ${../../tq/req/enqueue-priority:/test-run}( &ctx->tq_ctx->base );
+      }
+    text: |
+      The calling task shall be enqueued in the specified order on the thread
+      queue used by the semaphore.
+  test-epilogue: null
+  test-prologue: |
+    Status_Control status;
+- name: Count
+  states:
+  - name: Nop
+    test-code: |
+      /* Checked by GetProperties() */
+    text: |
+      The count of the semaphore shall not be modified.
+  - name: MinusOne
+    test-code: |
+      T_eq_u32( TQSemGetCount( ctx->tq_ctx ), 0 );
+    text: |
+      The count of the semaphore shall be decremented by one.
+  test-epilogue: null
+  test-prologue: null
+- name: Timer
+  states:
+  - name: Optional
+    test-code: |
+      /* Checked by GetProperties() */
+    text: |
+      Where the directive was called with a timeout in clock ticks, the thread
+      timer of the calling task shall fire after the specified clock ticks.
+
+      Where the directive was called without a timeout, the thread timer of the
+      calling task shall be inactive.
+  - name: 'No'
+    test-code: |
+      T_eq_int(
+        T_get_thread_timer_state( RTEMS_SELF ),
+        T_THREAD_TIMER_INACTIVE
+      );
+    text: |
+      The thread timer of the calling task shall be inactive.
+  test-epilogue: null
+  test-prologue: null
+pre-conditions:
+- name: Count
+  states:
+  - name: Zero
+    test-code: |
+      /* Done by Prepare() */
+    text: |
+      The count of the semaphore shall be zero.
+  - name: Positive
+    test-code: |
+      TQSemSetCount( ctx->tq_ctx, 1 );
+    text: |
+      The count of the semaphore shall be greater than zero.
+  test-epilogue: null
+  test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons: {}
+test-action: |
+  /* Action performed by Status post-condition */
+test-brief: null
+test-cleanup: null
+test-context: []
+test-context-support: null
+test-description: null
+test-header:
+  code: null
+  includes: []
+  local-includes:
+  - tx-thread-queue.h
+  run-params:
+  - description: |
+      is the semaphore thread queue context.
+    dir: inout
+    name: tq_ctx
+    specifier: TQSemContext *${.:name}
+  target: testsuites/validation/tr-sem-seize-wait.h
+test-includes:
+- rtems/score/statesimpl.h
+test-local-includes:
+- tr-sem-seize-wait.h
+- tr-tq-enqueue-fifo.h
+- tr-tq-enqueue-priority.h
+test-prepare: |
+  ctx->tq_ctx->base.prepare = Prepare;
+  ctx->tq_ctx->base.cleanup = Cleanup;
+  ctx->tq_ctx->base.get_properties = GetProperties;
+test-setup: null
+test-stop: null
+test-support: |
+  typedef ScoreSemReqSeizeWait_Context Context;
+
+  static Status_Control Status( const Context *ctx, Status_Control status )
+  {
+    return TQConvertStatus( &ctx->tq_ctx->base, status );
+  }
+
+  static void Prepare( TQContext *base )
+  {
+    TQSemContext *ctx;
+
+    ctx = (TQSemContext *) base;
+    TQSemSetCount( ctx, 0 );
+  }
+
+  static void Cleanup( TQContext *base )
+  {
+    TQSemContext *ctx;
+
+    ctx = (TQSemContext *) base;
+    TQSemSetCount( ctx, 1 );
+  }
+
+  static void GetProperties( TQContext *base, TQWorkerKind enqueued_worker )
+  {
+    TQSemContext        *ctx;
+    T_thread_timer_state timer_state;
+
+    ctx = (TQSemContext *) base;
+    T_eq_u32(
+      ctx->base.worker_tcb[ enqueued_worker ]->current_state,
+      STATES_WAITING_FOR_SEMAPHORE
+    );
+
+    timer_state = T_get_thread_timer_state(
+      ctx->base.worker_id[ enqueued_worker ]
+    );
+
+    if ( base->wait == TQ_WAIT_TICKS ) {
+      T_eq_int( timer_state, T_THREAD_TIMER_SCHEDULED );
+    } else {
+      T_eq_int( timer_state, T_THREAD_TIMER_INACTIVE );
+    }
+
+    T_eq_u32( TQSemGetCount( ctx ), 0 );
+  }
+test-target: testsuites/validation/tr-sem-seize-wait.c
+test-teardown: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+  post-conditions:
+    Status: Ok
+    Count: MinusOne
+    Timer: 'No'
+  pre-conditions:
+    Count:
+    - Positive
+- enabled-by: true
+  post-conditions:
+    Status: Enqueued
+    Count: Nop
+    Timer: Optional
+  pre-conditions:
+    Count:
+    - Zero
+type: requirement
diff --git a/spec/score/tq/req/enqueue-fifo.yml b/spec/score/tq/req/enqueue-fifo.yml
index ba10068..9c3d9bb 100644
--- a/spec/score/tq/req/enqueue-fifo.yml
+++ b/spec/score/tq/req/enqueue-fifo.yml
@@ -25,17 +25,27 @@ post-conditions:
     size_t i;
 
     i = 0;
+
+    /* Event receive */
+    T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+
+    /* Enqueue */
+    T_eq_ptr( GetBlock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
 pre-conditions:
-- name: Empty
+- name: Queue
   states:
-  - name: 'Yes'
+  - name: Empty
     test-code: |
       /* This is the default */
     text: |
       While the queue is empty.
-  - name: 'No'
+  - name: NonEmpty
     test-code: |
-      TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_ENQUEUE );
+      TQSend(
+        ctx->tq_ctx,
+        TQ_BLOCKER_B,
+        TQ_EVENT_ENQUEUE | TQ_EVENT_DEQUEUE_ONE
+      );
     text: |
       While the queue is non-empty.
   test-epilogue: null
@@ -45,14 +55,13 @@ references: []
 requirement-type: functional
 skip-reasons: {}
 test-action: |
-  TQPrepare( ctx->tq_ctx );
   TQSchedulerRecordStart( ctx->tq_ctx );
-  TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+  TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE | TQ_EVENT_DEQUEUE_ONE );
   TQDequeueAll( ctx->tq_ctx );
   TQSchedulerRecordStop( ctx->tq_ctx );
-  TQCleanup( ctx->tq_ctx );
 test-brief: null
-test-cleanup: null
+test-cleanup: |
+  TQCleanup( ctx->tq_ctx );
 test-context: []
 test-context-support: null
 test-description: null
@@ -71,20 +80,26 @@ test-header:
 test-includes: []
 test-local-includes:
 - tr-tq-enqueue-fifo.h
-test-prepare: null
+test-prepare: |
+  TQPrepare( ctx->tq_ctx );
 test-setup: null
 test-stop: null
 test-support: |
   typedef ScoreTqReqEnqueueFifo_Context Context;
 
-  static const T_scheduler_event *GetUnblock( Context *ctx, size_t *index )
+  static const rtems_tcb *GetBlock( Context *ctx, size_t *index )
+  {
+    return TQGetNextBlock( ctx->tq_ctx, index )->thread;
+  }
+
+  static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
   {
-    return TQGetNextUnblock( ctx->tq_ctx, index );
+    return TQGetNextUnblock( ctx->tq_ctx, index )->thread;
   }
 
   static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
   {
-    return ctx->tq_ctx->worker_tcb[ TQ_BLOCKER_A ];
+    return ctx->tq_ctx->worker_tcb[ worker ];
   }
 test-target: testsuites/validation/tr-tq-enqueue-fifo.c
 test-teardown: null
@@ -94,12 +109,12 @@ transition-map:
   post-conditions:
     Position: First
   pre-conditions:
-    Empty:
-    - 'Yes'
+    Queue:
+    - Empty
 - enabled-by: true
   post-conditions:
     Position: Last
   pre-conditions:
-    Empty:
-    - 'No'
+    Queue:
+    - NonEmpty
 type: requirement
diff --git a/spec/score/tq/req/enqueue-priority.yml b/spec/score/tq/req/enqueue-priority.yml
new file mode 100644
index 0000000..e43d7d2
--- /dev/null
+++ b/spec/score/tq/req/enqueue-priority.yml
@@ -0,0 +1,371 @@
+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: []
+post-conditions:
+- name: Position
+  states:
+  - name: InitialFirst
+    test-code: |
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+    text: |
+      A priority queue associated with the scheduler which contains exactly the
+      enqueueing thread shall be created as the first priority queue of the
+      thread queue.
+  - name: InitialLast
+    test-code: |
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+    text: |
+      A priority queue associated with the scheduler which contains exactly the
+      enqueueing thread shall be created as the last priority queue of the
+      thread queue.
+  - name: First
+    test-code: |
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+    text: |
+      The enqueueing thread shall be enqueued in the priority queue associated
+      with the scheduler.
+  - name: Second
+    test-code: |
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+    text: |
+      The enqueueing thread shall be enqueued in the priority queue associated
+      with the scheduler.
+  - name: FirstFirst
+    test-code: |
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+    text: |
+      The enqueueing thread shall be enqueued in the priority queue associated
+      with the scheduler.
+
+      The position of the priority queue in the thread queue shall not change.
+  - name: SecondFirst
+    test-code: |
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+    text: |
+      The enqueueing thread shall be enqueued in the priority queue associated
+      with the scheduler.
+
+      The position of the priority queue in the thread queue shall not change.
+  - name: FirstLast
+    test-code: |
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+    text: |
+      The enqueueing thread shall be enqueued in the priority queue associated
+      with the scheduler.
+
+      The position of the priority queue in the thread queue shall not change.
+  - name: SecondLast
+    test-code: |
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+      T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+    text: |
+      The enqueueing thread shall be enqueued in the priority queue associated
+      with the scheduler.
+
+      The position of the priority queue in the thread queue shall not change.
+  test-epilogue: null
+  test-prologue: |
+    size_t i;
+
+    i = 0;
+
+    /* Event receive */
+    T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+
+    /* Enqueue */
+    T_eq_ptr( GetBlock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+pre-conditions:
+- name: QueueEligible
+  states:
+  - name: None
+    test-code: |
+      /* This is the default */
+    text: |
+      While the priority queue of the thread queue associated with an eligible
+      scheduler of the enqueueing thread is empty.
+  - name: LT
+    test-code: |
+      ctx->priority = PRIO_ULTRA_HIGH;
+    text: |
+      While the priority queue of the thread queue associated with an eligible
+      scheduler of the enqueueing thread is non-empty, while at least one
+      thread of this priority queue has a priority less than the priority of
+      the enqueueing thread with respect to this scheduler.
+  - name: EQ
+    test-code: |
+      ctx->priority = PRIO_VERY_HIGH;
+    text: |
+      While the priority queue of the thread queue associated with an eligible
+      scheduler of the enqueueing thread is non-empty, while at least one
+      thread of this priority queue has a priority equal to the priority of the
+      enqueueing thread with respect to this scheduler.
+  - name: GT
+    test-code: |
+      ctx->priority = PRIO_HIGH;
+    text: |
+      While the priority queue of the thread queue associated with an eligible
+      scheduler of the enqueueing thread is non-empty, while at least one
+      thread of this priority queue has a priority greater than the priority of
+      the enqueueing thread with respect to this scheduler.
+  test-epilogue: null
+  test-prologue: null
+- name: QueueForeign
+  states:
+  - name: None
+    test-code: |
+      /* This is the default */
+    text: |
+      While no priority queue of the thread queue exists which is not
+      associated with an eligible scheduler of the enqueueing thread.
+  - name: Only
+    test-code: |
+      ctx->other_before = true;
+    text: |
+      While exactly one priority queue of the thread queue exists which is not
+      associated with an eligible scheduler of the enqueueing thread.
+  - name: Before
+    test-code: |
+      ctx->other_before = true;
+    text: |
+      While a priority queue of the thread queue exists which is not
+      associated with an eligible scheduler of the enqueueing thread, while
+      this priority queue is positioned before all priority queues which are
+      associated with eligible schedulers of the enqueueing thread.
+  - name: After
+    test-code: |
+      ctx->other_after = true;
+    text: |
+      While a priority queue of the thread queue exists which is not associated
+      with an eligible scheduler of the enqueueing thread, while this priority
+      queue is positioned after all priority queues which are associated with
+      eligible schedulers of the enqueueing thread.
+  test-epilogue: null
+  test-prologue: null
+rationale: null
+references: []
+requirement-type: functional
+skip-reasons:
+  Invalid: |
+    These variants are invalid due to three independent reasons.  Firstly,
+    where the system was built with SMP support disabled, no other scheduler
+    can exist.  Secondly, a priority queue must be present to have another
+    priority positioned before or after the priority queue.  Thirdly, if only
+    one priority queue shall be present, then on other priority queue can
+    exist.
+test-action: |
+  if ( ctx->other_before ) {
+    TQSetScheduler(
+      ctx->tq_ctx,
+      TQ_BLOCKER_C,
+      ctx->tq_ctx->other_scheduler_id,
+      PRIO_LOW
+    );
+    TQSend(
+      ctx->tq_ctx,
+      TQ_BLOCKER_C,
+      TQ_EVENT_HELPER_OTHER_SYNC | TQ_EVENT_ENQUEUE | TQ_EVENT_DEQUEUE_ONE | TQ_EVENT_RUNNER_SYNC
+    );
+    TQSynchronizeRunner();
+  }
+
+  if ( ctx->priority != PRIO_PSEUDO_ISR ) {
+    TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A , ctx->priority );
+    TQSend(
+      ctx->tq_ctx,
+      TQ_BLOCKER_A,
+      TQ_EVENT_ENQUEUE | TQ_EVENT_DEQUEUE_ONE
+    );
+  }
+
+  if ( ctx->other_after ) {
+    TQSetScheduler(
+      ctx->tq_ctx,
+      TQ_BLOCKER_C,
+      ctx->tq_ctx->other_scheduler_id,
+      PRIO_LOW
+    );
+    TQSend(
+      ctx->tq_ctx,
+      TQ_BLOCKER_C,
+      TQ_EVENT_HELPER_OTHER_SYNC | TQ_EVENT_ENQUEUE | TQ_EVENT_DEQUEUE_ONE | TQ_EVENT_RUNNER_SYNC
+    );
+    TQSynchronizeRunner();
+  }
+
+  TQSchedulerRecordStart( ctx->tq_ctx );
+  TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_ENQUEUE | TQ_EVENT_DEQUEUE_ONE );
+  TQDequeueAll( ctx->tq_ctx );
+
+  if ( ctx->other_before || ctx->other_after ) {
+    TQSynchronizeRunner();
+  }
+
+  TQSchedulerRecordStop( ctx->tq_ctx );
+test-brief: null
+test-cleanup: |
+  TQCleanup( ctx->tq_ctx );
+  TQReset( ctx->tq_ctx );
+test-context:
+- brief: |
+    This member specifies the priority of a thread with an eligible scheduler
+    equal to an eligible scheduler of the enqueueing thread.
+  description: null
+  member: |
+    rtems_task_priority priority;
+- brief: |
+    If this member is true, then a thread those eligible schedulers are foreign
+    scheduler to the enqueueing task should be enqueued before a thread with an
+    eligible scheduler equal to an eligible scheduler of the enqueueing thread.
+  description: null
+  member: |
+    size_t other_before;
+- brief: |
+    If this member is true, then a thread those eligible schedulers are foreign
+    scheduler to the enqueueing task should be enqueued after a thread with an
+    eligible scheduler equal to an eligible scheduler of the enqueueing thread.
+  description: null
+  member: |
+    size_t other_after;
+test-context-support: null
+test-description: null
+test-header:
+  code: null
+  includes: []
+  local-includes:
+  - tx-thread-queue.h
+  run-params:
+  - description: |
+      is the thread queue context.
+    dir: inout
+    name: tq_ctx
+    specifier: TQContext *${.:name}
+  target: testsuites/validation/tr-tq-enqueue-priority.h
+test-includes: []
+test-local-includes:
+- tr-tq-enqueue-priority.h
+test-prepare:
+  ctx->priority = PRIORITY_PSEUDO_ISR;
+  ctx->other_before = false;
+  ctx->other_after = false;
+  TQPrepare( ctx->tq_ctx );
+test-setup: null
+test-stop: null
+test-support: |
+  typedef ScoreTqReqEnqueuePriority_Context Context;
+
+  static const rtems_tcb *GetBlock( Context *ctx, size_t *index )
+  {
+    return TQGetNextBlock( ctx->tq_ctx, index )->thread;
+  }
+
+  static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
+  {
+    const rtems_tcb *thread;
+
+    do {
+      thread = TQGetNextUnblock( ctx->tq_ctx, index )->thread;
+    } while ( thread == ctx->tq_ctx->runner_tcb );
+
+    return thread;
+  }
+
+  static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+  {
+    return ctx->tq_ctx->worker_tcb[ worker ];
+  }
+test-target: testsuites/validation/tr-tq-enqueue-priority.c
+test-teardown: null
+text: ${.:text-template}
+transition-map:
+- enabled-by: true
+  post-conditions:
+    Position: InitialFirst
+  pre-conditions:
+    QueueEligible:
+    - None
+    QueueForeign:
+    - None
+- enabled-by: true
+  post-conditions:
+    Position: First
+  pre-conditions:
+    QueueEligible:
+    - GT
+    QueueForeign:
+    - None
+- enabled-by: true
+  post-conditions:
+    Position: Second
+  pre-conditions:
+    QueueEligible:
+    - LT
+    - EQ
+    QueueForeign:
+    - None
+- enabled-by: true
+  post-conditions: Invalid
+  pre-conditions: default
+- enabled-by: RTEMS_SMP
+  post-conditions:
+    Position: InitialLast
+  pre-conditions:
+    QueueEligible:
+    - None
+    QueueForeign:
+    - Only
+- enabled-by: RTEMS_SMP
+  post-conditions:
+    Position: FirstLast
+  pre-conditions:
+    QueueEligible:
+    - GT
+    QueueForeign:
+    - Before
+- enabled-by: RTEMS_SMP
+  post-conditions:
+    Position: SecondLast
+  pre-conditions:
+    QueueEligible:
+    - LT
+    - EQ
+    QueueForeign:
+    - Before
+- enabled-by: RTEMS_SMP
+  post-conditions:
+    Position: FirstFirst
+  pre-conditions:
+    QueueEligible:
+    - GT
+    QueueForeign:
+    - After
+- enabled-by: RTEMS_SMP
+  post-conditions:
+    Position: SecondFirst
+  pre-conditions:
+    QueueEligible:
+    - LT
+    - EQ
+    QueueForeign:
+    - After
+type: requirement



More information about the vc mailing list