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 ScoreTqReqFlushFifo
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-flush-fifo.h"
0056 #include "tx-support.h"
0057 
0058 #include <rtems/test.h>
0059 
0060 /**
0061  * @defgroup ScoreTqReqFlushFifo spec:/score/tq/req/flush-fifo
0062  *
0063  * @ingroup TestsuitesValidationNoClock0
0064  *
0065  * @{
0066  */
0067 
0068 typedef struct {
0069   uint8_t Skip : 1;
0070   uint8_t Pre_MayStop_NA : 1;
0071   uint8_t Pre_QueueEmpty_NA : 1;
0072   uint8_t Pre_Stop_NA : 1;
0073   uint8_t Pre_WaitState_NA : 1;
0074   uint8_t Post_Operation : 2;
0075 } ScoreTqReqFlushFifo_Entry;
0076 
0077 /**
0078  * @brief Test context for spec:/score/tq/req/flush-fifo test case.
0079  */
0080 typedef struct {
0081   /**
0082    * @brief If this member is true, then the flush filter shall return NULL.
0083    */
0084   bool stop;
0085 
0086   /**
0087    * @brief If this member is true, then the least recently enqueued thread
0088    *   shall be in the intend to block wait state.
0089    */
0090   bool intend_to_block;
0091 
0092   /**
0093    * @brief This member contains the call within ISR request.
0094    */
0095   CallWithinISRRequest request;
0096 
0097   /**
0098    * @brief This member contains a copy of the corresponding
0099    *   ScoreTqReqFlushFifo_Run() parameter.
0100    */
0101   TQContext *tq_ctx;
0102 
0103   /**
0104    * @brief This member contains a copy of the corresponding
0105    *   ScoreTqReqFlushFifo_Run() parameter.
0106    */
0107   bool may_stop;
0108 
0109   struct {
0110     /**
0111      * @brief This member defines the pre-condition indices for the next
0112      *   action.
0113      */
0114     size_t pci[ 4 ];
0115 
0116     /**
0117      * @brief This member defines the pre-condition states for the next action.
0118      */
0119     size_t pcs[ 4 ];
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     ScoreTqReqFlushFifo_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 } ScoreTqReqFlushFifo_Context;
0143 
0144 static ScoreTqReqFlushFifo_Context
0145   ScoreTqReqFlushFifo_Instance;
0146 
0147 static const char * const ScoreTqReqFlushFifo_PreDesc_MayStop[] = {
0148   "Yes",
0149   "No",
0150   "NA"
0151 };
0152 
0153 static const char * const ScoreTqReqFlushFifo_PreDesc_QueueEmpty[] = {
0154   "Yes",
0155   "No",
0156   "NA"
0157 };
0158 
0159 static const char * const ScoreTqReqFlushFifo_PreDesc_Stop[] = {
0160   "Yes",
0161   "No",
0162   "NA"
0163 };
0164 
0165 static const char * const ScoreTqReqFlushFifo_PreDesc_WaitState[] = {
0166   "Blocked",
0167   "IntendToBlock",
0168   "NA"
0169 };
0170 
0171 static const char * const * const ScoreTqReqFlushFifo_PreDesc[] = {
0172   ScoreTqReqFlushFifo_PreDesc_MayStop,
0173   ScoreTqReqFlushFifo_PreDesc_QueueEmpty,
0174   ScoreTqReqFlushFifo_PreDesc_Stop,
0175   ScoreTqReqFlushFifo_PreDesc_WaitState,
0176   NULL
0177 };
0178 
0179 typedef ScoreTqReqFlushFifo_Context Context;
0180 
0181 static const T_scheduler_event *GetUnblock( Context *ctx, size_t *index )
0182 {
0183   return TQGetNextUnblock( ctx->tq_ctx, index );
0184 }
0185 
0186 static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
0187 {
0188   return ctx->tq_ctx->worker_tcb[ worker ];
0189 }
0190 
0191 static void BlockerAFlush( Context *ctx )
0192 {
0193   TQSchedulerRecordStart( ctx->tq_ctx );
0194 
0195   if ( ctx->stop ) {
0196     TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_FLUSH_PARTIAL );
0197   } else {
0198     TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_FLUSH_ALL );
0199   }
0200 }
0201 
0202 static void InterruptFlush( void *arg )
0203 {
0204   Context *ctx;
0205 
0206   ctx = arg;
0207   TQSchedulerRecordStart( ctx->tq_ctx );
0208   TQFlush( ctx->tq_ctx, !ctx->stop );
0209 }
0210 
0211 static void SchedulerEvent(
0212   void                    *arg,
0213   const T_scheduler_event *event,
0214   T_scheduler_when         when
0215 )
0216 {
0217   Context *ctx;
0218 
0219   ctx = arg;
0220 
0221   if (
0222     when == T_SCHEDULER_BEFORE &&
0223     event->operation == T_SCHEDULER_BLOCK
0224   ) {
0225     T_scheduler_set_event_handler( NULL, NULL );
0226     ctx->request.handler = InterruptFlush;
0227     CallWithinISRSubmit( &ctx->request );
0228   }
0229 }
0230 
0231 static uint32_t CheckExtractions( Context *ctx )
0232 {
0233   uint32_t                 extracted_threads;
0234   size_t                   i;
0235   const T_scheduler_event *event;
0236 
0237   extracted_threads = 0;
0238   i = 0;
0239 
0240   if ( !ctx->intend_to_block ) {
0241     /* Event receive */
0242     T_eq_ptr( GetUnblock( ctx, &i )->thread, GetTCB( ctx, TQ_BLOCKER_A ) );
0243   }
0244 
0245   event = GetUnblock( ctx, &i );
0246 
0247   if ( event != &T_scheduler_event_null ) {
0248     if ( ctx->intend_to_block ) {
0249       T_eq_ptr( event->executing, NULL );
0250     } else {
0251       T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_A ) );
0252     }
0253 
0254     T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_B ) );
0255     ++extracted_threads;
0256   }
0257 
0258   event = GetUnblock( ctx, &i );
0259 
0260   if ( event != &T_scheduler_event_null ) {
0261     if ( ctx->intend_to_block ) {
0262       T_eq_ptr( event->executing, NULL );
0263     } else {
0264       T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_A ) );
0265     }
0266 
0267     T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_C ) );
0268     ++extracted_threads;
0269   }
0270 
0271   event = GetUnblock( ctx, &i );
0272 
0273   if ( event != &T_scheduler_event_null ) {
0274     if ( ctx->intend_to_block ) {
0275       T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_D ) );
0276     } else {
0277       T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_A ) );
0278     }
0279 
0280     T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_D ) );
0281     ++extracted_threads;
0282   }
0283 
0284   T_eq_ptr( GetUnblock( ctx, &i ), &T_scheduler_event_null );
0285   T_eq_u32( extracted_threads, ctx->tq_ctx->flush_count );
0286 
0287   return extracted_threads;
0288 }
0289 
0290 static void ScoreTqReqFlushFifo_Pre_MayStop_Prepare(
0291   ScoreTqReqFlushFifo_Context    *ctx,
0292   ScoreTqReqFlushFifo_Pre_MayStop state
0293 )
0294 {
0295   switch ( state ) {
0296     case ScoreTqReqFlushFifo_Pre_MayStop_Yes: {
0297       /*
0298        * Where the flush filter may return NULL.
0299        */
0300       if ( !ctx->may_stop ) {
0301         ctx->Map.skip = true;
0302       }
0303       break;
0304     }
0305 
0306     case ScoreTqReqFlushFifo_Pre_MayStop_No: {
0307       /*
0308        * Where the flush filter does not return NULL.
0309        */
0310       if ( ctx->may_stop ) {
0311         ctx->Map.skip = true;
0312       }
0313       break;
0314     }
0315 
0316     case ScoreTqReqFlushFifo_Pre_MayStop_NA:
0317       break;
0318   }
0319 }
0320 
0321 static void ScoreTqReqFlushFifo_Pre_QueueEmpty_Prepare(
0322   ScoreTqReqFlushFifo_Context       *ctx,
0323   ScoreTqReqFlushFifo_Pre_QueueEmpty state
0324 )
0325 {
0326   switch ( state ) {
0327     case ScoreTqReqFlushFifo_Pre_QueueEmpty_Yes: {
0328       /*
0329        * While the thread queue is empty.
0330        */
0331       ctx->tq_ctx->how_many = 0;
0332       break;
0333     }
0334 
0335     case ScoreTqReqFlushFifo_Pre_QueueEmpty_No: {
0336       /*
0337        * While the thread queue has at least one enqueued thread.
0338        */
0339       ctx->tq_ctx->how_many = 3;
0340       break;
0341     }
0342 
0343     case ScoreTqReqFlushFifo_Pre_QueueEmpty_NA:
0344       break;
0345   }
0346 }
0347 
0348 static void ScoreTqReqFlushFifo_Pre_Stop_Prepare(
0349   ScoreTqReqFlushFifo_Context *ctx,
0350   ScoreTqReqFlushFifo_Pre_Stop state
0351 )
0352 {
0353   switch ( state ) {
0354     case ScoreTqReqFlushFifo_Pre_Stop_Yes: {
0355       /*
0356        * While the flush filter returns NULL for an enqueued thread.
0357        */
0358       ctx->stop = true;
0359       break;
0360     }
0361 
0362     case ScoreTqReqFlushFifo_Pre_Stop_No: {
0363       /*
0364        * While the flush filter does not return NULL for an enqueued thread.
0365        */
0366       ctx->stop = false;
0367       break;
0368     }
0369 
0370     case ScoreTqReqFlushFifo_Pre_Stop_NA:
0371       break;
0372   }
0373 }
0374 
0375 static void ScoreTqReqFlushFifo_Pre_WaitState_Prepare(
0376   ScoreTqReqFlushFifo_Context      *ctx,
0377   ScoreTqReqFlushFifo_Pre_WaitState state
0378 )
0379 {
0380   switch ( state ) {
0381     case ScoreTqReqFlushFifo_Pre_WaitState_Blocked: {
0382       /*
0383        * While the least recently enqueued thread on the thread queue is in the
0384        * blocked wait state.
0385        */
0386       ctx->intend_to_block = false;
0387       break;
0388     }
0389 
0390     case ScoreTqReqFlushFifo_Pre_WaitState_IntendToBlock: {
0391       /*
0392        * While the least recently enqueued thread on the thread queue is in the
0393        * intend to block wait state.
0394        */
0395       ctx->intend_to_block = true;
0396       break;
0397     }
0398 
0399     case ScoreTqReqFlushFifo_Pre_WaitState_NA:
0400       break;
0401   }
0402 }
0403 
0404 static void ScoreTqReqFlushFifo_Post_Operation_Check(
0405   ScoreTqReqFlushFifo_Context       *ctx,
0406   ScoreTqReqFlushFifo_Post_Operation state
0407 )
0408 {
0409   size_t   i;
0410   uint32_t extracted_threads;
0411 
0412   switch ( state ) {
0413     case ScoreTqReqFlushFifo_Post_Operation_Nop: {
0414       /*
0415        * No thread queue extraction operation shall be performed.
0416        */
0417       /* Event receive */
0418       i = 0;
0419       T_eq_ptr( GetUnblock( ctx, &i )->thread, GetTCB( ctx, TQ_BLOCKER_A ) );
0420       T_eq_ptr( GetUnblock( ctx, &i ), &T_scheduler_event_null );
0421       break;
0422     }
0423 
0424     case ScoreTqReqFlushFifo_Post_Operation_ExtractAll: {
0425       /*
0426        * The enqueued threads shall be extracted from the thread queue in FIFO
0427        * order.
0428        */
0429       extracted_threads = CheckExtractions( ctx );
0430       T_eq_sz( extracted_threads, ctx->tq_ctx->how_many );
0431       break;
0432     }
0433 
0434     case ScoreTqReqFlushFifo_Post_Operation_ExtractPartial: {
0435       /*
0436        * The enqueued threads which precede in FIFO order the enqueued thread
0437        * for which the flush filter returned NULL shall be extracted from the
0438        * thread queue in FIFO order.
0439        */
0440       extracted_threads = CheckExtractions( ctx );
0441       T_lt_sz( extracted_threads, ctx->tq_ctx->how_many );
0442       break;
0443     }
0444 
0445     case ScoreTqReqFlushFifo_Post_Operation_NA:
0446       break;
0447   }
0448 }
0449 
0450 static void ScoreTqReqFlushFifo_Setup( ScoreTqReqFlushFifo_Context *ctx )
0451 {
0452   ctx->request.arg = ctx;
0453   TQReset( ctx->tq_ctx );
0454   TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_ULTRA_HIGH );
0455   TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B, PRIO_VERY_HIGH );
0456   TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_C, PRIO_HIGH );
0457   TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_D, PRIO_HIGH );
0458 }
0459 
0460 static void ScoreTqReqFlushFifo_Setup_Wrap( void *arg )
0461 {
0462   ScoreTqReqFlushFifo_Context *ctx;
0463 
0464   ctx = arg;
0465   ctx->Map.in_action_loop = false;
0466   ScoreTqReqFlushFifo_Setup( ctx );
0467 }
0468 
0469 static void ScoreTqReqFlushFifo_Teardown( ScoreTqReqFlushFifo_Context *ctx )
0470 {
0471   TQReset( ctx->tq_ctx );
0472 }
0473 
0474 static void ScoreTqReqFlushFifo_Teardown_Wrap( void *arg )
0475 {
0476   ScoreTqReqFlushFifo_Context *ctx;
0477 
0478   ctx = arg;
0479   ctx->Map.in_action_loop = false;
0480   ScoreTqReqFlushFifo_Teardown( ctx );
0481 }
0482 
0483 static void ScoreTqReqFlushFifo_Action( ScoreTqReqFlushFifo_Context *ctx )
0484 {
0485   uint32_t flush_count;
0486 
0487   TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_PREPARE );
0488 
0489   if ( ctx->tq_ctx->how_many > 0 ) {
0490     TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_ENQUEUE );
0491     TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE );
0492 
0493     if ( ctx->intend_to_block ) {
0494       T_scheduler_set_event_handler( SchedulerEvent, ctx );
0495     }
0496 
0497     TQSend( ctx->tq_ctx, TQ_BLOCKER_D, TQ_EVENT_ENQUEUE );
0498 
0499     if ( !ctx->intend_to_block ) {
0500       BlockerAFlush( ctx );
0501     }
0502   } else {
0503     BlockerAFlush( ctx );
0504   }
0505 
0506   flush_count = ctx->tq_ctx->flush_count;
0507   TQSchedulerRecordStop( ctx->tq_ctx );
0508   TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_FLUSH_ALL );
0509   TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_DONE );
0510   ctx->tq_ctx->flush_count = flush_count;
0511 }
0512 
0513 static const ScoreTqReqFlushFifo_Entry
0514 ScoreTqReqFlushFifo_Entries[] = {
0515   { 0, 0, 0, 1, 1, ScoreTqReqFlushFifo_Post_Operation_Nop },
0516   { 0, 0, 0, 0, 0, ScoreTqReqFlushFifo_Post_Operation_ExtractAll },
0517   { 0, 0, 0, 0, 0, ScoreTqReqFlushFifo_Post_Operation_ExtractPartial },
0518   { 1, 0, 0, 0, 0, ScoreTqReqFlushFifo_Post_Operation_NA }
0519 };
0520 
0521 static const uint8_t
0522 ScoreTqReqFlushFifo_Map[] = {
0523   0, 0, 0, 0, 2, 2, 1, 1, 0, 0, 0, 0, 3, 3, 1, 1
0524 };
0525 
0526 static size_t ScoreTqReqFlushFifo_Scope( void *arg, char *buf, size_t n )
0527 {
0528   ScoreTqReqFlushFifo_Context *ctx;
0529 
0530   ctx = arg;
0531 
0532   if ( ctx->Map.in_action_loop ) {
0533     return T_get_scope( ScoreTqReqFlushFifo_PreDesc, buf, n, ctx->Map.pcs );
0534   }
0535 
0536   return 0;
0537 }
0538 
0539 static T_fixture ScoreTqReqFlushFifo_Fixture = {
0540   .setup = ScoreTqReqFlushFifo_Setup_Wrap,
0541   .stop = NULL,
0542   .teardown = ScoreTqReqFlushFifo_Teardown_Wrap,
0543   .scope = ScoreTqReqFlushFifo_Scope,
0544   .initial_context = &ScoreTqReqFlushFifo_Instance
0545 };
0546 
0547 static const uint8_t ScoreTqReqFlushFifo_Weights[] = {
0548   8, 4, 2, 1
0549 };
0550 
0551 static void ScoreTqReqFlushFifo_Skip(
0552   ScoreTqReqFlushFifo_Context *ctx,
0553   size_t                       index
0554 )
0555 {
0556   switch ( index + 1 ) {
0557     case 1:
0558       ctx->Map.pci[ 1 ] = ScoreTqReqFlushFifo_Pre_QueueEmpty_NA - 1;
0559       /* Fall through */
0560     case 2:
0561       ctx->Map.pci[ 2 ] = ScoreTqReqFlushFifo_Pre_Stop_NA - 1;
0562       /* Fall through */
0563     case 3:
0564       ctx->Map.pci[ 3 ] = ScoreTqReqFlushFifo_Pre_WaitState_NA - 1;
0565       break;
0566   }
0567 }
0568 
0569 static inline ScoreTqReqFlushFifo_Entry ScoreTqReqFlushFifo_PopEntry(
0570   ScoreTqReqFlushFifo_Context *ctx
0571 )
0572 {
0573   size_t index;
0574 
0575   if ( ctx->Map.skip ) {
0576     size_t i;
0577 
0578     ctx->Map.skip = false;
0579     index = 0;
0580 
0581     for ( i = 0; i < 4; ++i ) {
0582       index += ScoreTqReqFlushFifo_Weights[ i ] * ctx->Map.pci[ i ];
0583     }
0584   } else {
0585     index = ctx->Map.index;
0586   }
0587 
0588   ctx->Map.index = index + 1;
0589 
0590   return ScoreTqReqFlushFifo_Entries[
0591     ScoreTqReqFlushFifo_Map[ index ]
0592   ];
0593 }
0594 
0595 static void ScoreTqReqFlushFifo_SetPreConditionStates(
0596   ScoreTqReqFlushFifo_Context *ctx
0597 )
0598 {
0599   ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0600   ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0601 
0602   if ( ctx->Map.entry.Pre_Stop_NA ) {
0603     ctx->Map.pcs[ 2 ] = ScoreTqReqFlushFifo_Pre_Stop_NA;
0604   } else {
0605     ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0606   }
0607 
0608   if ( ctx->Map.entry.Pre_WaitState_NA ) {
0609     ctx->Map.pcs[ 3 ] = ScoreTqReqFlushFifo_Pre_WaitState_NA;
0610   } else {
0611     ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
0612   }
0613 }
0614 
0615 static void ScoreTqReqFlushFifo_TestVariant( ScoreTqReqFlushFifo_Context *ctx )
0616 {
0617   ScoreTqReqFlushFifo_Pre_MayStop_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0618 
0619   if ( ctx->Map.skip ) {
0620     ScoreTqReqFlushFifo_Skip( ctx, 0 );
0621     return;
0622   }
0623 
0624   ScoreTqReqFlushFifo_Pre_QueueEmpty_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0625   ScoreTqReqFlushFifo_Pre_Stop_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0626   ScoreTqReqFlushFifo_Pre_WaitState_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0627   ScoreTqReqFlushFifo_Action( ctx );
0628   ScoreTqReqFlushFifo_Post_Operation_Check(
0629     ctx,
0630     ctx->Map.entry.Post_Operation
0631   );
0632 }
0633 
0634 static T_fixture_node ScoreTqReqFlushFifo_Node;
0635 
0636 static T_remark ScoreTqReqFlushFifo_Remark = {
0637   .next = NULL,
0638   .remark = "ScoreTqReqFlushFifo"
0639 };
0640 
0641 void ScoreTqReqFlushFifo_Run( TQContext *tq_ctx, bool may_stop )
0642 {
0643   ScoreTqReqFlushFifo_Context *ctx;
0644 
0645   ctx = &ScoreTqReqFlushFifo_Instance;
0646   ctx->tq_ctx = tq_ctx;
0647   ctx->may_stop = may_stop;
0648 
0649   ctx = T_push_fixture(
0650     &ScoreTqReqFlushFifo_Node,
0651     &ScoreTqReqFlushFifo_Fixture
0652   );
0653   ctx->Map.in_action_loop = true;
0654   ctx->Map.index = 0;
0655   ctx->Map.skip = false;
0656 
0657   for (
0658     ctx->Map.pci[ 0 ] = ScoreTqReqFlushFifo_Pre_MayStop_Yes;
0659     ctx->Map.pci[ 0 ] < ScoreTqReqFlushFifo_Pre_MayStop_NA;
0660     ++ctx->Map.pci[ 0 ]
0661   ) {
0662     for (
0663       ctx->Map.pci[ 1 ] = ScoreTqReqFlushFifo_Pre_QueueEmpty_Yes;
0664       ctx->Map.pci[ 1 ] < ScoreTqReqFlushFifo_Pre_QueueEmpty_NA;
0665       ++ctx->Map.pci[ 1 ]
0666     ) {
0667       for (
0668         ctx->Map.pci[ 2 ] = ScoreTqReqFlushFifo_Pre_Stop_Yes;
0669         ctx->Map.pci[ 2 ] < ScoreTqReqFlushFifo_Pre_Stop_NA;
0670         ++ctx->Map.pci[ 2 ]
0671       ) {
0672         for (
0673           ctx->Map.pci[ 3 ] = ScoreTqReqFlushFifo_Pre_WaitState_Blocked;
0674           ctx->Map.pci[ 3 ] < ScoreTqReqFlushFifo_Pre_WaitState_NA;
0675           ++ctx->Map.pci[ 3 ]
0676         ) {
0677           ctx->Map.entry = ScoreTqReqFlushFifo_PopEntry( ctx );
0678 
0679           if ( ctx->Map.entry.Skip ) {
0680             continue;
0681           }
0682 
0683           ScoreTqReqFlushFifo_SetPreConditionStates( ctx );
0684           ScoreTqReqFlushFifo_TestVariant( ctx );
0685         }
0686       }
0687     }
0688   }
0689 
0690   T_add_remark( &ScoreTqReqFlushFifo_Remark );
0691   T_pop_fixture();
0692 }
0693 
0694 /** @} */