Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup ScoreSchedReqYield
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 <rtems.h>
0056 #include <rtems/test-scheduler.h>
0057 #include <rtems/score/percpu.h>
0058 
0059 #include "tx-support.h"
0060 #include "tx-thread-queue.h"
0061 
0062 #include <rtems/test.h>
0063 
0064 /**
0065  * @defgroup ScoreSchedReqYield spec:/score/sched/req/yield
0066  *
0067  * @ingroup TestsuitesValidationNoClock0
0068  *
0069  * @{
0070  */
0071 
0072 typedef enum {
0073   ScoreSchedReqYield_Pre_EligibleScheduler_Home,
0074   ScoreSchedReqYield_Pre_EligibleScheduler_Helping,
0075   ScoreSchedReqYield_Pre_EligibleScheduler_NA
0076 } ScoreSchedReqYield_Pre_EligibleScheduler;
0077 
0078 typedef enum {
0079   ScoreSchedReqYield_Pre_UsedScheduler_Home,
0080   ScoreSchedReqYield_Pre_UsedScheduler_Helping,
0081   ScoreSchedReqYield_Pre_UsedScheduler_NA
0082 } ScoreSchedReqYield_Pre_UsedScheduler;
0083 
0084 typedef enum {
0085   ScoreSchedReqYield_Pre_HomeSchedulerState_Blocked,
0086   ScoreSchedReqYield_Pre_HomeSchedulerState_Scheduled,
0087   ScoreSchedReqYield_Pre_HomeSchedulerState_Ready,
0088   ScoreSchedReqYield_Pre_HomeSchedulerState_NA
0089 } ScoreSchedReqYield_Pre_HomeSchedulerState;
0090 
0091 typedef enum {
0092   ScoreSchedReqYield_Pre_Sticky_Yes,
0093   ScoreSchedReqYield_Pre_Sticky_No,
0094   ScoreSchedReqYield_Pre_Sticky_NA
0095 } ScoreSchedReqYield_Pre_Sticky;
0096 
0097 typedef enum {
0098   ScoreSchedReqYield_Pre_Other_Yes,
0099   ScoreSchedReqYield_Pre_Other_No,
0100   ScoreSchedReqYield_Pre_Other_NA
0101 } ScoreSchedReqYield_Pre_Other;
0102 
0103 typedef enum {
0104   ScoreSchedReqYield_Post_HomeSchedulerState_Blocked,
0105   ScoreSchedReqYield_Post_HomeSchedulerState_Scheduled,
0106   ScoreSchedReqYield_Post_HomeSchedulerState_Ready,
0107   ScoreSchedReqYield_Post_HomeSchedulerState_Idle,
0108   ScoreSchedReqYield_Post_HomeSchedulerState_NA
0109 } ScoreSchedReqYield_Post_HomeSchedulerState;
0110 
0111 typedef enum {
0112   ScoreSchedReqYield_Post_AskForHelp_Yes,
0113   ScoreSchedReqYield_Post_AskForHelp_No,
0114   ScoreSchedReqYield_Post_AskForHelp_NA
0115 } ScoreSchedReqYield_Post_AskForHelp;
0116 
0117 typedef struct {
0118   uint16_t Skip : 1;
0119   uint16_t Pre_EligibleScheduler_NA : 1;
0120   uint16_t Pre_UsedScheduler_NA : 1;
0121   uint16_t Pre_HomeSchedulerState_NA : 1;
0122   uint16_t Pre_Sticky_NA : 1;
0123   uint16_t Pre_Other_NA : 1;
0124   uint16_t Post_HomeSchedulerState : 3;
0125   uint16_t Post_AskForHelp : 2;
0126 } ScoreSchedReqYield_Entry;
0127 
0128 /**
0129  * @brief Test context for spec:/score/sched/req/yield test case.
0130  */
0131 typedef struct {
0132   /**
0133    * @brief This member contains the thread queue test context.
0134    */
0135   TQContext tq_ctx;
0136 
0137   /**
0138    * @brief This member contains the identifier of a sticky mutex.
0139    */
0140   rtems_id sticky_mutex;
0141 
0142   /**
0143    * @brief This member contains the processor index after yielding.
0144    */
0145   uint32_t cpu_after_yield;
0146 
0147   /**
0148    * @brief If this member is true, then the runner shall have a helping
0149    *   scheduler.
0150    */
0151   bool has_helping;
0152 
0153   /**
0154    * @brief If this member is true, then the runner shall use a helping
0155    *   scheduler.
0156    */
0157   bool use_helping;
0158 
0159   /**
0160    * @brief If this member is true, then the runner shall be ready in its home
0161    *   scheduler.
0162    */
0163   bool ready;
0164 
0165   /**
0166    * @brief If this member is true, then the runner shall be sticky.
0167    */
0168   bool sticky;
0169 
0170   /**
0171    * @brief If this member is true, then another ready task in the home
0172    *   scheduler of the runner shall be ready with an equal priority.
0173    */
0174   bool other_ready;
0175 
0176   /**
0177    * @brief If this member is true, then the processor zero was idle before
0178    *   yielding.
0179    */
0180   bool is_idle_before_yield;
0181 
0182   /**
0183    * @brief If this member is true, then the processor zero was idle after
0184    *   yielding.
0185    */
0186   bool is_idle_after_yield;
0187 
0188   struct {
0189     /**
0190      * @brief This member defines the pre-condition states for the next action.
0191      */
0192     size_t pcs[ 5 ];
0193 
0194     /**
0195      * @brief If this member is true, then the test action loop is executed.
0196      */
0197     bool in_action_loop;
0198 
0199     /**
0200      * @brief This member contains the next transition map index.
0201      */
0202     size_t index;
0203 
0204     /**
0205      * @brief This member contains the current transition map entry.
0206      */
0207     ScoreSchedReqYield_Entry entry;
0208 
0209     /**
0210      * @brief If this member is true, then the current transition variant
0211      *   should be skipped.
0212      */
0213     bool skip;
0214   } Map;
0215 } ScoreSchedReqYield_Context;
0216 
0217 static ScoreSchedReqYield_Context
0218   ScoreSchedReqYield_Instance;
0219 
0220 static const char * const ScoreSchedReqYield_PreDesc_EligibleScheduler[] = {
0221   "Home",
0222   "Helping",
0223   "NA"
0224 };
0225 
0226 static const char * const ScoreSchedReqYield_PreDesc_UsedScheduler[] = {
0227   "Home",
0228   "Helping",
0229   "NA"
0230 };
0231 
0232 static const char * const ScoreSchedReqYield_PreDesc_HomeSchedulerState[] = {
0233   "Blocked",
0234   "Scheduled",
0235   "Ready",
0236   "NA"
0237 };
0238 
0239 static const char * const ScoreSchedReqYield_PreDesc_Sticky[] = {
0240   "Yes",
0241   "No",
0242   "NA"
0243 };
0244 
0245 static const char * const ScoreSchedReqYield_PreDesc_Other[] = {
0246   "Yes",
0247   "No",
0248   "NA"
0249 };
0250 
0251 static const char * const * const ScoreSchedReqYield_PreDesc[] = {
0252   ScoreSchedReqYield_PreDesc_EligibleScheduler,
0253   ScoreSchedReqYield_PreDesc_UsedScheduler,
0254   ScoreSchedReqYield_PreDesc_HomeSchedulerState,
0255   ScoreSchedReqYield_PreDesc_Sticky,
0256   ScoreSchedReqYield_PreDesc_Other,
0257   NULL
0258 };
0259 
0260 #define COUNTER TQ_BLOCKER_A
0261 
0262 #define HELPER TQ_BLOCKER_B
0263 
0264 #define MOVER TQ_BLOCKER_C
0265 
0266 typedef ScoreSchedReqYield_Context Context;
0267 
0268 static void MoveToHelping( Context *ctx )
0269 {
0270   ctx->tq_ctx.busy_wait[ MOVER ] = true;
0271   TQSend( &ctx->tq_ctx, MOVER, TQ_EVENT_BUSY_WAIT );
0272   TQWaitForEventsReceived( &ctx->tq_ctx, MOVER );
0273   T_eq_u32( rtems_scheduler_get_processor(), 1 );
0274   ctx->tq_ctx.busy_wait[ MOVER ] = false;
0275   TQWaitForExecutionStop( &ctx->tq_ctx, MOVER );
0276 }
0277 
0278 static uint32_t GetCounter( const Context *ctx )
0279 {
0280   return TQGetWorkerCounter( &ctx->tq_ctx, COUNTER );
0281 }
0282 
0283 static void ScoreSchedReqYield_Pre_EligibleScheduler_Prepare(
0284   ScoreSchedReqYield_Context              *ctx,
0285   ScoreSchedReqYield_Pre_EligibleScheduler state
0286 )
0287 {
0288   switch ( state ) {
0289     case ScoreSchedReqYield_Pre_EligibleScheduler_Home: {
0290       /*
0291        * While the only eligible scheduler of the thread is the home scheduler.
0292        */
0293       ctx->has_helping = false;
0294       break;
0295     }
0296 
0297     case ScoreSchedReqYield_Pre_EligibleScheduler_Helping: {
0298       /*
0299        * While the thread has at least one helping scheduler.
0300        */
0301       ctx->has_helping = true;
0302       break;
0303     }
0304 
0305     case ScoreSchedReqYield_Pre_EligibleScheduler_NA:
0306       break;
0307   }
0308 }
0309 
0310 static void ScoreSchedReqYield_Pre_UsedScheduler_Prepare(
0311   ScoreSchedReqYield_Context          *ctx,
0312   ScoreSchedReqYield_Pre_UsedScheduler state
0313 )
0314 {
0315   switch ( state ) {
0316     case ScoreSchedReqYield_Pre_UsedScheduler_Home: {
0317       /*
0318        * While the thread is scheduled on the home scheduler.
0319        */
0320       ctx->use_helping = false;
0321       break;
0322     }
0323 
0324     case ScoreSchedReqYield_Pre_UsedScheduler_Helping: {
0325       /*
0326        * While the thread is scheduled on a helping scheduler.
0327        */
0328       ctx->use_helping = true;
0329       break;
0330     }
0331 
0332     case ScoreSchedReqYield_Pre_UsedScheduler_NA:
0333       break;
0334   }
0335 }
0336 
0337 static void ScoreSchedReqYield_Pre_HomeSchedulerState_Prepare(
0338   ScoreSchedReqYield_Context               *ctx,
0339   ScoreSchedReqYield_Pre_HomeSchedulerState state
0340 )
0341 {
0342   switch ( state ) {
0343     case ScoreSchedReqYield_Pre_HomeSchedulerState_Blocked: {
0344       /*
0345        * The thread shall be blocked in its home scheduler.
0346        */
0347       ctx->ready = false;
0348       break;
0349     }
0350 
0351     case ScoreSchedReqYield_Pre_HomeSchedulerState_Scheduled: {
0352       /*
0353        * The thread shall be scheduled in its home scheduler.
0354        */
0355       ctx->ready = false;
0356       break;
0357     }
0358 
0359     case ScoreSchedReqYield_Pre_HomeSchedulerState_Ready: {
0360       /*
0361        * The thread shall be ready in its home scheduler.
0362        */
0363       ctx->ready = true;
0364       break;
0365     }
0366 
0367     case ScoreSchedReqYield_Pre_HomeSchedulerState_NA:
0368       break;
0369   }
0370 }
0371 
0372 static void ScoreSchedReqYield_Pre_Sticky_Prepare(
0373   ScoreSchedReqYield_Context   *ctx,
0374   ScoreSchedReqYield_Pre_Sticky state
0375 )
0376 {
0377   switch ( state ) {
0378     case ScoreSchedReqYield_Pre_Sticky_Yes: {
0379       /*
0380        * While the thread is sticky.
0381        */
0382       ctx->sticky = true;
0383       break;
0384     }
0385 
0386     case ScoreSchedReqYield_Pre_Sticky_No: {
0387       /*
0388        * While the thread not sticky.
0389        */
0390       ctx->sticky = false;
0391       break;
0392     }
0393 
0394     case ScoreSchedReqYield_Pre_Sticky_NA:
0395       break;
0396   }
0397 }
0398 
0399 static void ScoreSchedReqYield_Pre_Other_Prepare(
0400   ScoreSchedReqYield_Context  *ctx,
0401   ScoreSchedReqYield_Pre_Other state
0402 )
0403 {
0404   switch ( state ) {
0405     case ScoreSchedReqYield_Pre_Other_Yes: {
0406       /*
0407        * While at least one ready thread with a priority equal to the priority
0408        * of the thread exists in the home scheduler of the thread.
0409        */
0410       ctx->other_ready = true;
0411       break;
0412     }
0413 
0414     case ScoreSchedReqYield_Pre_Other_No: {
0415       /*
0416        * While no ready thread with a priority equal to the priority of the
0417        * thread exists in the home scheduler of the thread.
0418        */
0419       ctx->other_ready = false;
0420       break;
0421     }
0422 
0423     case ScoreSchedReqYield_Pre_Other_NA:
0424       break;
0425   }
0426 }
0427 
0428 static void ScoreSchedReqYield_Post_HomeSchedulerState_Check(
0429   ScoreSchedReqYield_Context                *ctx,
0430   ScoreSchedReqYield_Post_HomeSchedulerState state
0431 )
0432 {
0433   switch ( state ) {
0434     case ScoreSchedReqYield_Post_HomeSchedulerState_Blocked: {
0435       /*
0436        * The thread shall be blocked in its home scheduler.
0437        */
0438       T_true( ctx->is_idle_after_yield );
0439       T_eq_u32( ctx->cpu_after_yield, 1 );
0440       break;
0441     }
0442 
0443     case ScoreSchedReqYield_Post_HomeSchedulerState_Scheduled: {
0444       /*
0445        * The thread shall be scheduled in its home scheduler.
0446        */
0447       T_false( ctx->is_idle_before_yield );
0448       T_false( ctx->is_idle_after_yield );
0449       T_eq_u32( GetCounter( ctx ), 0 );
0450       T_eq_u32( ctx->cpu_after_yield, 0 );
0451       break;
0452     }
0453 
0454     case ScoreSchedReqYield_Post_HomeSchedulerState_Ready: {
0455       /*
0456        * The thread shall be ready in its home scheduler.
0457        */
0458       T_eq_u32( GetCounter( ctx ), 1 );
0459       break;
0460     }
0461 
0462     case ScoreSchedReqYield_Post_HomeSchedulerState_Idle: {
0463       /*
0464        * An idle thread shall execute on behalf of the thread in its home
0465        * scheduler.
0466        */
0467       T_true( ctx->is_idle_before_yield );
0468       T_true( ctx->is_idle_after_yield );
0469       T_eq_u32( GetCounter( ctx ), 0 );
0470       T_eq_u32( ctx->cpu_after_yield, 1 );
0471       break;
0472     }
0473 
0474     case ScoreSchedReqYield_Post_HomeSchedulerState_NA:
0475       break;
0476   }
0477 }
0478 
0479 static void ScoreSchedReqYield_Post_AskForHelp_Check(
0480   ScoreSchedReqYield_Context        *ctx,
0481   ScoreSchedReqYield_Post_AskForHelp state
0482 )
0483 {
0484   size_t                   index;
0485   const T_scheduler_event *event;
0486 
0487   index = 0;
0488 
0489   switch ( state ) {
0490     case ScoreSchedReqYield_Post_AskForHelp_Yes: {
0491       /*
0492        * The thread shall ask all its eligible scheduler for help.
0493        */
0494       event = TQGetNextAskForHelp( &ctx->tq_ctx, &index );
0495       T_eq_ptr( event->thread, ctx->tq_ctx.runner_tcb );
0496 
0497       event = TQGetNextAskForHelp( &ctx->tq_ctx, &index );
0498       T_eq_ptr( event->thread, ctx->tq_ctx.runner_tcb );
0499 
0500       event = TQGetNextAskForHelp( &ctx->tq_ctx, &index );
0501       T_eq_ptr( event, &T_scheduler_event_null );
0502       break;
0503     }
0504 
0505     case ScoreSchedReqYield_Post_AskForHelp_No: {
0506       /*
0507        * The thread shall not ask for help.
0508        */
0509       event = TQGetNextAskForHelp( &ctx->tq_ctx, &index );
0510       T_eq_ptr( event, &T_scheduler_event_null );
0511       break;
0512     }
0513 
0514     case ScoreSchedReqYield_Post_AskForHelp_NA:
0515       break;
0516   }
0517 }
0518 
0519 static void ScoreSchedReqYield_Setup( ScoreSchedReqYield_Context *ctx )
0520 {
0521   rtems_status_code sc;
0522 
0523   memset( ctx, 0, sizeof( *ctx ) );
0524   ctx->tq_ctx.enqueue_prepare = TQEnqueuePrepareDefault;
0525   ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
0526   ctx->tq_ctx.enqueue = TQEnqueueClassicSem;
0527   ctx->tq_ctx.surrender = TQSurrenderClassicSem;
0528   ctx->tq_ctx.convert_status = TQConvertStatusClassic;
0529   TQInitialize( &ctx->tq_ctx );
0530 
0531   sc = rtems_semaphore_create(
0532     rtems_build_name( 'M', 'U', 'T', 'X' ),
0533     1,
0534     RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
0535       RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
0536     PRIO_NORMAL,
0537     &ctx->sticky_mutex
0538   );
0539   T_rsc_success( sc );
0540 
0541   TQSetPriority( &ctx->tq_ctx, COUNTER, PRIO_NORMAL );
0542 
0543   #if defined(RTEMS_SMP)
0544   TQSetScheduler( &ctx->tq_ctx, HELPER, SCHEDULER_B_ID, PRIO_NORMAL );
0545   TQSetPriority( &ctx->tq_ctx, MOVER, PRIO_HIGH );
0546   #endif
0547 }
0548 
0549 static void ScoreSchedReqYield_Setup_Wrap( void *arg )
0550 {
0551   ScoreSchedReqYield_Context *ctx;
0552 
0553   ctx = arg;
0554   ctx->Map.in_action_loop = false;
0555   ScoreSchedReqYield_Setup( ctx );
0556 }
0557 
0558 static void ScoreSchedReqYield_Teardown( ScoreSchedReqYield_Context *ctx )
0559 {
0560   TQDestroy( &ctx->tq_ctx );
0561   DeleteMutex( ctx->sticky_mutex );
0562 }
0563 
0564 static void ScoreSchedReqYield_Teardown_Wrap( void *arg )
0565 {
0566   ScoreSchedReqYield_Context *ctx;
0567 
0568   ctx = arg;
0569   ctx->Map.in_action_loop = false;
0570   ScoreSchedReqYield_Teardown( ctx );
0571 }
0572 
0573 static void ScoreSchedReqYield_Action( ScoreSchedReqYield_Context *ctx )
0574 {
0575   const Per_CPU_Control *cpu;
0576   bool                   other_busy;
0577 
0578   if ( ctx->has_helping ) {
0579     TQMutexObtain( &ctx->tq_ctx, TQ_MUTEX_A );
0580     TQSendAndWaitForExecutionStop(
0581       &ctx->tq_ctx,
0582       HELPER,
0583       TQ_EVENT_MUTEX_A_OBTAIN
0584     );
0585   }
0586 
0587   if ( ctx->use_helping ) {
0588     MoveToHelping( ctx );
0589   }
0590 
0591   TQResetCounter( &ctx->tq_ctx );
0592 
0593   if ( ctx->use_helping && ctx->ready ) {
0594     ctx->tq_ctx.busy_wait[ COUNTER ] = true;
0595     TQSend( &ctx->tq_ctx, COUNTER, TQ_EVENT_COUNT | TQ_EVENT_BUSY_WAIT );
0596     other_busy = true;
0597   } else {
0598     other_busy = false;
0599   }
0600 
0601   if ( ctx->sticky ) {
0602     ObtainMutex( ctx->sticky_mutex );
0603   }
0604 
0605   if ( ctx->other_ready && !other_busy ) {
0606     TQSend( &ctx->tq_ctx, COUNTER, TQ_EVENT_COUNT );
0607   }
0608 
0609   cpu = _Per_CPU_Get_by_index( 0 );
0610   ctx->is_idle_before_yield = cpu->heir->is_idle;
0611 
0612   TQSchedulerRecordStart( &ctx->tq_ctx );
0613   Yield();
0614   TQSchedulerRecordStop( &ctx->tq_ctx );
0615 
0616   #if defined(RTEMS_SMP)
0617   ctx->tq_ctx.busy_wait[ COUNTER ] = false;
0618 
0619   while ( cpu->heir == ctx->tq_ctx.worker_tcb[ COUNTER ] ) {
0620     RTEMS_COMPILER_MEMORY_BARRIER();
0621   }
0622   #endif
0623 
0624   ctx->is_idle_after_yield = cpu->heir->is_idle;
0625   ctx->cpu_after_yield = rtems_scheduler_get_processor();
0626 
0627   if ( ctx->sticky ) {
0628     ReleaseMutex( ctx->sticky_mutex );
0629   }
0630 
0631   if ( ctx->has_helping ) {
0632     TQMutexRelease( &ctx->tq_ctx, TQ_MUTEX_A );
0633     TQSendAndWaitForExecutionStop(
0634       &ctx->tq_ctx,
0635       HELPER,
0636       TQ_EVENT_MUTEX_A_RELEASE
0637     );
0638   }
0639 }
0640 
0641 static const ScoreSchedReqYield_Entry
0642 ScoreSchedReqYield_Entries[] = {
0643 #if !defined(RTEMS_SMP)
0644   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0645     ScoreSchedReqYield_Post_AskForHelp_NA },
0646 #else
0647   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0648     ScoreSchedReqYield_Post_AskForHelp_NA },
0649 #endif
0650   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0651     ScoreSchedReqYield_Post_AskForHelp_NA },
0652   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0653     ScoreSchedReqYield_Post_AskForHelp_NA },
0654 #if !defined(RTEMS_SMP)
0655   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0656     ScoreSchedReqYield_Post_AskForHelp_NA },
0657 #else
0658   { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Ready,
0659     ScoreSchedReqYield_Post_AskForHelp_No },
0660 #endif
0661 #if !defined(RTEMS_SMP)
0662   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0663     ScoreSchedReqYield_Post_AskForHelp_NA },
0664 #else
0665   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0666     ScoreSchedReqYield_Post_AskForHelp_NA },
0667 #endif
0668 #if !defined(RTEMS_SMP)
0669   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0670     ScoreSchedReqYield_Post_AskForHelp_NA },
0671 #else
0672   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0673     ScoreSchedReqYield_Post_AskForHelp_NA },
0674 #endif
0675 #if !defined(RTEMS_SMP)
0676   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0677     ScoreSchedReqYield_Post_AskForHelp_NA },
0678 #else
0679   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0680     ScoreSchedReqYield_Post_AskForHelp_NA },
0681 #endif
0682 #if !defined(RTEMS_SMP)
0683   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0684     ScoreSchedReqYield_Post_AskForHelp_NA },
0685 #else
0686   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0687     ScoreSchedReqYield_Post_AskForHelp_NA },
0688 #endif
0689 #if !defined(RTEMS_SMP)
0690   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0691     ScoreSchedReqYield_Post_AskForHelp_NA },
0692 #else
0693   { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Scheduled,
0694     ScoreSchedReqYield_Post_AskForHelp_No },
0695 #endif
0696 #if !defined(RTEMS_SMP)
0697   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0698     ScoreSchedReqYield_Post_AskForHelp_NA },
0699 #else
0700   { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Blocked,
0701     ScoreSchedReqYield_Post_AskForHelp_No },
0702 #endif
0703   { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Ready,
0704     ScoreSchedReqYield_Post_AskForHelp_No },
0705   { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Scheduled,
0706     ScoreSchedReqYield_Post_AskForHelp_No },
0707 #if !defined(RTEMS_SMP)
0708   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0709     ScoreSchedReqYield_Post_AskForHelp_NA },
0710 #else
0711   { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Ready,
0712     ScoreSchedReqYield_Post_AskForHelp_Yes },
0713 #endif
0714 #if !defined(RTEMS_SMP)
0715   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0716     ScoreSchedReqYield_Post_AskForHelp_NA },
0717 #else
0718   { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Ready,
0719     ScoreSchedReqYield_Post_AskForHelp_Yes },
0720 #endif
0721 #if !defined(RTEMS_SMP)
0722   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0723     ScoreSchedReqYield_Post_AskForHelp_NA },
0724 #else
0725   { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Scheduled,
0726     ScoreSchedReqYield_Post_AskForHelp_No },
0727 #endif
0728 #if !defined(RTEMS_SMP)
0729   { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
0730     ScoreSchedReqYield_Post_AskForHelp_NA }
0731 #else
0732   { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Idle,
0733     ScoreSchedReqYield_Post_AskForHelp_No }
0734 #endif
0735 };
0736 
0737 static const uint8_t
0738 ScoreSchedReqYield_Map[] = {
0739   0, 0, 2, 2, 3, 8, 10, 11, 0, 0, 2, 2, 4, 4, 1, 1, 5, 5, 1, 1, 5, 5, 1, 1, 0,
0740   0, 6, 6, 12, 8, 13, 14, 0, 0, 6, 6, 4, 4, 9, 9, 3, 15, 7, 7, 3, 3, 7, 7
0741 };
0742 
0743 static size_t ScoreSchedReqYield_Scope( void *arg, char *buf, size_t n )
0744 {
0745   ScoreSchedReqYield_Context *ctx;
0746 
0747   ctx = arg;
0748 
0749   if ( ctx->Map.in_action_loop ) {
0750     return T_get_scope( ScoreSchedReqYield_PreDesc, buf, n, ctx->Map.pcs );
0751   }
0752 
0753   return 0;
0754 }
0755 
0756 static T_fixture ScoreSchedReqYield_Fixture = {
0757   .setup = ScoreSchedReqYield_Setup_Wrap,
0758   .stop = NULL,
0759   .teardown = ScoreSchedReqYield_Teardown_Wrap,
0760   .scope = ScoreSchedReqYield_Scope,
0761   .initial_context = &ScoreSchedReqYield_Instance
0762 };
0763 
0764 static inline ScoreSchedReqYield_Entry ScoreSchedReqYield_PopEntry(
0765   ScoreSchedReqYield_Context *ctx
0766 )
0767 {
0768   size_t index;
0769 
0770   index = ctx->Map.index;
0771   ctx->Map.index = index + 1;
0772   return ScoreSchedReqYield_Entries[
0773     ScoreSchedReqYield_Map[ index ]
0774   ];
0775 }
0776 
0777 static void ScoreSchedReqYield_TestVariant( ScoreSchedReqYield_Context *ctx )
0778 {
0779   ScoreSchedReqYield_Pre_EligibleScheduler_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0780   ScoreSchedReqYield_Pre_UsedScheduler_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0781   ScoreSchedReqYield_Pre_HomeSchedulerState_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0782   ScoreSchedReqYield_Pre_Sticky_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0783   ScoreSchedReqYield_Pre_Other_Prepare( ctx, ctx->Map.pcs[ 4 ] );
0784   ScoreSchedReqYield_Action( ctx );
0785   ScoreSchedReqYield_Post_HomeSchedulerState_Check(
0786     ctx,
0787     ctx->Map.entry.Post_HomeSchedulerState
0788   );
0789   ScoreSchedReqYield_Post_AskForHelp_Check(
0790     ctx,
0791     ctx->Map.entry.Post_AskForHelp
0792   );
0793 }
0794 
0795 /**
0796  * @fn void T_case_body_ScoreSchedReqYield( void )
0797  */
0798 T_TEST_CASE_FIXTURE( ScoreSchedReqYield, &ScoreSchedReqYield_Fixture )
0799 {
0800   ScoreSchedReqYield_Context *ctx;
0801 
0802   ctx = T_fixture_context();
0803   ctx->Map.in_action_loop = true;
0804   ctx->Map.index = 0;
0805 
0806   for (
0807     ctx->Map.pcs[ 0 ] = ScoreSchedReqYield_Pre_EligibleScheduler_Home;
0808     ctx->Map.pcs[ 0 ] < ScoreSchedReqYield_Pre_EligibleScheduler_NA;
0809     ++ctx->Map.pcs[ 0 ]
0810   ) {
0811     for (
0812       ctx->Map.pcs[ 1 ] = ScoreSchedReqYield_Pre_UsedScheduler_Home;
0813       ctx->Map.pcs[ 1 ] < ScoreSchedReqYield_Pre_UsedScheduler_NA;
0814       ++ctx->Map.pcs[ 1 ]
0815     ) {
0816       for (
0817         ctx->Map.pcs[ 2 ] = ScoreSchedReqYield_Pre_HomeSchedulerState_Blocked;
0818         ctx->Map.pcs[ 2 ] < ScoreSchedReqYield_Pre_HomeSchedulerState_NA;
0819         ++ctx->Map.pcs[ 2 ]
0820       ) {
0821         for (
0822           ctx->Map.pcs[ 3 ] = ScoreSchedReqYield_Pre_Sticky_Yes;
0823           ctx->Map.pcs[ 3 ] < ScoreSchedReqYield_Pre_Sticky_NA;
0824           ++ctx->Map.pcs[ 3 ]
0825         ) {
0826           for (
0827             ctx->Map.pcs[ 4 ] = ScoreSchedReqYield_Pre_Other_Yes;
0828             ctx->Map.pcs[ 4 ] < ScoreSchedReqYield_Pre_Other_NA;
0829             ++ctx->Map.pcs[ 4 ]
0830           ) {
0831             ctx->Map.entry = ScoreSchedReqYield_PopEntry( ctx );
0832 
0833             if ( ctx->Map.entry.Skip ) {
0834               continue;
0835             }
0836 
0837             ScoreSchedReqYield_TestVariant( ctx );
0838           }
0839         }
0840       }
0841     }
0842   }
0843 }
0844 
0845 /** @} */