summaryrefslogtreecommitdiffstats
path: root/spec/score/tq/req/enqueue-ceiling.yml
diff options
context:
space:
mode:
Diffstat (limited to 'spec/score/tq/req/enqueue-ceiling.yml')
-rw-r--r--spec/score/tq/req/enqueue-ceiling.yml429
1 files changed, 429 insertions, 0 deletions
diff --git a/spec/score/tq/req/enqueue-ceiling.yml b/spec/score/tq/req/enqueue-ceiling.yml
new file mode 100644
index 00000000..6b136894
--- /dev/null
+++ b/spec/score/tq/req/enqueue-ceiling.yml
@@ -0,0 +1,429 @@
+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_C ) );
+ 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: First
+ 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: |
+ 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_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ 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_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: SecondFirst
+ 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 ), 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: SecondQueue
+ 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 ), 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 receives */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+pre-conditions:
+- name: EligibleScheduler
+ states:
+ - name: Home
+ test-code: |
+ ctx->helping = false;
+ text: |
+ While the enqueueing thread has no helping scheduler.
+ - name: Helping
+ test-code: |
+ ctx->helping = true;
+ text: |
+ While the enqueueing thread has at least one helping scheduler.
+ test-epilogue: null
+ test-prologue: null
+- 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: 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: QueueIneligible
+ 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: 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 two 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 queue positioned before or after the priority queue.
+test-action: |
+ Status_Control status;
+
+ if ( ctx->priority == PRIO_PSEUDO_ISR ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ } else {
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B , ctx->priority );
+
+ if ( ctx->other_before || ctx->other_after ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_B_OBTAIN );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_D,
+ TQ_EVENT_MUTEX_B_OBTAIN | TQ_EVENT_MUTEX_B_RELEASE |
+ TQ_EVENT_RUNNER_SYNC
+ );
+
+ if ( ctx->other_before ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE );
+ }
+
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
+ );
+
+ if ( ctx->other_before ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_SURRENDER );
+ }
+ } else {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
+ );
+ }
+ }
+
+ if ( ctx->helping ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ if ( rtems_scheduler_get_processor_maximum() > 2 ) {
+ AddHelper( ctx->tq_ctx, ctx->tq_ctx->third_scheduler_id );
+ }
+ } else {
+ AddHelper( ctx->tq_ctx, ctx->tq_ctx->other_scheduler_id );
+ }
+ }
+
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
+ status = TQEnqueue( ctx->tq_ctx, TQ_WAIT_FOREVER );
+ T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
+ TQSchedulerRecordStop( ctx->tq_ctx );
+ TQSurrender( ctx->tq_ctx );
+
+ if ( ctx->other_before || ctx->other_after ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_B_RELEASE );
+ TQSynchronizeRunner();
+ }
+
+ if ( ctx->helping ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ if ( rtems_scheduler_get_processor_maximum() > 2 ) {
+ RemoveHelper( ctx->tq_ctx );
+ }
+ } else {
+ RemoveHelper( ctx->tq_ctx );
+ }
+ }
+test-brief: null
+test-cleanup: null
+test-context:
+- brief: |
+ This this member is true, then the enqueueing thread shall have at least
+ one helping scheduler.
+ description: null
+ member: |
+ bool helping
+- 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
+ ineligible 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
+ ineligible 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-ceiling.h
+test-includes: []
+test-local-includes:
+- tr-tq-enqueue-ceiling.h
+test-prepare:
+ ctx->priority = PRIO_PSEUDO_ISR;
+ ctx->other_before = false;
+ ctx->other_after = false;
+test-setup:
+ brief: null
+ code: |
+ rtems_id scheduler_id;
+
+ scheduler_id = ctx->tq_ctx->runner_scheduler_id;
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_A, scheduler_id, PRIO_VERY_HIGH );
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_B, scheduler_id, PRIO_VERY_HIGH );
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_C, scheduler_id, PRIO_VERY_HIGH );
+ #if defined( RTEMS_SMP )
+ TQSetScheduler(
+ ctx->tq_ctx,
+ TQ_BLOCKER_D,
+ ctx->tq_ctx->other_scheduler_id,
+ PRIO_LOW
+ );
+ #endif
+ description: null
+test-stop: null
+test-support: |
+ typedef ScoreTqReqEnqueueCeiling_Context Context;
+
+ 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 ];
+ }
+
+ static void AddHelper( TQContext *tq_ctx, rtems_id scheduler_id )
+ {
+ TQSend( tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_A_OBTAIN );
+ TQSetScheduler( tq_ctx, TQ_BLOCKER_E, scheduler_id, PRIO_LOW );
+ TQSendAndWaitForExecutionStop(
+ tq_ctx,
+ TQ_BLOCKER_E,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE
+ );
+ }
+
+ static void RemoveHelper( TQContext *tq_ctx )
+ {
+ TQSend( tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_A_RELEASE );
+ TQMutexObtain( tq_ctx, TQ_MUTEX_A );
+ TQMutexRelease( tq_ctx, TQ_MUTEX_A );
+ }
+test-target: testsuites/validation/tr-tq-enqueue-ceiling.c
+test-teardown:
+ brief: null
+ code: |
+ TQReset( ctx->tq_ctx );
+ description: null
+text: |
+ When the calling thread is enqueued on the thread queue.
+transition-map:
+- enabled-by: true
+ post-conditions:
+ Position: InitialFirst
+ pre-conditions:
+ EligibleScheduler:
+ - Home
+ QueueEligible:
+ - None
+ QueueIneligible:
+ - None
+- enabled-by: true
+ post-conditions:
+ Position: First
+ pre-conditions:
+ EligibleScheduler:
+ - Home
+ QueueEligible:
+ - GT
+ QueueIneligible:
+ - None
+- enabled-by: true
+ post-conditions:
+ Position: Second
+ pre-conditions:
+ EligibleScheduler:
+ - Home
+ QueueEligible:
+ - EQ
+ QueueIneligible:
+ - None
+- enabled-by: true
+ post-conditions: Invalid
+ pre-conditions: default
+- enabled-by: RTEMS_SMP
+ post-conditions:
+ Position: InitialFirst
+ pre-conditions:
+ EligibleScheduler:
+ - Helping
+ QueueEligible:
+ - None
+ QueueIneligible:
+ - None
+- enabled-by: RTEMS_SMP
+ post-conditions:
+ Position: First
+ pre-conditions:
+ EligibleScheduler:
+ - Helping
+ QueueEligible:
+ - GT
+ QueueIneligible:
+ - None
+- enabled-by: RTEMS_SMP
+ post-conditions:
+ Position: Second
+ pre-conditions:
+ EligibleScheduler:
+ - Helping
+ QueueEligible:
+ - EQ
+ QueueIneligible:
+ - None
+- enabled-by: RTEMS_SMP
+ post-conditions:
+ Position: SecondQueue
+ pre-conditions:
+ EligibleScheduler: all
+ QueueEligible:
+ - EQ
+ - GT
+ QueueIneligible:
+ - Before
+- enabled-by: RTEMS_SMP
+ post-conditions:
+ Position: FirstFirst
+ pre-conditions:
+ EligibleScheduler: all
+ QueueEligible:
+ - GT
+ QueueIneligible:
+ - After
+- enabled-by: RTEMS_SMP
+ post-conditions:
+ Position: SecondFirst
+ pre-conditions:
+ EligibleScheduler: all
+ QueueEligible:
+ - EQ
+ QueueIneligible:
+ - After
+type: requirement