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 ScoreMtxReqSurrender
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-mtx-surrender.h"
0056 #include "tr-tq-surrender-priority-inherit.h"
0057 #include "tr-tq-surrender.h"
0058 
0059 #include <rtems/test.h>
0060 
0061 /**
0062  * @defgroup ScoreMtxReqSurrender spec:/score/mtx/req/surrender
0063  *
0064  * @ingroup TestsuitesValidationNoClock0
0065  *
0066  * @{
0067  */
0068 
0069 typedef struct {
0070   uint32_t Skip : 1;
0071   uint32_t Pre_Protocol_NA : 1;
0072   uint32_t Pre_Discipline_NA : 1;
0073   uint32_t Pre_Recursive_NA : 1;
0074   uint32_t Pre_OwnerCheck_NA : 1;
0075   uint32_t Pre_Owner_NA : 1;
0076   uint32_t Pre_Nested_NA : 1;
0077   uint32_t Pre_Blocked_NA : 1;
0078   uint32_t Pre_Priority_NA : 1;
0079   uint32_t Post_Status : 2;
0080   uint32_t Post_Owner : 3;
0081   uint32_t Post_Surrender : 3;
0082   uint32_t Post_Priority : 2;
0083 } ScoreMtxReqSurrender_Entry;
0084 
0085 /**
0086  * @brief Test context for spec:/score/mtx/req/surrender test case.
0087  */
0088 typedef struct {
0089   /**
0090    * @brief If this member is true, then the calling thread shall be the owner
0091    *   of the mutex.
0092    */
0093   bool owner_caller;
0094 
0095   /**
0096    * @brief If this member is true, then a thread other than the calling thread
0097    *   shall be the owner of the mutex.
0098    */
0099   bool owner_other;
0100 
0101   /**
0102    * @brief If this member is true, then the calling thread shall have seized
0103    *   the mutex recursively.
0104    */
0105   bool nested;
0106 
0107   /**
0108    * @brief If this member is true, then there shall be a thread blocked
0109    *   waiting for the mutex.
0110    */
0111   bool blocked;
0112 
0113   /**
0114    * @brief This member contains the real priority of the calling thread.
0115    */
0116   rtems_task_priority priority_real;
0117 
0118   /**
0119    * @brief This member contains the current priority of the calling thread
0120    *   before the directive call.
0121    */
0122   rtems_task_priority priority_before;
0123 
0124   /**
0125    * @brief This member contains the return status of the directive call.
0126    */
0127   Status_Control status;
0128 
0129   /**
0130    * @brief This member contains the owner of the mutex after the directive
0131    *   call.
0132    */
0133   const rtems_tcb *owner_after;
0134 
0135   /**
0136    * @brief This member contains the current priority of the calling thread
0137    *   after the directive call.
0138    */
0139   rtems_task_priority priority_after;
0140 
0141   /**
0142    * @brief This member contains the counter snapshot after the directive call.
0143    */
0144   uint32_t counter;
0145 
0146   /**
0147    * @brief This member contains a copy of the corresponding
0148    *   ScoreMtxReqSurrender_Run() parameter.
0149    */
0150   TQMtxContext *tq_ctx;
0151 
0152   struct {
0153     /**
0154      * @brief This member defines the pre-condition indices for the next
0155      *   action.
0156      */
0157     size_t pci[ 8 ];
0158 
0159     /**
0160      * @brief This member defines the pre-condition states for the next action.
0161      */
0162     size_t pcs[ 8 ];
0163 
0164     /**
0165      * @brief If this member is true, then the test action loop is executed.
0166      */
0167     bool in_action_loop;
0168 
0169     /**
0170      * @brief This member contains the next transition map index.
0171      */
0172     size_t index;
0173 
0174     /**
0175      * @brief This member contains the current transition map entry.
0176      */
0177     ScoreMtxReqSurrender_Entry entry;
0178 
0179     /**
0180      * @brief If this member is true, then the current transition variant
0181      *   should be skipped.
0182      */
0183     bool skip;
0184   } Map;
0185 } ScoreMtxReqSurrender_Context;
0186 
0187 static ScoreMtxReqSurrender_Context
0188   ScoreMtxReqSurrender_Instance;
0189 
0190 static const char * const ScoreMtxReqSurrender_PreDesc_Protocol[] = {
0191   "None",
0192   "Inherit",
0193   "Ceiling",
0194   "MrsP",
0195   "NA"
0196 };
0197 
0198 static const char * const ScoreMtxReqSurrender_PreDesc_Discipline[] = {
0199   "FIFO",
0200   "Priority",
0201   "NA"
0202 };
0203 
0204 static const char * const ScoreMtxReqSurrender_PreDesc_Recursive[] = {
0205   "Allowed",
0206   "NotAllowed",
0207   "NA"
0208 };
0209 
0210 static const char * const ScoreMtxReqSurrender_PreDesc_OwnerCheck[] = {
0211   "Yes",
0212   "No",
0213   "NA"
0214 };
0215 
0216 static const char * const ScoreMtxReqSurrender_PreDesc_Owner[] = {
0217   "None",
0218   "Caller",
0219   "Other",
0220   "NA"
0221 };
0222 
0223 static const char * const ScoreMtxReqSurrender_PreDesc_Nested[] = {
0224   "Yes",
0225   "No",
0226   "NA"
0227 };
0228 
0229 static const char * const ScoreMtxReqSurrender_PreDesc_Blocked[] = {
0230   "Yes",
0231   "No",
0232   "NA"
0233 };
0234 
0235 static const char * const ScoreMtxReqSurrender_PreDesc_Priority[] = {
0236   "High",
0237   "Equal",
0238   "Low",
0239   "NA"
0240 };
0241 
0242 static const char * const * const ScoreMtxReqSurrender_PreDesc[] = {
0243   ScoreMtxReqSurrender_PreDesc_Protocol,
0244   ScoreMtxReqSurrender_PreDesc_Discipline,
0245   ScoreMtxReqSurrender_PreDesc_Recursive,
0246   ScoreMtxReqSurrender_PreDesc_OwnerCheck,
0247   ScoreMtxReqSurrender_PreDesc_Owner,
0248   ScoreMtxReqSurrender_PreDesc_Nested,
0249   ScoreMtxReqSurrender_PreDesc_Blocked,
0250   ScoreMtxReqSurrender_PreDesc_Priority,
0251   NULL
0252 };
0253 
0254 #if defined(RTEMS_SMP)
0255 #include "tr-tq-surrender-mrsp.h"
0256 #endif
0257 
0258 typedef ScoreMtxReqSurrender_Context Context;
0259 
0260 static Status_Control Status( const Context *ctx, Status_Control status )
0261 {
0262   return TQConvertStatus( &ctx->tq_ctx->base, status );
0263 }
0264 
0265 static void Action( Context *ctx )
0266 {
0267   Status_Control status;
0268 
0269   TQSetScheduler(
0270     &ctx->tq_ctx->base,
0271     TQ_HELPER_A,
0272     SCHEDULER_A_ID,
0273     PRIO_VERY_HIGH
0274   );
0275   TQSetScheduler(
0276     &ctx->tq_ctx->base,
0277     TQ_BLOCKER_A,
0278     SCHEDULER_A_ID,
0279     PRIO_VERY_HIGH
0280   );
0281 
0282   if ( ctx->owner_caller ) {
0283     status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT );
0284     T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
0285   } else if ( ctx->owner_other ) {
0286     TQSend( &ctx->tq_ctx->base, TQ_HELPER_A, TQ_EVENT_ENQUEUE );
0287   }
0288 
0289   if ( ctx->nested ) {
0290     status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT );
0291     T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
0292   }
0293 
0294   if ( ctx->blocked ) {
0295     TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
0296     Yield();
0297   }
0298 
0299   TQResetCounter( &ctx->tq_ctx->base );
0300   SetSelfPriority( ctx->priority_real );
0301   ctx->priority_before = GetSelfPriority();
0302   TQSchedulerRecordStart( &ctx->tq_ctx->base );
0303   ctx->status = TQSurrender( &ctx->tq_ctx->base );
0304   TQSchedulerRecordStop( &ctx->tq_ctx->base );
0305   ctx->owner_after = TQGetOwner( &ctx->tq_ctx->base );
0306   ctx->priority_after = GetSelfPriority();
0307   SetSelfPriority( PRIO_NORMAL );
0308   Yield();
0309   ctx->counter = TQGetCounter( &ctx->tq_ctx->base );
0310 
0311   if ( ctx->nested ) {
0312     status = TQSurrender( &ctx->tq_ctx->base );
0313     T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
0314   }
0315 
0316   if ( ctx->owner_other ) {
0317     TQSend( &ctx->tq_ctx->base, TQ_HELPER_A, TQ_EVENT_SURRENDER );
0318   }
0319 
0320   if ( ctx->blocked ) {
0321     TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
0322   }
0323 }
0324 
0325 static void ActionSticky( Context *ctx )
0326 {
0327   Status_Control status;
0328 
0329   TQSetScheduler(
0330     &ctx->tq_ctx->base,
0331     TQ_HELPER_A,
0332     SCHEDULER_A_ID,
0333     PRIO_VERY_HIGH
0334   );
0335   TQSetScheduler(
0336     &ctx->tq_ctx->base,
0337     TQ_BLOCKER_A,
0338     SCHEDULER_B_ID,
0339     PRIO_VERY_HIGH
0340   );
0341 
0342   if ( ctx->owner_caller ) {
0343     status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT );
0344     T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
0345   } else if ( ctx->owner_other ) {
0346     SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
0347     TQSendAndSynchronizeRunner(
0348       &ctx->tq_ctx->base,
0349       TQ_HELPER_A,
0350       TQ_EVENT_ENQUEUE
0351     );
0352     SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
0353   }
0354 
0355   if ( ctx->nested ) {
0356     status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT );
0357     T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
0358   }
0359 
0360   if ( ctx->blocked ) {
0361     TQSendAndWaitForIntendToBlock(
0362       &ctx->tq_ctx->base,
0363       TQ_BLOCKER_A,
0364       TQ_EVENT_ENQUEUE
0365     );
0366   }
0367 
0368   TQResetCounter( &ctx->tq_ctx->base );
0369   SetSelfPriority( ctx->priority_real );
0370   ctx->priority_before = GetSelfPriority();
0371   TQSchedulerRecordStart( &ctx->tq_ctx->base );
0372   ctx->status = TQSurrender( &ctx->tq_ctx->base );
0373   TQSchedulerRecordStop( &ctx->tq_ctx->base );
0374   ctx->owner_after = TQGetOwner( &ctx->tq_ctx->base );
0375   ctx->priority_after = GetSelfPriority();
0376 
0377   if ( ctx->status == Status( ctx, STATUS_SUCCESSFUL ) ) {
0378     TQWaitForExecutionStop( &ctx->tq_ctx->base, TQ_BLOCKER_A );
0379   }
0380 
0381   ctx->counter = TQGetCounter( &ctx->tq_ctx->base );
0382 
0383   if ( ctx->nested ) {
0384     status = TQSurrender( &ctx->tq_ctx->base );
0385     T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
0386   }
0387 
0388   if ( ctx->owner_other ) {
0389     SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
0390     TQSendAndSynchronizeRunner(
0391       &ctx->tq_ctx->base,
0392       TQ_HELPER_A,
0393       TQ_EVENT_SURRENDER
0394     );
0395     SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
0396   } else {
0397     SetSelfPriority( PRIO_NORMAL );
0398   }
0399 
0400   if ( ctx->blocked ) {
0401     TQSendAndSynchronizeRunner(
0402       &ctx->tq_ctx->base,
0403       TQ_BLOCKER_A,
0404       TQ_EVENT_SURRENDER
0405     );
0406   }
0407 }
0408 
0409 static void ScoreMtxReqSurrender_Pre_Protocol_Prepare(
0410   ScoreMtxReqSurrender_Context     *ctx,
0411   ScoreMtxReqSurrender_Pre_Protocol state
0412 )
0413 {
0414   switch ( state ) {
0415     case ScoreMtxReqSurrender_Pre_Protocol_None: {
0416       /*
0417        * Where the mutex does not use a locking protocol.
0418        */
0419       if ( ctx->tq_ctx->protocol != TQ_MTX_NO_PROTOCOL ) {
0420         ctx->Map.skip = true;
0421       }
0422       break;
0423     }
0424 
0425     case ScoreMtxReqSurrender_Pre_Protocol_Inherit: {
0426       /*
0427        * Where the mutex uses the priority inheritance locking protocol.
0428        */
0429       if ( ctx->tq_ctx->protocol != TQ_MTX_PRIORITY_INHERIT ) {
0430         ctx->Map.skip = true;
0431       }
0432       break;
0433     }
0434 
0435     case ScoreMtxReqSurrender_Pre_Protocol_Ceiling: {
0436       /*
0437        * Where the mutex uses the priority ceiling locking protocol.
0438        */
0439       if ( ctx->tq_ctx->protocol != TQ_MTX_PRIORITY_CEILING ) {
0440         ctx->Map.skip = true;
0441       }
0442       break;
0443     }
0444 
0445     case ScoreMtxReqSurrender_Pre_Protocol_MrsP: {
0446       /*
0447        * Where the mutex uses the MrsP locking protocol.
0448        */
0449       if ( ctx->tq_ctx->protocol != TQ_MTX_MRSP ) {
0450         ctx->Map.skip = true;
0451       }
0452       break;
0453     }
0454 
0455     case ScoreMtxReqSurrender_Pre_Protocol_NA:
0456       break;
0457   }
0458 }
0459 
0460 static void ScoreMtxReqSurrender_Pre_Discipline_Prepare(
0461   ScoreMtxReqSurrender_Context       *ctx,
0462   ScoreMtxReqSurrender_Pre_Discipline state
0463 )
0464 {
0465   switch ( state ) {
0466     case ScoreMtxReqSurrender_Pre_Discipline_FIFO: {
0467       /*
0468        * Where the thread queue of the mutex uses the FIFO discipline.
0469        */
0470       if ( ctx->tq_ctx->base.discipline != TQ_FIFO ) {
0471         ctx->Map.skip = true;
0472       }
0473       break;
0474     }
0475 
0476     case ScoreMtxReqSurrender_Pre_Discipline_Priority: {
0477       /*
0478        * Where the thread queue of the mutex uses the priority discipline.
0479        */
0480       if ( ctx->tq_ctx->base.discipline != TQ_PRIORITY ) {
0481         ctx->Map.skip = true;
0482       }
0483       break;
0484     }
0485 
0486     case ScoreMtxReqSurrender_Pre_Discipline_NA:
0487       break;
0488   }
0489 }
0490 
0491 static void ScoreMtxReqSurrender_Pre_Recursive_Prepare(
0492   ScoreMtxReqSurrender_Context      *ctx,
0493   ScoreMtxReqSurrender_Pre_Recursive state
0494 )
0495 {
0496   switch ( state ) {
0497     case ScoreMtxReqSurrender_Pre_Recursive_Allowed: {
0498       /*
0499        * Where a recursive seize of the mutex is allowed.
0500        */
0501       if ( ctx->tq_ctx->recursive != TQ_MTX_RECURSIVE_ALLOWED ) {
0502         ctx->Map.skip = true;
0503       }
0504       break;
0505     }
0506 
0507     case ScoreMtxReqSurrender_Pre_Recursive_NotAllowed: {
0508       /*
0509        * Where a recursive seize of the mutex is not allowed.
0510        */
0511       if ( ctx->tq_ctx->recursive == TQ_MTX_RECURSIVE_ALLOWED ) {
0512         ctx->Map.skip = true;
0513       }
0514       break;
0515     }
0516 
0517     case ScoreMtxReqSurrender_Pre_Recursive_NA:
0518       break;
0519   }
0520 }
0521 
0522 static void ScoreMtxReqSurrender_Pre_OwnerCheck_Prepare(
0523   ScoreMtxReqSurrender_Context       *ctx,
0524   ScoreMtxReqSurrender_Pre_OwnerCheck state
0525 )
0526 {
0527   switch ( state ) {
0528     case ScoreMtxReqSurrender_Pre_OwnerCheck_Yes: {
0529       /*
0530        * Where the surrender checks that the mutex owner is the calling thread.
0531        */
0532       if ( ctx->tq_ctx->owner_check != TQ_MTX_CHECKS_OWNER ) {
0533         ctx->Map.skip = true;
0534       }
0535       break;
0536     }
0537 
0538     case ScoreMtxReqSurrender_Pre_OwnerCheck_No: {
0539       /*
0540        * Where the surrender does not check that the mutex owner is the calling
0541        * thread.
0542        */
0543       if ( ctx->tq_ctx->owner_check != TQ_MTX_NO_OWNER_CHECK ) {
0544         ctx->Map.skip = true;
0545       }
0546       break;
0547     }
0548 
0549     case ScoreMtxReqSurrender_Pre_OwnerCheck_NA:
0550       break;
0551   }
0552 }
0553 
0554 static void ScoreMtxReqSurrender_Pre_Owner_Prepare(
0555   ScoreMtxReqSurrender_Context  *ctx,
0556   ScoreMtxReqSurrender_Pre_Owner state
0557 )
0558 {
0559   switch ( state ) {
0560     case ScoreMtxReqSurrender_Pre_Owner_None: {
0561       /*
0562        * While the mutex has no owner.
0563        */
0564       ctx->owner_caller = false;
0565       ctx->owner_other = false;
0566       break;
0567     }
0568 
0569     case ScoreMtxReqSurrender_Pre_Owner_Caller: {
0570       /*
0571        * While the owner of the mutex is the calling thread.
0572        */
0573       ctx->owner_caller = true;
0574       ctx->owner_other = false;
0575       break;
0576     }
0577 
0578     case ScoreMtxReqSurrender_Pre_Owner_Other: {
0579       /*
0580        * While the owner of the mutex is a thread other than the calling
0581        * thread.
0582        */
0583       ctx->owner_caller = false;
0584       ctx->owner_other = true;
0585       break;
0586     }
0587 
0588     case ScoreMtxReqSurrender_Pre_Owner_NA:
0589       break;
0590   }
0591 }
0592 
0593 static void ScoreMtxReqSurrender_Pre_Nested_Prepare(
0594   ScoreMtxReqSurrender_Context   *ctx,
0595   ScoreMtxReqSurrender_Pre_Nested state
0596 )
0597 {
0598   switch ( state ) {
0599     case ScoreMtxReqSurrender_Pre_Nested_Yes: {
0600       /*
0601        * While calling thread seized the mutex recursively.
0602        */
0603       ctx->nested = true;
0604       break;
0605     }
0606 
0607     case ScoreMtxReqSurrender_Pre_Nested_No: {
0608       /*
0609        * While calling thread seized the mutex not recursively.
0610        */
0611       ctx->nested = false;
0612       break;
0613     }
0614 
0615     case ScoreMtxReqSurrender_Pre_Nested_NA:
0616       break;
0617   }
0618 }
0619 
0620 static void ScoreMtxReqSurrender_Pre_Blocked_Prepare(
0621   ScoreMtxReqSurrender_Context    *ctx,
0622   ScoreMtxReqSurrender_Pre_Blocked state
0623 )
0624 {
0625   switch ( state ) {
0626     case ScoreMtxReqSurrender_Pre_Blocked_Yes: {
0627       /*
0628        * While the mutex has threads blocked on the mutex.
0629        */
0630       ctx->blocked = true;
0631       break;
0632     }
0633 
0634     case ScoreMtxReqSurrender_Pre_Blocked_No: {
0635       /*
0636        * While no threads are blocked on the mutex.
0637        */
0638       ctx->blocked = false;
0639       break;
0640     }
0641 
0642     case ScoreMtxReqSurrender_Pre_Blocked_NA:
0643       break;
0644   }
0645 }
0646 
0647 static void ScoreMtxReqSurrender_Pre_Priority_Prepare(
0648   ScoreMtxReqSurrender_Context     *ctx,
0649   ScoreMtxReqSurrender_Pre_Priority state
0650 )
0651 {
0652   switch ( state ) {
0653     case ScoreMtxReqSurrender_Pre_Priority_High: {
0654       /*
0655        * While the current priority of the calling thread without the
0656        * priorities available through the mutex would be higher than the
0657        * highest priority of the priorities available through the mutex.
0658        */
0659       ctx->priority_real = PRIO_ULTRA_HIGH;
0660       break;
0661     }
0662 
0663     case ScoreMtxReqSurrender_Pre_Priority_Equal: {
0664       /*
0665        * While the current priority of the calling thread without the
0666        * priorities available through the mutex would be equal to the highest
0667        * priority of the priorities available through the mutex.
0668        */
0669       ctx->priority_real = PRIO_VERY_HIGH;
0670       break;
0671     }
0672 
0673     case ScoreMtxReqSurrender_Pre_Priority_Low: {
0674       /*
0675        * While the current priority of the calling thread without the
0676        * priorities available through the mutex would be lower than the highest
0677        * priority of the priorities available through the mutex.
0678        */
0679       ctx->priority_real = PRIO_HIGH;
0680       break;
0681     }
0682 
0683     case ScoreMtxReqSurrender_Pre_Priority_NA:
0684       break;
0685   }
0686 }
0687 
0688 static void ScoreMtxReqSurrender_Post_Status_Check(
0689   ScoreMtxReqSurrender_Context    *ctx,
0690   ScoreMtxReqSurrender_Post_Status state
0691 )
0692 {
0693   switch ( state ) {
0694     case ScoreMtxReqSurrender_Post_Status_Ok: {
0695       /*
0696        * The return status of the directive call shall be derived from
0697        * STATUS_SUCCESSFUL.
0698        */
0699       T_eq_int( ctx->status, Status( ctx, STATUS_SUCCESSFUL ) );
0700       break;
0701     }
0702 
0703     case ScoreMtxReqSurrender_Post_Status_NotOwner: {
0704       /*
0705        * The return status of the directive call shall be derived from
0706        * STATUS_NOT_OWNER.
0707        */
0708       T_eq_int( ctx->status, Status( ctx, STATUS_NOT_OWNER ) );
0709       break;
0710     }
0711 
0712     case ScoreMtxReqSurrender_Post_Status_NA:
0713       break;
0714   }
0715 }
0716 
0717 static void ScoreMtxReqSurrender_Post_Owner_Check(
0718   ScoreMtxReqSurrender_Context   *ctx,
0719   ScoreMtxReqSurrender_Post_Owner state
0720 )
0721 {
0722   switch ( state ) {
0723     case ScoreMtxReqSurrender_Post_Owner_None: {
0724       /*
0725        * The mutex shall have no owner.
0726        */
0727       T_null( ctx->owner_after );
0728       break;
0729     }
0730 
0731     case ScoreMtxReqSurrender_Post_Owner_Caller: {
0732       /*
0733        * The owner of the mutex shall be the calling thread.
0734        */
0735       T_eq_ptr(
0736         ctx->owner_after,
0737         ctx->tq_ctx->base.runner_tcb
0738       );
0739       break;
0740     }
0741 
0742     case ScoreMtxReqSurrender_Post_Owner_Other: {
0743       /*
0744        * The owner of the mutex shall not be modified.
0745        */
0746       T_eq_ptr(
0747         ctx->owner_after,
0748         ctx->tq_ctx->base.worker_tcb[ TQ_HELPER_A ]
0749       );
0750       break;
0751     }
0752 
0753     case ScoreMtxReqSurrender_Post_Owner_First: {
0754       /*
0755        * The owner of the mutex shall be dequeued thread.
0756        */
0757       T_eq_ptr(
0758         ctx->owner_after,
0759         ctx->tq_ctx->base.worker_tcb[ TQ_BLOCKER_A ]
0760       );
0761       break;
0762     }
0763 
0764     case ScoreMtxReqSurrender_Post_Owner_NA:
0765       break;
0766   }
0767 }
0768 
0769 static void ScoreMtxReqSurrender_Post_Surrender_Check(
0770   ScoreMtxReqSurrender_Context       *ctx,
0771   ScoreMtxReqSurrender_Post_Surrender state
0772 )
0773 {
0774   switch ( state ) {
0775     case ScoreMtxReqSurrender_Post_Surrender_Nop: {
0776       /*
0777        * The thread queue of the mutex shall not be surrendered to a thread.
0778        */
0779       T_eq_u32( ctx->counter, 0 );
0780       break;
0781     }
0782 
0783     case ScoreMtxReqSurrender_Post_Surrender_FIFO: {
0784       /*
0785        * The thread queue of the mutex shall be surrendered in FIFO order.
0786        */
0787       T_eq_u32( ctx->counter, 1 );
0788       ScoreTqReqSurrender_Run( &ctx->tq_ctx->base );
0789       break;
0790     }
0791 
0792     case ScoreMtxReqSurrender_Post_Surrender_Priority: {
0793       /*
0794        * The thread queue of the mutex shall be surrendered in priority order.
0795        */
0796       T_eq_u32( ctx->counter, 1 );
0797       ScoreTqReqSurrender_Run( &ctx->tq_ctx->base );
0798       break;
0799     }
0800 
0801     case ScoreMtxReqSurrender_Post_Surrender_PriorityInherit: {
0802       /*
0803        * The thread queue of the mutex shall be surrendered in priority order
0804        * with priority inheritance.
0805        */
0806       T_eq_u32( ctx->counter, 1 );
0807       ScoreTqReqSurrenderPriorityInherit_Run( &ctx->tq_ctx->base );
0808       break;
0809     }
0810 
0811     case ScoreMtxReqSurrender_Post_Surrender_MrsP: {
0812       /*
0813        * The thread queue of the mutex shall be surrendered in priority order
0814        * with MrsP.
0815        */
0816       #if defined(RTEMS_SMP)
0817       T_eq_u32( ctx->counter, 1 );
0818       ScoreTqReqSurrenderMrsp_Run( &ctx->tq_ctx->base );
0819       #else
0820       T_unreachable();
0821       #endif
0822       break;
0823     }
0824 
0825     case ScoreMtxReqSurrender_Post_Surrender_NA:
0826       break;
0827   }
0828 }
0829 
0830 static void ScoreMtxReqSurrender_Post_Priority_Check(
0831   ScoreMtxReqSurrender_Context      *ctx,
0832   ScoreMtxReqSurrender_Post_Priority state
0833 )
0834 {
0835   switch ( state ) {
0836     case ScoreMtxReqSurrender_Post_Priority_Nop: {
0837       /*
0838        * The current priority of the calling thread shall be not be modified.
0839        */
0840       T_eq_u32( ctx->priority_after, ctx->priority_before );
0841       break;
0842     }
0843 
0844     case ScoreMtxReqSurrender_Post_Priority_Low: {
0845       /*
0846        * The current priority of the calling thread shall be lowered to reflect
0847        * the removal of the priorities available through the mutex.
0848        */
0849       T_eq_u32( ctx->priority_after, ctx->priority_real );
0850       break;
0851     }
0852 
0853     case ScoreMtxReqSurrender_Post_Priority_NA:
0854       break;
0855   }
0856 }
0857 
0858 static void ScoreMtxReqSurrender_Prepare( ScoreMtxReqSurrender_Context *ctx )
0859 {
0860   ctx->owner_caller = false;
0861   ctx->owner_other = false;
0862   ctx->nested = false;
0863   ctx->blocked = false;
0864 
0865   if ( ctx->tq_ctx->base.enqueue_variant == TQ_ENQUEUE_STICKY ) {
0866     ctx->priority_real = PRIO_ULTRA_HIGH;
0867   } else {
0868     ctx->priority_real = PRIO_NORMAL;
0869   }
0870 }
0871 
0872 static void ScoreMtxReqSurrender_Action( ScoreMtxReqSurrender_Context *ctx )
0873 {
0874   if ( ctx->tq_ctx->base.enqueue_variant == TQ_ENQUEUE_STICKY ) {
0875     ActionSticky( ctx );
0876   } else {
0877     Action( ctx );
0878   }
0879 }
0880 
0881 static const ScoreMtxReqSurrender_Entry
0882 ScoreMtxReqSurrender_Entries[] = {
0883   { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_NA,
0884     ScoreMtxReqSurrender_Post_Owner_NA, ScoreMtxReqSurrender_Post_Surrender_NA,
0885     ScoreMtxReqSurrender_Post_Priority_NA },
0886   { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_NA,
0887     ScoreMtxReqSurrender_Post_Owner_NA, ScoreMtxReqSurrender_Post_Surrender_NA,
0888     ScoreMtxReqSurrender_Post_Priority_NA },
0889   { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_NA,
0890     ScoreMtxReqSurrender_Post_Owner_NA, ScoreMtxReqSurrender_Post_Surrender_NA,
0891     ScoreMtxReqSurrender_Post_Priority_NA },
0892   { 0, 0, 0, 0, 0, 0, 1, 0, 1, ScoreMtxReqSurrender_Post_Status_NotOwner,
0893     ScoreMtxReqSurrender_Post_Owner_Other,
0894     ScoreMtxReqSurrender_Post_Surrender_Nop,
0895     ScoreMtxReqSurrender_Post_Priority_Nop },
0896   { 1, 0, 0, 0, 0, 0, 1, 0, 1, ScoreMtxReqSurrender_Post_Status_NA,
0897     ScoreMtxReqSurrender_Post_Owner_NA, ScoreMtxReqSurrender_Post_Surrender_NA,
0898     ScoreMtxReqSurrender_Post_Priority_NA },
0899   { 0, 0, 0, 0, 0, 0, 1, 0, 1, ScoreMtxReqSurrender_Post_Status_NotOwner,
0900     ScoreMtxReqSurrender_Post_Owner_None,
0901     ScoreMtxReqSurrender_Post_Surrender_Nop,
0902     ScoreMtxReqSurrender_Post_Priority_Nop },
0903   { 0, 0, 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSurrender_Post_Status_Ok,
0904     ScoreMtxReqSurrender_Post_Owner_None,
0905     ScoreMtxReqSurrender_Post_Surrender_Nop,
0906     ScoreMtxReqSurrender_Post_Priority_Nop },
0907   { 0, 0, 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSurrender_Post_Status_Ok,
0908     ScoreMtxReqSurrender_Post_Owner_Caller,
0909     ScoreMtxReqSurrender_Post_Surrender_Nop,
0910     ScoreMtxReqSurrender_Post_Priority_Nop },
0911   { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
0912     ScoreMtxReqSurrender_Post_Owner_Caller,
0913     ScoreMtxReqSurrender_Post_Surrender_Nop,
0914     ScoreMtxReqSurrender_Post_Priority_Nop },
0915   { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
0916     ScoreMtxReqSurrender_Post_Owner_None,
0917     ScoreMtxReqSurrender_Post_Surrender_Nop,
0918     ScoreMtxReqSurrender_Post_Priority_Nop },
0919   { 0, 0, 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSurrender_Post_Status_Ok,
0920     ScoreMtxReqSurrender_Post_Owner_First,
0921     ScoreMtxReqSurrender_Post_Surrender_FIFO,
0922     ScoreMtxReqSurrender_Post_Priority_Nop },
0923   { 0, 0, 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSurrender_Post_Status_Ok,
0924     ScoreMtxReqSurrender_Post_Owner_First,
0925     ScoreMtxReqSurrender_Post_Surrender_Priority,
0926     ScoreMtxReqSurrender_Post_Priority_Nop },
0927   { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
0928     ScoreMtxReqSurrender_Post_Owner_First,
0929     ScoreMtxReqSurrender_Post_Surrender_PriorityInherit,
0930     ScoreMtxReqSurrender_Post_Priority_Nop },
0931   { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
0932     ScoreMtxReqSurrender_Post_Owner_First,
0933     ScoreMtxReqSurrender_Post_Surrender_Priority,
0934     ScoreMtxReqSurrender_Post_Priority_Nop },
0935   { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
0936     ScoreMtxReqSurrender_Post_Owner_None,
0937     ScoreMtxReqSurrender_Post_Surrender_Nop,
0938     ScoreMtxReqSurrender_Post_Priority_Low },
0939   { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
0940     ScoreMtxReqSurrender_Post_Owner_First,
0941     ScoreMtxReqSurrender_Post_Surrender_MrsP,
0942     ScoreMtxReqSurrender_Post_Priority_Nop },
0943   { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
0944     ScoreMtxReqSurrender_Post_Owner_First,
0945     ScoreMtxReqSurrender_Post_Surrender_PriorityInherit,
0946     ScoreMtxReqSurrender_Post_Priority_Low },
0947   { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
0948     ScoreMtxReqSurrender_Post_Owner_First,
0949     ScoreMtxReqSurrender_Post_Surrender_Priority,
0950     ScoreMtxReqSurrender_Post_Priority_Low },
0951   { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
0952     ScoreMtxReqSurrender_Post_Owner_First,
0953     ScoreMtxReqSurrender_Post_Surrender_MrsP,
0954     ScoreMtxReqSurrender_Post_Priority_Low }
0955 };
0956 
0957 static const uint8_t
0958 ScoreMtxReqSurrender_Map[] = {
0959   4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 7, 7, 7, 7, 7, 7, 10, 10, 10, 6, 6, 6, 3,
0960   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7,
0961   7, 7, 7, 10, 10, 10, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
0962   2, 2, 4, 4, 4, 5, 5, 5, 2, 2, 2, 2, 2, 2, 10, 10, 10, 6, 6, 6, 2, 2, 2, 2, 2,
0963   2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
0964   10, 10, 10, 6, 6, 6, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 4, 4, 4, 5, 5, 5, 4,
0965   4, 4, 5, 5, 5, 7, 7, 7, 7, 7, 7, 11, 11, 11, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
0966   3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 11, 11, 11,
0967   6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 4, 4, 5, 5,
0968   5, 2, 2, 2, 2, 2, 2, 11, 11, 11, 6, 6, 6, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
0969   2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 11, 11, 11, 6, 6, 6, 2,
0970   2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0971   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0972   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0973   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0974   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0975   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
0976   4, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 8, 8, 8, 7, 7, 7, 12, 12, 16, 6, 6, 6, 3, 3,
0977   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 7,
0978   7, 7, 12, 12, 16, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
0979   2, 4, 4, 4, 5, 5, 5, 2, 2, 2, 2, 2, 2, 12, 12, 16, 6, 6, 6, 2, 2, 2, 2, 2, 2,
0980   3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 12,
0981   12, 16, 6, 6, 6, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0982   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0983   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0984   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0985   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0986   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0987   0, 0, 0, 0, 0, 0, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 8, 8, 8, 8, 8, 8, 13,
0988   13, 17, 9, 9, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1,
0989   1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 13, 13, 17, 9, 9, 14, 1, 1, 1, 1, 1, 1, 1, 1,
0990   1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 4, 4, 5, 5, 5, 2, 2, 2, 2, 2, 2, 13, 13, 17,
0991   9, 9, 14, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
0992   1, 1, 2, 2, 2, 2, 2, 2, 13, 13, 17, 9, 9, 14, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
0993   1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0994   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0995   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0996   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0997   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0998   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5,
0999   5, 5, 8, 8, 8, 8, 8, 8, 15, 15, 18, 9, 9, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1000   3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 15, 15, 18, 9, 9,
1001   14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 4, 4, 5, 5, 5,
1002   2, 2, 2, 2, 2, 2, 15, 15, 18, 9, 9, 14, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
1003   2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 15, 15, 18, 9, 9, 14,
1004   2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1
1005 };
1006 
1007 static size_t ScoreMtxReqSurrender_Scope( void *arg, char *buf, size_t n )
1008 {
1009   ScoreMtxReqSurrender_Context *ctx;
1010 
1011   ctx = arg;
1012 
1013   if ( ctx->Map.in_action_loop ) {
1014     return T_get_scope( ScoreMtxReqSurrender_PreDesc, buf, n, ctx->Map.pcs );
1015   }
1016 
1017   return 0;
1018 }
1019 
1020 static T_fixture ScoreMtxReqSurrender_Fixture = {
1021   .setup = NULL,
1022   .stop = NULL,
1023   .teardown = NULL,
1024   .scope = ScoreMtxReqSurrender_Scope,
1025   .initial_context = &ScoreMtxReqSurrender_Instance
1026 };
1027 
1028 static const uint16_t ScoreMtxReqSurrender_Weights[] = {
1029   288, 144, 72, 36, 12, 6, 3, 1
1030 };
1031 
1032 static void ScoreMtxReqSurrender_Skip(
1033   ScoreMtxReqSurrender_Context *ctx,
1034   size_t                        index
1035 )
1036 {
1037   switch ( index + 1 ) {
1038     case 1:
1039       ctx->Map.pci[ 1 ] = ScoreMtxReqSurrender_Pre_Discipline_NA - 1;
1040       /* Fall through */
1041     case 2:
1042       ctx->Map.pci[ 2 ] = ScoreMtxReqSurrender_Pre_Recursive_NA - 1;
1043       /* Fall through */
1044     case 3:
1045       ctx->Map.pci[ 3 ] = ScoreMtxReqSurrender_Pre_OwnerCheck_NA - 1;
1046       /* Fall through */
1047     case 4:
1048       ctx->Map.pci[ 4 ] = ScoreMtxReqSurrender_Pre_Owner_NA - 1;
1049       /* Fall through */
1050     case 5:
1051       ctx->Map.pci[ 5 ] = ScoreMtxReqSurrender_Pre_Nested_NA - 1;
1052       /* Fall through */
1053     case 6:
1054       ctx->Map.pci[ 6 ] = ScoreMtxReqSurrender_Pre_Blocked_NA - 1;
1055       /* Fall through */
1056     case 7:
1057       ctx->Map.pci[ 7 ] = ScoreMtxReqSurrender_Pre_Priority_NA - 1;
1058       break;
1059   }
1060 }
1061 
1062 static inline ScoreMtxReqSurrender_Entry ScoreMtxReqSurrender_PopEntry(
1063   ScoreMtxReqSurrender_Context *ctx
1064 )
1065 {
1066   size_t index;
1067 
1068   if ( ctx->Map.skip ) {
1069     size_t i;
1070 
1071     ctx->Map.skip = false;
1072     index = 0;
1073 
1074     for ( i = 0; i < 8; ++i ) {
1075       index += ScoreMtxReqSurrender_Weights[ i ] * ctx->Map.pci[ i ];
1076     }
1077   } else {
1078     index = ctx->Map.index;
1079   }
1080 
1081   ctx->Map.index = index + 1;
1082 
1083   return ScoreMtxReqSurrender_Entries[
1084     ScoreMtxReqSurrender_Map[ index ]
1085   ];
1086 }
1087 
1088 static void ScoreMtxReqSurrender_SetPreConditionStates(
1089   ScoreMtxReqSurrender_Context *ctx
1090 )
1091 {
1092   ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
1093   ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
1094   ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
1095   ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
1096   ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
1097 
1098   if ( ctx->Map.entry.Pre_Nested_NA ) {
1099     ctx->Map.pcs[ 5 ] = ScoreMtxReqSurrender_Pre_Nested_NA;
1100   } else {
1101     ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
1102   }
1103 
1104   ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ];
1105 
1106   if ( ctx->Map.entry.Pre_Priority_NA ) {
1107     ctx->Map.pcs[ 7 ] = ScoreMtxReqSurrender_Pre_Priority_NA;
1108   } else {
1109     ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ];
1110   }
1111 }
1112 
1113 static void ScoreMtxReqSurrender_TestVariant(
1114   ScoreMtxReqSurrender_Context *ctx
1115 )
1116 {
1117   ScoreMtxReqSurrender_Pre_Protocol_Prepare( ctx, ctx->Map.pcs[ 0 ] );
1118 
1119   if ( ctx->Map.skip ) {
1120     ScoreMtxReqSurrender_Skip( ctx, 0 );
1121     return;
1122   }
1123 
1124   ScoreMtxReqSurrender_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
1125 
1126   if ( ctx->Map.skip ) {
1127     ScoreMtxReqSurrender_Skip( ctx, 1 );
1128     return;
1129   }
1130 
1131   ScoreMtxReqSurrender_Pre_Recursive_Prepare( ctx, ctx->Map.pcs[ 2 ] );
1132 
1133   if ( ctx->Map.skip ) {
1134     ScoreMtxReqSurrender_Skip( ctx, 2 );
1135     return;
1136   }
1137 
1138   ScoreMtxReqSurrender_Pre_OwnerCheck_Prepare( ctx, ctx->Map.pcs[ 3 ] );
1139 
1140   if ( ctx->Map.skip ) {
1141     ScoreMtxReqSurrender_Skip( ctx, 3 );
1142     return;
1143   }
1144 
1145   ScoreMtxReqSurrender_Pre_Owner_Prepare( ctx, ctx->Map.pcs[ 4 ] );
1146   ScoreMtxReqSurrender_Pre_Nested_Prepare( ctx, ctx->Map.pcs[ 5 ] );
1147   ScoreMtxReqSurrender_Pre_Blocked_Prepare( ctx, ctx->Map.pcs[ 6 ] );
1148   ScoreMtxReqSurrender_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 7 ] );
1149   ScoreMtxReqSurrender_Action( ctx );
1150   ScoreMtxReqSurrender_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
1151   ScoreMtxReqSurrender_Post_Owner_Check( ctx, ctx->Map.entry.Post_Owner );
1152   ScoreMtxReqSurrender_Post_Surrender_Check(
1153     ctx,
1154     ctx->Map.entry.Post_Surrender
1155   );
1156   ScoreMtxReqSurrender_Post_Priority_Check(
1157     ctx,
1158     ctx->Map.entry.Post_Priority
1159   );
1160 }
1161 
1162 static T_fixture_node ScoreMtxReqSurrender_Node;
1163 
1164 static T_remark ScoreMtxReqSurrender_Remark = {
1165   .next = NULL,
1166   .remark = "ScoreMtxReqSurrender"
1167 };
1168 
1169 void ScoreMtxReqSurrender_Run( TQMtxContext *tq_ctx )
1170 {
1171   ScoreMtxReqSurrender_Context *ctx;
1172 
1173   ctx = &ScoreMtxReqSurrender_Instance;
1174   ctx->tq_ctx = tq_ctx;
1175 
1176   ctx = T_push_fixture(
1177     &ScoreMtxReqSurrender_Node,
1178     &ScoreMtxReqSurrender_Fixture
1179   );
1180   ctx->Map.in_action_loop = true;
1181   ctx->Map.index = 0;
1182   ctx->Map.skip = false;
1183 
1184   for (
1185     ctx->Map.pci[ 0 ] = ScoreMtxReqSurrender_Pre_Protocol_None;
1186     ctx->Map.pci[ 0 ] < ScoreMtxReqSurrender_Pre_Protocol_NA;
1187     ++ctx->Map.pci[ 0 ]
1188   ) {
1189     for (
1190       ctx->Map.pci[ 1 ] = ScoreMtxReqSurrender_Pre_Discipline_FIFO;
1191       ctx->Map.pci[ 1 ] < ScoreMtxReqSurrender_Pre_Discipline_NA;
1192       ++ctx->Map.pci[ 1 ]
1193     ) {
1194       for (
1195         ctx->Map.pci[ 2 ] = ScoreMtxReqSurrender_Pre_Recursive_Allowed;
1196         ctx->Map.pci[ 2 ] < ScoreMtxReqSurrender_Pre_Recursive_NA;
1197         ++ctx->Map.pci[ 2 ]
1198       ) {
1199         for (
1200           ctx->Map.pci[ 3 ] = ScoreMtxReqSurrender_Pre_OwnerCheck_Yes;
1201           ctx->Map.pci[ 3 ] < ScoreMtxReqSurrender_Pre_OwnerCheck_NA;
1202           ++ctx->Map.pci[ 3 ]
1203         ) {
1204           for (
1205             ctx->Map.pci[ 4 ] = ScoreMtxReqSurrender_Pre_Owner_None;
1206             ctx->Map.pci[ 4 ] < ScoreMtxReqSurrender_Pre_Owner_NA;
1207             ++ctx->Map.pci[ 4 ]
1208           ) {
1209             for (
1210               ctx->Map.pci[ 5 ] = ScoreMtxReqSurrender_Pre_Nested_Yes;
1211               ctx->Map.pci[ 5 ] < ScoreMtxReqSurrender_Pre_Nested_NA;
1212               ++ctx->Map.pci[ 5 ]
1213             ) {
1214               for (
1215                 ctx->Map.pci[ 6 ] = ScoreMtxReqSurrender_Pre_Blocked_Yes;
1216                 ctx->Map.pci[ 6 ] < ScoreMtxReqSurrender_Pre_Blocked_NA;
1217                 ++ctx->Map.pci[ 6 ]
1218               ) {
1219                 for (
1220                   ctx->Map.pci[ 7 ] = ScoreMtxReqSurrender_Pre_Priority_High;
1221                   ctx->Map.pci[ 7 ] < ScoreMtxReqSurrender_Pre_Priority_NA;
1222                   ++ctx->Map.pci[ 7 ]
1223                 ) {
1224                   ctx->Map.entry = ScoreMtxReqSurrender_PopEntry( ctx );
1225 
1226                   if ( ctx->Map.entry.Skip ) {
1227                     continue;
1228                   }
1229 
1230                   ScoreMtxReqSurrender_SetPreConditionStates( ctx );
1231                   ScoreMtxReqSurrender_Prepare( ctx );
1232                   ScoreMtxReqSurrender_TestVariant( ctx );
1233                 }
1234               }
1235             }
1236           }
1237         }
1238       }
1239     }
1240   }
1241 
1242   T_add_remark( &ScoreMtxReqSurrender_Remark );
1243   T_pop_fixture();
1244 }
1245 
1246 /** @} */