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 ScoreTqReqEnqueueMrsp
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-mrsp.h"
0056 
0057 #include <rtems/test.h>
0058 
0059 /**
0060  * @defgroup ScoreTqReqEnqueueMrsp spec:/score/tq/req/enqueue-mrsp
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 : 3;
0073 } ScoreTqReqEnqueueMrsp_Entry;
0074 
0075 /**
0076  * @brief Test context for spec:/score/tq/req/enqueue-mrsp 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 which is an ineligible scheduler for the
0082    *   already enqueued threads.
0083    */
0084   bool helping;
0085 
0086   /**
0087    * @brief This member specifies the priority of an already enqueued thread
0088    *   with an eligible scheduler equal to an eligible scheduler of the
0089    *   enqueueing thread.
0090    */
0091   rtems_task_priority priority;
0092 
0093   /**
0094    * @brief If this member is true, then a thread those eligible schedulers are
0095    *   ineligible scheduler to the enqueueing task should be enqueued before a
0096    *   thread with an eligible scheduler equal to an eligible scheduler of the
0097    *   enqueueing thread.
0098    */
0099   size_t other_before;
0100 
0101   /**
0102    * @brief If this member is true, then a thread those eligible schedulers are
0103    *   ineligible scheduler to the enqueueing task should be enqueued after a
0104    *   thread with an eligible scheduler equal to an eligible scheduler of the
0105    *   enqueueing thread.
0106    */
0107   size_t other_after;
0108 
0109   /**
0110    * @brief This member contains a copy of the corresponding
0111    *   ScoreTqReqEnqueueMrsp_Run() parameter.
0112    */
0113   TQContext *tq_ctx;
0114 
0115   struct {
0116     /**
0117      * @brief This member defines the pre-condition states for the next action.
0118      */
0119     size_t pcs[ 3 ];
0120 
0121     /**
0122      * @brief If this member is true, then the test action loop is executed.
0123      */
0124     bool in_action_loop;
0125 
0126     /**
0127      * @brief This member contains the next transition map index.
0128      */
0129     size_t index;
0130 
0131     /**
0132      * @brief This member contains the current transition map entry.
0133      */
0134     ScoreTqReqEnqueueMrsp_Entry entry;
0135 
0136     /**
0137      * @brief If this member is true, then the current transition variant
0138      *   should be skipped.
0139      */
0140     bool skip;
0141   } Map;
0142 } ScoreTqReqEnqueueMrsp_Context;
0143 
0144 static ScoreTqReqEnqueueMrsp_Context
0145   ScoreTqReqEnqueueMrsp_Instance;
0146 
0147 static const char * const ScoreTqReqEnqueueMrsp_PreDesc_EligibleScheduler[] = {
0148   "Home",
0149   "Helping",
0150   "NA"
0151 };
0152 
0153 static const char * const ScoreTqReqEnqueueMrsp_PreDesc_QueueEligible[] = {
0154   "None",
0155   "Equal",
0156   "Low",
0157   "NA"
0158 };
0159 
0160 static const char * const ScoreTqReqEnqueueMrsp_PreDesc_QueueIneligible[] = {
0161   "None",
0162   "Only",
0163   "Before",
0164   "After",
0165   "NA"
0166 };
0167 
0168 static const char * const * const ScoreTqReqEnqueueMrsp_PreDesc[] = {
0169   ScoreTqReqEnqueueMrsp_PreDesc_EligibleScheduler,
0170   ScoreTqReqEnqueueMrsp_PreDesc_QueueEligible,
0171   ScoreTqReqEnqueueMrsp_PreDesc_QueueIneligible,
0172   NULL
0173 };
0174 
0175 /*
0176  * The MrsP locking protocol uses a sticky thread queue enqueue.  This means
0177  * that threads waiting for the mutex ownership perform a busy wait and thus
0178  * occupy the processor.  For a full validation we need at least four
0179  * processors.
0180  */
0181 static bool CanDoFullValidation( void )
0182 {
0183   return rtems_scheduler_get_processor_maximum() >= 4;
0184 }
0185 
0186 static void ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Prepare(
0187   ScoreTqReqEnqueueMrsp_Context              *ctx,
0188   ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler state
0189 )
0190 {
0191   switch ( state ) {
0192     case ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Home: {
0193       /*
0194        * While the enqueueing thread has no helping scheduler.
0195        */
0196       ctx->helping = false;
0197       break;
0198     }
0199 
0200     case ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Helping: {
0201       /*
0202        * While the enqueueing thread has at least one helping scheduler.
0203        */
0204       ctx->helping = true;
0205       break;
0206     }
0207 
0208     case ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_NA:
0209       break;
0210   }
0211 }
0212 
0213 static void ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Prepare(
0214   ScoreTqReqEnqueueMrsp_Context          *ctx,
0215   ScoreTqReqEnqueueMrsp_Pre_QueueEligible state
0216 )
0217 {
0218   switch ( state ) {
0219     case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_None: {
0220       /*
0221        * While all priority queues of the thread queue associated with eligible
0222        * schedulers of the enqueueing thread are empty.
0223        */
0224       ctx->priority = PRIO_PSEUDO_ISR;
0225       break;
0226     }
0227 
0228     case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Equal: {
0229       /*
0230        * While a priority queue of the thread queue associated with an eligible
0231        * scheduler of the enqueueing thread is non-empty, while the highest
0232        * priority of the priority queue is equal to the priority of the
0233        * enqueueing thread with respect to the eligible scheduler.
0234        */
0235       ctx->priority = PRIO_VERY_HIGH;
0236       break;
0237     }
0238 
0239     case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Low: {
0240       /*
0241        * While a priority queue of the thread queue associated with an eligible
0242        * scheduler of the enqueueing thread is non-empty, while the highest
0243        * priority of the priority queue is lower than the priority of the
0244        * enqueueing thread with respect to the eligible scheduler.
0245        */
0246       ctx->priority = PRIO_HIGH;
0247       break;
0248     }
0249 
0250     case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_NA:
0251       break;
0252   }
0253 }
0254 
0255 static void ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Prepare(
0256   ScoreTqReqEnqueueMrsp_Context            *ctx,
0257   ScoreTqReqEnqueueMrsp_Pre_QueueIneligible state
0258 )
0259 {
0260   switch ( state ) {
0261     case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_None: {
0262       /*
0263        * While no priority queue of the thread queue exists which is not
0264        * associated with an eligible scheduler of the enqueueing thread.
0265        */
0266       ctx->other_before = false;
0267       ctx->other_after = false;
0268       break;
0269     }
0270 
0271     case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Only: {
0272       /*
0273        * While exactly one priority queue of the thread queue exists which is
0274        * not associated with an eligible scheduler of the enqueueing thread.
0275        */
0276       ctx->other_before = true;
0277       ctx->other_after = false;
0278       break;
0279     }
0280 
0281     case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Before: {
0282       /*
0283        * While a priority queue of the thread queue exists which is not
0284        * associated with an eligible scheduler of the enqueueing thread, while
0285        * this priority queue is positioned before all priority queues which are
0286        * associated with eligible schedulers of the enqueueing thread.
0287        */
0288       ctx->other_before = true;
0289       ctx->other_after = false;
0290       break;
0291     }
0292 
0293     case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_After: {
0294       /*
0295        * While a priority queue of the thread queue exists which is not
0296        * associated with an eligible scheduler of the enqueueing thread, while
0297        * this priority queue is positioned after all priority queues which are
0298        * associated with eligible schedulers of the enqueueing thread.
0299        */
0300       ctx->other_before = false;
0301       ctx->other_after = true;
0302       break;
0303     }
0304 
0305     case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_NA:
0306       break;
0307   }
0308 }
0309 
0310 static void ScoreTqReqEnqueueMrsp_Post_Position_Check(
0311   ScoreTqReqEnqueueMrsp_Context      *ctx,
0312   ScoreTqReqEnqueueMrsp_Post_Position state
0313 )
0314 {
0315   size_t i;
0316 
0317   i = 0;
0318 
0319   /* The enqueue is sticky, so no enqueued thread is blocked by the scheduler */
0320   T_null( TQGetNextUnblock( ctx->tq_ctx, &i )->thread );
0321 
0322   switch ( state ) {
0323     case ScoreTqReqEnqueueMrsp_Post_Position_InitialFirst: {
0324       /*
0325        * A priority queue associated with the scheduler which contains exactly
0326        * the enqueueing thread shall be created as the first priority queue of
0327        * the thread queue.
0328        */
0329       T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0330       T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
0331       break;
0332     }
0333 
0334     case ScoreTqReqEnqueueMrsp_Post_Position_InitialLast: {
0335       /*
0336        * A priority queue associated with the scheduler which contains exactly
0337        * the enqueueing thread shall be created as the last priority queue of
0338        * the thread queue.
0339        */
0340       if ( CanDoFullValidation() ) {
0341         T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_C ) );
0342         T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0343         T_eq_u32( 2, TQGetCounter( ctx->tq_ctx ) );
0344       } else {
0345         T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0346         T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
0347       }
0348       break;
0349     }
0350 
0351     case ScoreTqReqEnqueueMrsp_Post_Position_Second: {
0352       /*
0353        * The enqueueing thread shall be enqueued in the priority queue
0354        * associated with the scheduler.
0355        */
0356       if ( CanDoFullValidation() ) {
0357         T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ) );
0358         T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0359         T_eq_u32( 2, TQGetCounter( ctx->tq_ctx ) );
0360       } else {
0361         T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0362         T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
0363       }
0364       break;
0365     }
0366 
0367     case ScoreTqReqEnqueueMrsp_Post_Position_SecondFirst: {
0368       /*
0369        * The enqueueing thread shall be enqueued in the priority queue
0370        * associated with the scheduler.
0371        *
0372        * The position of the priority queue in the thread queue shall not
0373        * change.
0374        */
0375       if ( CanDoFullValidation() ) {
0376         T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ) );
0377         T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_C ) );
0378         T_eq_u32( 3, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0379         T_eq_u32( 3, TQGetCounter( ctx->tq_ctx ) );
0380       } else {
0381         T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0382         T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
0383       }
0384       break;
0385     }
0386 
0387     case ScoreTqReqEnqueueMrsp_Post_Position_SecondLast: {
0388       /*
0389        * The enqueueing thread shall be enqueued in the priority queue
0390        * associated with the scheduler.
0391        *
0392        * The position of the priority queue in the thread queue shall not
0393        * change.
0394        */
0395       if ( CanDoFullValidation() ) {
0396         T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_C ) );
0397         T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ) );
0398         T_eq_u32( 3, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0399         T_eq_u32( 3, TQGetCounter( ctx->tq_ctx ) );
0400       } else {
0401         T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0402         T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
0403       }
0404       break;
0405     }
0406 
0407     case ScoreTqReqEnqueueMrsp_Post_Position_NA:
0408       break;
0409   }
0410 }
0411 
0412 static void ScoreTqReqEnqueueMrsp_Setup( ScoreTqReqEnqueueMrsp_Context *ctx )
0413 {
0414   if ( CanDoFullValidation() ) {
0415     RemoveProcessor( SCHEDULER_C_ID, 2 );
0416     AddProcessor( SCHEDULER_B_ID, 2 );
0417     TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_C, SCHEDULER_C_ID, PRIO_LOW );
0418   }
0419 
0420   TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_A, SCHEDULER_B_ID, PRIO_LOW );
0421   TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_B, SCHEDULER_B_ID, PRIO_LOW );
0422   TQSetScheduler(
0423     ctx->tq_ctx,
0424     TQ_BLOCKER_D,
0425     SCHEDULER_A_ID,
0426     PRIO_ULTRA_HIGH
0427   );
0428 }
0429 
0430 static void ScoreTqReqEnqueueMrsp_Setup_Wrap( void *arg )
0431 {
0432   ScoreTqReqEnqueueMrsp_Context *ctx;
0433 
0434   ctx = arg;
0435   ctx->Map.in_action_loop = false;
0436   ScoreTqReqEnqueueMrsp_Setup( ctx );
0437 }
0438 
0439 static void ScoreTqReqEnqueueMrsp_Teardown(
0440   ScoreTqReqEnqueueMrsp_Context *ctx
0441 )
0442 {
0443   if ( CanDoFullValidation() ) {
0444     RemoveProcessor( SCHEDULER_B_ID, 2 );
0445     AddProcessor( SCHEDULER_C_ID, 2 );
0446   }
0447 
0448   TQReset( ctx->tq_ctx );
0449 }
0450 
0451 static void ScoreTqReqEnqueueMrsp_Teardown_Wrap( void *arg )
0452 {
0453   ScoreTqReqEnqueueMrsp_Context *ctx;
0454 
0455   ctx = arg;
0456   ctx->Map.in_action_loop = false;
0457   ScoreTqReqEnqueueMrsp_Teardown( ctx );
0458 }
0459 
0460 static void ScoreTqReqEnqueueMrsp_Action( ScoreTqReqEnqueueMrsp_Context *ctx )
0461 {
0462   Status_Control status;
0463 
0464   TQResetCounter( ctx->tq_ctx );
0465   TQClearDone( ctx->tq_ctx, TQ_BLOCKER_A );
0466   TQClearDone( ctx->tq_ctx, TQ_BLOCKER_B );
0467   TQClearDone( ctx->tq_ctx, TQ_BLOCKER_C );
0468 
0469   status = TQEnqueue( ctx->tq_ctx, TQ_WAIT_FOREVER );
0470   T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
0471 
0472   if ( ctx->helping ) {
0473     TQSend(
0474       ctx->tq_ctx,
0475       TQ_BLOCKER_A,
0476       TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_RUNNER_SYNC
0477     );
0478     TQSynchronizeRunner();
0479     TQSend(
0480       ctx->tq_ctx,
0481       TQ_BLOCKER_D,
0482       TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE |
0483         TQ_EVENT_RUNNER_SYNC_2
0484     );
0485   }
0486 
0487   if ( CanDoFullValidation() ) {
0488     if ( ctx->other_before ) {
0489       TQSendAndWaitForIntendToBlock(
0490         ctx->tq_ctx,
0491         TQ_BLOCKER_C,
0492         TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
0493       );
0494     }
0495 
0496     if ( ctx->priority != PRIO_PSEUDO_ISR ) {
0497       TQSendAndWaitForIntendToBlock(
0498         ctx->tq_ctx,
0499         TQ_BLOCKER_B,
0500         TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
0501       );
0502     }
0503 
0504     if ( ctx->other_after ) {
0505       TQSendAndWaitForIntendToBlock(
0506         ctx->tq_ctx,
0507         TQ_BLOCKER_C,
0508         TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
0509       );
0510     }
0511   }
0512 
0513   TQSendAndWaitForIntendToBlock(
0514     ctx->tq_ctx,
0515     TQ_BLOCKER_A,
0516     TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
0517   );
0518 
0519   TQSchedulerRecordStart( ctx->tq_ctx );
0520   status = TQSurrender( ctx->tq_ctx );
0521   T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
0522   TQWaitForDone( ctx->tq_ctx, TQ_BLOCKER_A );
0523 
0524   if ( CanDoFullValidation() ) {
0525     if ( ctx->priority != PRIO_PSEUDO_ISR ) {
0526       TQWaitForDone( ctx->tq_ctx, TQ_BLOCKER_B );
0527     }
0528 
0529     if ( ctx->other_before || ctx->other_after ) {
0530       TQWaitForDone( ctx->tq_ctx, TQ_BLOCKER_C );
0531     }
0532   }
0533 
0534   TQSchedulerRecordStop( ctx->tq_ctx );
0535 
0536   if ( ctx->helping ) {
0537     TQSend(
0538       ctx->tq_ctx,
0539       TQ_BLOCKER_A,
0540       TQ_EVENT_MUTEX_A_RELEASE | TQ_EVENT_RUNNER_SYNC
0541     );
0542     TQSynchronizeRunner2();
0543   }
0544 }
0545 
0546 static const ScoreTqReqEnqueueMrsp_Entry
0547 ScoreTqReqEnqueueMrsp_Entries[] = {
0548   { 1, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_NA },
0549   { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_Second },
0550   { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_SecondLast },
0551   { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_SecondFirst },
0552   { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_InitialFirst },
0553   { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_InitialLast }
0554 };
0555 
0556 static const uint8_t
0557 ScoreTqReqEnqueueMrsp_Map[] = {
0558   4, 5, 0, 0, 1, 0, 2, 3, 1, 0, 2, 3, 4, 5, 0, 0, 1, 0, 2, 3, 1, 0, 2, 3
0559 };
0560 
0561 static size_t ScoreTqReqEnqueueMrsp_Scope( void *arg, char *buf, size_t n )
0562 {
0563   ScoreTqReqEnqueueMrsp_Context *ctx;
0564 
0565   ctx = arg;
0566 
0567   if ( ctx->Map.in_action_loop ) {
0568     return T_get_scope( ScoreTqReqEnqueueMrsp_PreDesc, buf, n, ctx->Map.pcs );
0569   }
0570 
0571   return 0;
0572 }
0573 
0574 static T_fixture ScoreTqReqEnqueueMrsp_Fixture = {
0575   .setup = ScoreTqReqEnqueueMrsp_Setup_Wrap,
0576   .stop = NULL,
0577   .teardown = ScoreTqReqEnqueueMrsp_Teardown_Wrap,
0578   .scope = ScoreTqReqEnqueueMrsp_Scope,
0579   .initial_context = &ScoreTqReqEnqueueMrsp_Instance
0580 };
0581 
0582 static inline ScoreTqReqEnqueueMrsp_Entry ScoreTqReqEnqueueMrsp_PopEntry(
0583   ScoreTqReqEnqueueMrsp_Context *ctx
0584 )
0585 {
0586   size_t index;
0587 
0588   index = ctx->Map.index;
0589   ctx->Map.index = index + 1;
0590   return ScoreTqReqEnqueueMrsp_Entries[
0591     ScoreTqReqEnqueueMrsp_Map[ index ]
0592   ];
0593 }
0594 
0595 static void ScoreTqReqEnqueueMrsp_TestVariant(
0596   ScoreTqReqEnqueueMrsp_Context *ctx
0597 )
0598 {
0599   ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Prepare(
0600     ctx,
0601     ctx->Map.pcs[ 0 ]
0602   );
0603   ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0604   ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0605   ScoreTqReqEnqueueMrsp_Action( ctx );
0606   ScoreTqReqEnqueueMrsp_Post_Position_Check(
0607     ctx,
0608     ctx->Map.entry.Post_Position
0609   );
0610 }
0611 
0612 static T_fixture_node ScoreTqReqEnqueueMrsp_Node;
0613 
0614 static T_remark ScoreTqReqEnqueueMrsp_Remark = {
0615   .next = NULL,
0616   .remark = "ScoreTqReqEnqueueMrsp"
0617 };
0618 
0619 void ScoreTqReqEnqueueMrsp_Run( TQContext *tq_ctx )
0620 {
0621   ScoreTqReqEnqueueMrsp_Context *ctx;
0622 
0623   ctx = &ScoreTqReqEnqueueMrsp_Instance;
0624   ctx->tq_ctx = tq_ctx;
0625 
0626   ctx = T_push_fixture(
0627     &ScoreTqReqEnqueueMrsp_Node,
0628     &ScoreTqReqEnqueueMrsp_Fixture
0629   );
0630   ctx->Map.in_action_loop = true;
0631   ctx->Map.index = 0;
0632 
0633   for (
0634     ctx->Map.pcs[ 0 ] = ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Home;
0635     ctx->Map.pcs[ 0 ] < ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_NA;
0636     ++ctx->Map.pcs[ 0 ]
0637   ) {
0638     for (
0639       ctx->Map.pcs[ 1 ] = ScoreTqReqEnqueueMrsp_Pre_QueueEligible_None;
0640       ctx->Map.pcs[ 1 ] < ScoreTqReqEnqueueMrsp_Pre_QueueEligible_NA;
0641       ++ctx->Map.pcs[ 1 ]
0642     ) {
0643       for (
0644         ctx->Map.pcs[ 2 ] = ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_None;
0645         ctx->Map.pcs[ 2 ] < ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_NA;
0646         ++ctx->Map.pcs[ 2 ]
0647       ) {
0648         ctx->Map.entry = ScoreTqReqEnqueueMrsp_PopEntry( ctx );
0649         ScoreTqReqEnqueueMrsp_TestVariant( ctx );
0650       }
0651     }
0652   }
0653 
0654   T_add_remark( &ScoreTqReqEnqueueMrsp_Remark );
0655   T_pop_fixture();
0656 }
0657 
0658 /** @} */