Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:53

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup ScoreTqReqEnqueuePriority
0007  */
0008 
0009 /*
0010  * Copyright (C) 2021 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 /*
0035  * This file is part of the RTEMS quality process and was automatically
0036  * generated.  If you find something that needs to be fixed or
0037  * worded better please post a report or patch to an RTEMS mailing list
0038  * or raise a bug report:
0039  *
0040  * https://www.rtems.org/bugs.html
0041  *
0042  * For information on updating and regenerating please refer to the How-To
0043  * section in the Software Requirements Engineering chapter of the
0044  * RTEMS Software Engineering manual.  The manual is provided as a part of
0045  * a release.  For development sources please refer to the online
0046  * documentation at:
0047  *
0048  * https://docs.rtems.org
0049  */
0050 
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054 
0055 #include "tr-tq-enqueue-priority.h"
0056 
0057 #include <rtems/test.h>
0058 
0059 /**
0060  * @defgroup ScoreTqReqEnqueuePriority spec:/score/tq/req/enqueue-priority
0061  *
0062  * @ingroup TestsuitesValidationNoClock0
0063  *
0064  * @{
0065  */
0066 
0067 typedef struct {
0068   uint8_t Skip : 1;
0069   uint8_t Pre_EligibleScheduler_NA : 1;
0070   uint8_t Pre_QueueEligible_NA : 1;
0071   uint8_t Pre_QueueIneligible_NA : 1;
0072   uint8_t Post_Position : 4;
0073 } ScoreTqReqEnqueuePriority_Entry;
0074 
0075 /**
0076  * @brief Test context for spec:/score/tq/req/enqueue-priority test case.
0077  */
0078 typedef struct {
0079   /**
0080    * @brief This this member is true, then the enqueueing thread shall have at
0081    *   least one helping scheduler.
0082    */
0083   bool helping;
0084 
0085   /**
0086    * @brief This member specifies the priority of a thread with an eligible
0087    *   scheduler equal to an eligible scheduler of the enqueueing thread.
0088    */
0089   rtems_task_priority priority;
0090 
0091   /**
0092    * @brief If this member is true, then a thread those eligible schedulers are
0093    *   ineligible scheduler to the enqueueing task should be enqueued before a
0094    *   thread with an eligible scheduler equal to an eligible scheduler of the
0095    *   enqueueing thread.
0096    */
0097   size_t other_before;
0098 
0099   /**
0100    * @brief If this member is true, then a thread those eligible schedulers are
0101    *   ineligible scheduler to the enqueueing task should be enqueued after a
0102    *   thread with an eligible scheduler equal to an eligible scheduler of the
0103    *   enqueueing thread.
0104    */
0105   size_t other_after;
0106 
0107   /**
0108    * @brief This member contains a copy of the corresponding
0109    *   ScoreTqReqEnqueuePriority_Run() parameter.
0110    */
0111   TQContext *tq_ctx;
0112 
0113   struct {
0114     /**
0115      * @brief This member defines the pre-condition states for the next action.
0116      */
0117     size_t pcs[ 3 ];
0118 
0119     /**
0120      * @brief If this member is true, then the test action loop is executed.
0121      */
0122     bool in_action_loop;
0123 
0124     /**
0125      * @brief This member contains the next transition map index.
0126      */
0127     size_t index;
0128 
0129     /**
0130      * @brief This member contains the current transition map entry.
0131      */
0132     ScoreTqReqEnqueuePriority_Entry entry;
0133 
0134     /**
0135      * @brief If this member is true, then the current transition variant
0136      *   should be skipped.
0137      */
0138     bool skip;
0139   } Map;
0140 } ScoreTqReqEnqueuePriority_Context;
0141 
0142 static ScoreTqReqEnqueuePriority_Context
0143   ScoreTqReqEnqueuePriority_Instance;
0144 
0145 static const char * const ScoreTqReqEnqueuePriority_PreDesc_EligibleScheduler[] = {
0146   "Home",
0147   "Helping",
0148   "NA"
0149 };
0150 
0151 static const char * const ScoreTqReqEnqueuePriority_PreDesc_QueueEligible[] = {
0152   "None",
0153   "High",
0154   "Equal",
0155   "Low",
0156   "NA"
0157 };
0158 
0159 static const char * const ScoreTqReqEnqueuePriority_PreDesc_QueueIneligible[] = {
0160   "None",
0161   "Only",
0162   "Before",
0163   "After",
0164   "NA"
0165 };
0166 
0167 static const char * const * const ScoreTqReqEnqueuePriority_PreDesc[] = {
0168   ScoreTqReqEnqueuePriority_PreDesc_EligibleScheduler,
0169   ScoreTqReqEnqueuePriority_PreDesc_QueueEligible,
0170   ScoreTqReqEnqueuePriority_PreDesc_QueueIneligible,
0171   NULL
0172 };
0173 
0174 typedef ScoreTqReqEnqueuePriority_Context Context;
0175 
0176 static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
0177 {
0178   const rtems_tcb *thread;
0179 
0180   do {
0181     thread = TQGetNextUnblock( ctx->tq_ctx, index )->thread;
0182   } while ( thread == ctx->tq_ctx->runner_tcb );
0183 
0184   return thread;
0185 }
0186 
0187 static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
0188 {
0189   return ctx->tq_ctx->worker_tcb[ worker ];
0190 }
0191 
0192 static void AddHelper( TQContext *tq_ctx, rtems_id scheduler_id )
0193 {
0194   TQSend( tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_A_OBTAIN );
0195   TQSetScheduler( tq_ctx, TQ_BLOCKER_E, scheduler_id, PRIO_LOW );
0196   TQSendAndWaitForExecutionStop(
0197     tq_ctx,
0198     TQ_BLOCKER_E,
0199     TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE
0200   );
0201 }
0202 
0203 static void RemoveHelper( TQContext *tq_ctx )
0204 {
0205   TQSend( tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_A_RELEASE );
0206   TQMutexObtain( tq_ctx, TQ_MUTEX_A );
0207   TQMutexRelease( tq_ctx, TQ_MUTEX_A );
0208 }
0209 
0210 static void ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Prepare(
0211   ScoreTqReqEnqueuePriority_Context              *ctx,
0212   ScoreTqReqEnqueuePriority_Pre_EligibleScheduler state
0213 )
0214 {
0215   switch ( state ) {
0216     case ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Home: {
0217       /*
0218        * While the enqueueing thread has no helping scheduler.
0219        */
0220       ctx->helping = false;
0221       break;
0222     }
0223 
0224     case ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Helping: {
0225       /*
0226        * While the enqueueing thread has at least one helping scheduler.
0227        */
0228       ctx->helping = true;
0229       break;
0230     }
0231 
0232     case ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_NA:
0233       break;
0234   }
0235 }
0236 
0237 static void ScoreTqReqEnqueuePriority_Pre_QueueEligible_Prepare(
0238   ScoreTqReqEnqueuePriority_Context          *ctx,
0239   ScoreTqReqEnqueuePriority_Pre_QueueEligible state
0240 )
0241 {
0242   switch ( state ) {
0243     case ScoreTqReqEnqueuePriority_Pre_QueueEligible_None: {
0244       /*
0245        * While all priority queues of the thread queue associated with eligible
0246        * schedulers of the enqueueing thread are empty.
0247        */
0248       ctx->priority = PRIO_PSEUDO_ISR;
0249       break;
0250     }
0251 
0252     case ScoreTqReqEnqueuePriority_Pre_QueueEligible_High: {
0253       /*
0254        * While a priority queue of the thread queue associated with an eligible
0255        * scheduler of the enqueueing thread is non-empty, while the highest
0256        * priority of the priority queue is higher than the priority of the
0257        * enqueueing thread with respect to the eligible scheduler.
0258        */
0259       ++ctx->tq_ctx->how_many;
0260       ctx->priority = PRIO_ULTRA_HIGH;
0261       break;
0262     }
0263 
0264     case ScoreTqReqEnqueuePriority_Pre_QueueEligible_Equal: {
0265       /*
0266        * While a priority queue of the thread queue associated with an eligible
0267        * scheduler of the enqueueing thread is non-empty, while the highest
0268        * priority of the priority queue is equal to the priority of the
0269        * enqueueing thread with respect to the eligible scheduler.
0270        */
0271       ++ctx->tq_ctx->how_many;
0272       ctx->priority = PRIO_VERY_HIGH;
0273       break;
0274     }
0275 
0276     case ScoreTqReqEnqueuePriority_Pre_QueueEligible_Low: {
0277       /*
0278        * While a priority queue of the thread queue associated with an eligible
0279        * scheduler of the enqueueing thread is non-empty, while the highest
0280        * priority of the priority queue is lower than the priority of the
0281        * enqueueing thread with respect to the eligible scheduler.
0282        */
0283       ++ctx->tq_ctx->how_many;
0284       ctx->priority = PRIO_HIGH;
0285       break;
0286     }
0287 
0288     case ScoreTqReqEnqueuePriority_Pre_QueueEligible_NA:
0289       break;
0290   }
0291 }
0292 
0293 static void ScoreTqReqEnqueuePriority_Pre_QueueIneligible_Prepare(
0294   ScoreTqReqEnqueuePriority_Context            *ctx,
0295   ScoreTqReqEnqueuePriority_Pre_QueueIneligible state
0296 )
0297 {
0298   switch ( state ) {
0299     case ScoreTqReqEnqueuePriority_Pre_QueueIneligible_None: {
0300       /*
0301        * While no priority queue of the thread queue exists which is not
0302        * associated with an eligible scheduler of the enqueueing thread.
0303        */
0304       ctx->other_before = false;
0305       ctx->other_after = false;
0306       break;
0307     }
0308 
0309     case ScoreTqReqEnqueuePriority_Pre_QueueIneligible_Only: {
0310       /*
0311        * While exactly one priority queue of the thread queue exists which is
0312        * not associated with an eligible scheduler of the enqueueing thread.
0313        */
0314       ++ctx->tq_ctx->how_many;
0315       ctx->other_before = true;
0316       ctx->other_after = false;
0317       break;
0318     }
0319 
0320     case ScoreTqReqEnqueuePriority_Pre_QueueIneligible_Before: {
0321       /*
0322        * While a priority queue of the thread queue exists which is not
0323        * associated with an eligible scheduler of the enqueueing thread, while
0324        * this priority queue is positioned before all priority queues which are
0325        * associated with eligible schedulers of the enqueueing thread.
0326        */
0327       ++ctx->tq_ctx->how_many;
0328       ctx->other_before = true;
0329       ctx->other_after = false;
0330       break;
0331     }
0332 
0333     case ScoreTqReqEnqueuePriority_Pre_QueueIneligible_After: {
0334       /*
0335        * While a priority queue of the thread queue exists which is not
0336        * associated with an eligible scheduler of the enqueueing thread, while
0337        * this priority queue is positioned after all priority queues which are
0338        * associated with eligible schedulers of the enqueueing thread.
0339        */
0340       ++ctx->tq_ctx->how_many;
0341       ctx->other_before = false;
0342       ctx->other_after = true;
0343       break;
0344     }
0345 
0346     case ScoreTqReqEnqueuePriority_Pre_QueueIneligible_NA:
0347       break;
0348   }
0349 }
0350 
0351 static void ScoreTqReqEnqueuePriority_Post_Position_Check(
0352   ScoreTqReqEnqueuePriority_Context      *ctx,
0353   ScoreTqReqEnqueuePriority_Post_Position state
0354 )
0355 {
0356   size_t i;
0357 
0358   i = 0;
0359 
0360   /* Event receives */
0361   T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0362   T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
0363 
0364   switch ( state ) {
0365     case ScoreTqReqEnqueuePriority_Post_Position_InitialFirst: {
0366       /*
0367        * A priority queue associated with the scheduler which contains exactly
0368        * the enqueueing thread shall be created as the first priority queue of
0369        * the thread queue.
0370        */
0371       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0372       T_eq_ptr( GetUnblock( ctx, &i ), NULL );
0373       break;
0374     }
0375 
0376     case ScoreTqReqEnqueuePriority_Post_Position_InitialLast: {
0377       /*
0378        * A priority queue associated with the scheduler which contains exactly
0379        * the enqueueing thread shall be created as the last priority queue of
0380        * the thread queue.
0381        */
0382       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_D ) );
0383       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0384       T_eq_ptr( GetUnblock( ctx, &i ), NULL );
0385       break;
0386     }
0387 
0388     case ScoreTqReqEnqueuePriority_Post_Position_First: {
0389       /*
0390        * The enqueueing thread shall be enqueued in the priority queue
0391        * associated with the scheduler.
0392        */
0393       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0394       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
0395       T_eq_ptr( GetUnblock( ctx, &i ), NULL );
0396       break;
0397     }
0398 
0399     case ScoreTqReqEnqueuePriority_Post_Position_Second: {
0400       /*
0401        * The enqueueing thread shall be enqueued in the priority queue
0402        * associated with the scheduler.
0403        */
0404       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
0405       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0406       T_eq_ptr( GetUnblock( ctx, &i ), NULL );
0407       break;
0408     }
0409 
0410     case ScoreTqReqEnqueuePriority_Post_Position_FirstFirst: {
0411       /*
0412        * The enqueueing thread shall be enqueued in the priority queue
0413        * associated with the scheduler.
0414        *
0415        * The position of the priority queue in the thread queue shall not
0416        * change.
0417        */
0418       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0419       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_D ) );
0420       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
0421       T_eq_ptr( GetUnblock( ctx, &i ), NULL );
0422       break;
0423     }
0424 
0425     case ScoreTqReqEnqueuePriority_Post_Position_SecondFirst: {
0426       /*
0427        * The enqueueing thread shall be enqueued in the priority queue
0428        * associated with the scheduler.
0429        *
0430        * The position of the priority queue in the thread queue shall not
0431        * change.
0432        */
0433       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
0434       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_D ) );
0435       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0436       T_eq_ptr( GetUnblock( ctx, &i ), NULL );
0437       break;
0438     }
0439 
0440     case ScoreTqReqEnqueuePriority_Post_Position_FirstLast: {
0441       /*
0442        * The enqueueing thread shall be enqueued in the priority queue
0443        * associated with the scheduler.
0444        *
0445        * The position of the priority queue in the thread queue shall not
0446        * change.
0447        */
0448       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_D ) );
0449       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0450       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
0451       T_eq_ptr( GetUnblock( ctx, &i ), NULL );
0452       break;
0453     }
0454 
0455     case ScoreTqReqEnqueuePriority_Post_Position_SecondLast: {
0456       /*
0457        * The enqueueing thread shall be enqueued in the priority queue
0458        * associated with the scheduler.
0459        *
0460        * The position of the priority queue in the thread queue shall not
0461        * change.
0462        */
0463       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_D ) );
0464       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
0465       T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0466       T_eq_ptr( GetUnblock( ctx, &i ), NULL );
0467       break;
0468     }
0469 
0470     case ScoreTqReqEnqueuePriority_Post_Position_NA:
0471       break;
0472   }
0473 }
0474 
0475 static void ScoreTqReqEnqueuePriority_Setup(
0476   ScoreTqReqEnqueuePriority_Context *ctx
0477 )
0478 {
0479   TQReset( ctx->tq_ctx );
0480   TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_ULTRA_HIGH );
0481   TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B, PRIO_LOW );
0482   TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_C, PRIO_VERY_HIGH );
0483 
0484   #if defined( RTEMS_SMP )
0485   TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_D, SCHEDULER_B_ID, PRIO_LOW );
0486   #endif
0487 }
0488 
0489 static void ScoreTqReqEnqueuePriority_Setup_Wrap( void *arg )
0490 {
0491   ScoreTqReqEnqueuePriority_Context *ctx;
0492 
0493   ctx = arg;
0494   ctx->Map.in_action_loop = false;
0495   ScoreTqReqEnqueuePriority_Setup( ctx );
0496 }
0497 
0498 static void ScoreTqReqEnqueuePriority_Teardown(
0499   ScoreTqReqEnqueuePriority_Context *ctx
0500 )
0501 {
0502   TQReset( ctx->tq_ctx );
0503 }
0504 
0505 static void ScoreTqReqEnqueuePriority_Teardown_Wrap( void *arg )
0506 {
0507   ScoreTqReqEnqueuePriority_Context *ctx;
0508 
0509   ctx = arg;
0510   ctx->Map.in_action_loop = false;
0511   ScoreTqReqEnqueuePriority_Teardown( ctx );
0512 }
0513 
0514 static void ScoreTqReqEnqueuePriority_Prepare(
0515   ScoreTqReqEnqueuePriority_Context *ctx
0516 )
0517 {
0518   ctx->tq_ctx->how_many = 1;
0519 }
0520 
0521 static void ScoreTqReqEnqueuePriority_Action(
0522   ScoreTqReqEnqueuePriority_Context *ctx
0523 )
0524 {
0525   TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_PREPARE );
0526 
0527   if ( ctx->other_before ) {
0528     TQSendAndWaitForExecutionStop(
0529       ctx->tq_ctx,
0530       TQ_BLOCKER_D,
0531       TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER | TQ_EVENT_RUNNER_SYNC_2
0532     );
0533   }
0534 
0535   if ( ctx->priority != PRIO_PSEUDO_ISR ) {
0536     TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B , ctx->priority );
0537     TQSend(
0538       ctx->tq_ctx,
0539       TQ_BLOCKER_B,
0540       TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
0541     );
0542   }
0543 
0544   if ( ctx->other_after ) {
0545     TQSendAndWaitForExecutionStop(
0546       ctx->tq_ctx,
0547       TQ_BLOCKER_D,
0548       TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER | TQ_EVENT_RUNNER_SYNC_2
0549     );
0550   }
0551 
0552   if ( ctx->helping ) {
0553     if ( ctx->other_before || ctx->other_after ) {
0554       if ( rtems_scheduler_get_processor_maximum() > 2 ) {
0555         AddHelper( ctx->tq_ctx, SCHEDULER_C_ID );
0556       }
0557     } else {
0558       AddHelper( ctx->tq_ctx, SCHEDULER_B_ID );
0559     }
0560   }
0561 
0562   TQSchedulerRecordStart( ctx->tq_ctx );
0563   TQSend(
0564     ctx->tq_ctx,
0565     TQ_BLOCKER_C,
0566     TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER | TQ_EVENT_RUNNER_SYNC
0567   );
0568   TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_DONE );
0569 
0570   if ( ctx->other_before || ctx->other_after ) {
0571     TQSynchronizeRunner2();
0572   } else {
0573     TQSynchronizeRunner();
0574   }
0575 
0576   TQSchedulerRecordStop( ctx->tq_ctx );
0577 
0578   if ( ctx->helping ) {
0579     if ( ctx->other_before || ctx->other_after ) {
0580       if ( rtems_scheduler_get_processor_maximum() > 2 ) {
0581         RemoveHelper( ctx->tq_ctx );
0582       }
0583     } else {
0584       RemoveHelper( ctx->tq_ctx );
0585     }
0586   }
0587 }
0588 
0589 static const ScoreTqReqEnqueuePriority_Entry
0590 ScoreTqReqEnqueuePriority_Entries[] = {
0591   { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
0592 #if defined(RTEMS_SMP)
0593   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_SecondLast },
0594 #else
0595   { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
0596 #endif
0597 #if defined(RTEMS_SMP)
0598   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_SecondFirst },
0599 #else
0600   { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
0601 #endif
0602 #if defined(RTEMS_SMP)
0603   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_InitialLast },
0604 #else
0605   { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
0606 #endif
0607   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_Second },
0608 #if defined(RTEMS_SMP)
0609   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_FirstLast },
0610 #else
0611   { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
0612 #endif
0613 #if defined(RTEMS_SMP)
0614   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_FirstFirst },
0615 #else
0616   { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
0617 #endif
0618 #if defined(RTEMS_SMP)
0619   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_Second },
0620 #else
0621   { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
0622 #endif
0623   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_InitialFirst },
0624   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_First },
0625 #if defined(RTEMS_SMP)
0626   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_InitialFirst },
0627 #else
0628   { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
0629 #endif
0630 #if defined(RTEMS_SMP)
0631   { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_First }
0632 #else
0633   { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA }
0634 #endif
0635 };
0636 
0637 static const uint8_t
0638 ScoreTqReqEnqueuePriority_Map[] = {
0639   8, 3, 0, 0, 4, 0, 1, 2, 4, 0, 1, 2, 9, 0, 5, 6, 10, 3, 0, 0, 7, 0, 1, 2, 7,
0640   0, 1, 2, 11, 0, 5, 6
0641 };
0642 
0643 static size_t ScoreTqReqEnqueuePriority_Scope( void *arg, char *buf, size_t n )
0644 {
0645   ScoreTqReqEnqueuePriority_Context *ctx;
0646 
0647   ctx = arg;
0648 
0649   if ( ctx->Map.in_action_loop ) {
0650     return T_get_scope(
0651       ScoreTqReqEnqueuePriority_PreDesc,
0652       buf,
0653       n,
0654       ctx->Map.pcs
0655     );
0656   }
0657 
0658   return 0;
0659 }
0660 
0661 static T_fixture ScoreTqReqEnqueuePriority_Fixture = {
0662   .setup = ScoreTqReqEnqueuePriority_Setup_Wrap,
0663   .stop = NULL,
0664   .teardown = ScoreTqReqEnqueuePriority_Teardown_Wrap,
0665   .scope = ScoreTqReqEnqueuePriority_Scope,
0666   .initial_context = &ScoreTqReqEnqueuePriority_Instance
0667 };
0668 
0669 static inline ScoreTqReqEnqueuePriority_Entry
0670 ScoreTqReqEnqueuePriority_PopEntry( ScoreTqReqEnqueuePriority_Context *ctx )
0671 {
0672   size_t index;
0673 
0674   index = ctx->Map.index;
0675   ctx->Map.index = index + 1;
0676   return ScoreTqReqEnqueuePriority_Entries[
0677     ScoreTqReqEnqueuePriority_Map[ index ]
0678   ];
0679 }
0680 
0681 static void ScoreTqReqEnqueuePriority_TestVariant(
0682   ScoreTqReqEnqueuePriority_Context *ctx
0683 )
0684 {
0685   ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Prepare(
0686     ctx,
0687     ctx->Map.pcs[ 0 ]
0688   );
0689   ScoreTqReqEnqueuePriority_Pre_QueueEligible_Prepare(
0690     ctx,
0691     ctx->Map.pcs[ 1 ]
0692   );
0693   ScoreTqReqEnqueuePriority_Pre_QueueIneligible_Prepare(
0694     ctx,
0695     ctx->Map.pcs[ 2 ]
0696   );
0697   ScoreTqReqEnqueuePriority_Action( ctx );
0698   ScoreTqReqEnqueuePriority_Post_Position_Check(
0699     ctx,
0700     ctx->Map.entry.Post_Position
0701   );
0702 }
0703 
0704 static T_fixture_node ScoreTqReqEnqueuePriority_Node;
0705 
0706 static T_remark ScoreTqReqEnqueuePriority_Remark = {
0707   .next = NULL,
0708   .remark = "ScoreTqReqEnqueuePriority"
0709 };
0710 
0711 void ScoreTqReqEnqueuePriority_Run( TQContext *tq_ctx )
0712 {
0713   ScoreTqReqEnqueuePriority_Context *ctx;
0714 
0715   ctx = &ScoreTqReqEnqueuePriority_Instance;
0716   ctx->tq_ctx = tq_ctx;
0717 
0718   ctx = T_push_fixture(
0719     &ScoreTqReqEnqueuePriority_Node,
0720     &ScoreTqReqEnqueuePriority_Fixture
0721   );
0722   ctx->Map.in_action_loop = true;
0723   ctx->Map.index = 0;
0724 
0725   for (
0726     ctx->Map.pcs[ 0 ] = ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Home;
0727     ctx->Map.pcs[ 0 ] < ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_NA;
0728     ++ctx->Map.pcs[ 0 ]
0729   ) {
0730     for (
0731       ctx->Map.pcs[ 1 ] = ScoreTqReqEnqueuePriority_Pre_QueueEligible_None;
0732       ctx->Map.pcs[ 1 ] < ScoreTqReqEnqueuePriority_Pre_QueueEligible_NA;
0733       ++ctx->Map.pcs[ 1 ]
0734     ) {
0735       for (
0736         ctx->Map.pcs[ 2 ] = ScoreTqReqEnqueuePriority_Pre_QueueIneligible_None;
0737         ctx->Map.pcs[ 2 ] < ScoreTqReqEnqueuePriority_Pre_QueueIneligible_NA;
0738         ++ctx->Map.pcs[ 2 ]
0739       ) {
0740         ctx->Map.entry = ScoreTqReqEnqueuePriority_PopEntry( ctx );
0741         ScoreTqReqEnqueuePriority_Prepare( ctx );
0742         ScoreTqReqEnqueuePriority_TestVariant( ctx );
0743       }
0744     }
0745   }
0746 
0747   T_add_remark( &ScoreTqReqEnqueuePriority_Remark );
0748   T_pop_fixture();
0749 }
0750 
0751 /** @} */