From 9b90a96fb67d53023da54969a64fdf5ffd8339c1 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 12 Apr 2021 14:55:27 +0200 Subject: 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(-) create mode 100644 spec/score/sem/req/seize-wait.yml create mode 100644 spec/score/tq/req/enqueue-priority.yml diff --git a/spec/rtems/sem/req/obtain.yml b/spec/rtems/sem/req/obtain.yml index 7e14f577..62cee1b1 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 724a0003..5dbc5c87 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 00000000..9b135ada --- /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 ba100681..9c3d9bbb 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 00000000..e43d7d25 --- /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 -- cgit v1.2.3