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 RtemsSemReqObtain
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 <string.h>
0057 
0058 #include "tr-mtx-seize-try.h"
0059 #include "tr-mtx-seize-wait.h"
0060 #include "tr-sem-seize-try.h"
0061 #include "tr-sem-seize-wait.h"
0062 #include "tx-support.h"
0063 #include "tx-thread-queue.h"
0064 
0065 #include <rtems/test.h>
0066 
0067 /**
0068  * @defgroup RtemsSemReqObtain spec:/rtems/sem/req/obtain
0069  *
0070  * @ingroup TestsuitesValidationNoClock0
0071  *
0072  * @{
0073  */
0074 
0075 typedef enum {
0076   RtemsSemReqObtain_Pre_Class_Counting,
0077   RtemsSemReqObtain_Pre_Class_Simple,
0078   RtemsSemReqObtain_Pre_Class_Binary,
0079   RtemsSemReqObtain_Pre_Class_PrioCeiling,
0080   RtemsSemReqObtain_Pre_Class_PrioInherit,
0081   RtemsSemReqObtain_Pre_Class_MrsP,
0082   RtemsSemReqObtain_Pre_Class_NA
0083 } RtemsSemReqObtain_Pre_Class;
0084 
0085 typedef enum {
0086   RtemsSemReqObtain_Pre_Discipline_FIFO,
0087   RtemsSemReqObtain_Pre_Discipline_Priority,
0088   RtemsSemReqObtain_Pre_Discipline_NA
0089 } RtemsSemReqObtain_Pre_Discipline;
0090 
0091 typedef enum {
0092   RtemsSemReqObtain_Pre_Id_Valid,
0093   RtemsSemReqObtain_Pre_Id_Invalid,
0094   RtemsSemReqObtain_Pre_Id_NA
0095 } RtemsSemReqObtain_Pre_Id;
0096 
0097 typedef enum {
0098   RtemsSemReqObtain_Pre_Wait_No,
0099   RtemsSemReqObtain_Pre_Wait_Timeout,
0100   RtemsSemReqObtain_Pre_Wait_Forever,
0101   RtemsSemReqObtain_Pre_Wait_NA
0102 } RtemsSemReqObtain_Pre_Wait;
0103 
0104 typedef enum {
0105   RtemsSemReqObtain_Post_Action_InvId,
0106   RtemsSemReqObtain_Post_Action_SemSeizeTry,
0107   RtemsSemReqObtain_Post_Action_SemSeizeWait,
0108   RtemsSemReqObtain_Post_Action_MtxSeizeTry,
0109   RtemsSemReqObtain_Post_Action_MtxSeizeWait,
0110   RtemsSemReqObtain_Post_Action_InheritMtxSeizeTry,
0111   RtemsSemReqObtain_Post_Action_InheritMtxSeizeWait,
0112   RtemsSemReqObtain_Post_Action_CeilingMtxSeizeTry,
0113   RtemsSemReqObtain_Post_Action_CeilingMtxSeizeWait,
0114   RtemsSemReqObtain_Post_Action_MrsPMtxSeizeTry,
0115   RtemsSemReqObtain_Post_Action_MrsPMtxSeizeWait,
0116   RtemsSemReqObtain_Post_Action_NA
0117 } RtemsSemReqObtain_Post_Action;
0118 
0119 typedef struct {
0120   uint16_t Skip : 1;
0121   uint16_t Pre_Class_NA : 1;
0122   uint16_t Pre_Discipline_NA : 1;
0123   uint16_t Pre_Id_NA : 1;
0124   uint16_t Pre_Wait_NA : 1;
0125   uint16_t Post_Action : 4;
0126 } RtemsSemReqObtain_Entry;
0127 
0128 /**
0129  * @brief Test context for spec:/rtems/sem/req/obtain test case.
0130  */
0131 typedef struct {
0132   /**
0133    * @brief This member contains the thread queue test context.
0134    */
0135   union {
0136     TQContext tq_ctx;
0137     TQMtxContext tq_mtx_ctx;
0138     TQSemContext tq_sem_ctx;
0139   };
0140 
0141   /**
0142    * @brief This member specifies if the attribute set of the semaphore.
0143    */
0144   rtems_attribute attribute_set;
0145 
0146   struct {
0147     /**
0148      * @brief This member defines the pre-condition states for the next action.
0149      */
0150     size_t pcs[ 4 ];
0151 
0152     /**
0153      * @brief If this member is true, then the test action loop is executed.
0154      */
0155     bool in_action_loop;
0156 
0157     /**
0158      * @brief This member contains the next transition map index.
0159      */
0160     size_t index;
0161 
0162     /**
0163      * @brief This member contains the current transition map entry.
0164      */
0165     RtemsSemReqObtain_Entry entry;
0166 
0167     /**
0168      * @brief If this member is true, then the current transition variant
0169      *   should be skipped.
0170      */
0171     bool skip;
0172   } Map;
0173 } RtemsSemReqObtain_Context;
0174 
0175 static RtemsSemReqObtain_Context
0176   RtemsSemReqObtain_Instance;
0177 
0178 static const char * const RtemsSemReqObtain_PreDesc_Class[] = {
0179   "Counting",
0180   "Simple",
0181   "Binary",
0182   "PrioCeiling",
0183   "PrioInherit",
0184   "MrsP",
0185   "NA"
0186 };
0187 
0188 static const char * const RtemsSemReqObtain_PreDesc_Discipline[] = {
0189   "FIFO",
0190   "Priority",
0191   "NA"
0192 };
0193 
0194 static const char * const RtemsSemReqObtain_PreDesc_Id[] = {
0195   "Valid",
0196   "Invalid",
0197   "NA"
0198 };
0199 
0200 static const char * const RtemsSemReqObtain_PreDesc_Wait[] = {
0201   "No",
0202   "Timeout",
0203   "Forever",
0204   "NA"
0205 };
0206 
0207 static const char * const * const RtemsSemReqObtain_PreDesc[] = {
0208   RtemsSemReqObtain_PreDesc_Class,
0209   RtemsSemReqObtain_PreDesc_Discipline,
0210   RtemsSemReqObtain_PreDesc_Id,
0211   RtemsSemReqObtain_PreDesc_Wait,
0212   NULL
0213 };
0214 
0215 #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
0216 
0217 typedef RtemsSemReqObtain_Context Context;
0218 
0219 static void RtemsSemReqObtain_Pre_Class_Prepare(
0220   RtemsSemReqObtain_Context  *ctx,
0221   RtemsSemReqObtain_Pre_Class state
0222 )
0223 {
0224   switch ( state ) {
0225     case RtemsSemReqObtain_Pre_Class_Counting: {
0226       /*
0227        * While the semaphore object is a counting semaphore.
0228        */
0229       ctx->attribute_set |= RTEMS_COUNTING_SEMAPHORE;
0230       break;
0231     }
0232 
0233     case RtemsSemReqObtain_Pre_Class_Simple: {
0234       /*
0235        * While the semaphore object is a simple binary semaphore.
0236        */
0237       ctx->attribute_set |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
0238       break;
0239     }
0240 
0241     case RtemsSemReqObtain_Pre_Class_Binary: {
0242       /*
0243        * While the semaphore object is a binary semaphore.
0244        */
0245       ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE;
0246       break;
0247     }
0248 
0249     case RtemsSemReqObtain_Pre_Class_PrioCeiling: {
0250       /*
0251        * While the semaphore object is a priority ceiling semaphore.
0252        */
0253       ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING;
0254       break;
0255     }
0256 
0257     case RtemsSemReqObtain_Pre_Class_PrioInherit: {
0258       /*
0259        * While the semaphore object is a priority inheritance semaphore.
0260        */
0261       ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY;
0262       break;
0263     }
0264 
0265     case RtemsSemReqObtain_Pre_Class_MrsP: {
0266       /*
0267        * While the semaphore object is a MrsP semaphore.
0268        */
0269       ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE |
0270         RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
0271       break;
0272     }
0273 
0274     case RtemsSemReqObtain_Pre_Class_NA:
0275       break;
0276   }
0277 }
0278 
0279 static void RtemsSemReqObtain_Pre_Discipline_Prepare(
0280   RtemsSemReqObtain_Context       *ctx,
0281   RtemsSemReqObtain_Pre_Discipline state
0282 )
0283 {
0284   switch ( state ) {
0285     case RtemsSemReqObtain_Pre_Discipline_FIFO: {
0286       /*
0287        * While the semaphore uses the FIFO task wait queue discipline.
0288        */
0289       ctx->attribute_set |= RTEMS_FIFO;
0290       ctx->tq_ctx.discipline = TQ_FIFO;
0291       break;
0292     }
0293 
0294     case RtemsSemReqObtain_Pre_Discipline_Priority: {
0295       /*
0296        * While the semaphore uses the priority task wait queue discipline.
0297        */
0298       ctx->attribute_set |= RTEMS_PRIORITY;
0299       ctx->tq_ctx.discipline = TQ_PRIORITY;
0300       break;
0301     }
0302 
0303     case RtemsSemReqObtain_Pre_Discipline_NA:
0304       break;
0305   }
0306 }
0307 
0308 static void RtemsSemReqObtain_Pre_Id_Prepare(
0309   RtemsSemReqObtain_Context *ctx,
0310   RtemsSemReqObtain_Pre_Id   state
0311 )
0312 {
0313   switch ( state ) {
0314     case RtemsSemReqObtain_Pre_Id_Valid: {
0315       /*
0316        * While the ``id`` parameter is associated with the semaphore.
0317        */
0318       /* Nothing to prepare */
0319       break;
0320     }
0321 
0322     case RtemsSemReqObtain_Pre_Id_Invalid: {
0323       /*
0324        * While the ``id`` parameter is not associated with a semaphore.
0325        */
0326       /* Nothing to prepare */
0327       break;
0328     }
0329 
0330     case RtemsSemReqObtain_Pre_Id_NA:
0331       break;
0332   }
0333 }
0334 
0335 static void RtemsSemReqObtain_Pre_Wait_Prepare(
0336   RtemsSemReqObtain_Context *ctx,
0337   RtemsSemReqObtain_Pre_Wait state
0338 )
0339 {
0340   switch ( state ) {
0341     case RtemsSemReqObtain_Pre_Wait_No: {
0342       /*
0343        * While the ``option_set`` parameter indicates the RTEMS_NO_WAIT option.
0344        */
0345       ctx->tq_ctx.wait = TQ_NO_WAIT;
0346       break;
0347     }
0348 
0349     case RtemsSemReqObtain_Pre_Wait_Timeout: {
0350       /*
0351        * While the ``option_set`` parameter indicates the RTEMS_WAIT option,
0352        * while the ``timeout`` parameter is not equal to RTEMS_NO_TIMEOUT.
0353        */
0354       ctx->tq_ctx.wait = TQ_WAIT_TIMED;
0355       break;
0356     }
0357 
0358     case RtemsSemReqObtain_Pre_Wait_Forever: {
0359       /*
0360        * While the ``option_set`` parameter indicates the RTEMS_WAIT option,
0361        * while the ``timeout`` parameter is equal to RTEMS_NO_TIMEOUT.
0362        */
0363       ctx->tq_ctx.wait = TQ_WAIT_FOREVER;
0364       break;
0365     }
0366 
0367     case RtemsSemReqObtain_Pre_Wait_NA:
0368       break;
0369   }
0370 }
0371 
0372 static void RtemsSemReqObtain_Post_Action_Check(
0373   RtemsSemReqObtain_Context    *ctx,
0374   RtemsSemReqObtain_Post_Action state
0375 )
0376 {
0377   rtems_status_code sc;
0378 
0379   switch ( state ) {
0380     case RtemsSemReqObtain_Post_Action_InvId: {
0381       /*
0382        * The return status of rtems_semaphore_obtain() shall be
0383        * RTEMS_INVALID_ID.
0384        */
0385       sc = rtems_semaphore_obtain( 0xffffffff, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
0386       T_rsc( sc, RTEMS_INVALID_ID );
0387       break;
0388     }
0389 
0390     case RtemsSemReqObtain_Post_Action_SemSeizeTry: {
0391       /*
0392        * The calling task shall try to seize the semaphore as specified by
0393        * spec:/score/sem/req/seize-try.
0394        */
0395       ctx->tq_sem_ctx.get_count = TQSemGetCountClassic;
0396       ctx->tq_sem_ctx.set_count = TQSemSetCountClassic;
0397       ScoreSemReqSeizeTry_Run( &ctx->tq_sem_ctx );
0398       break;
0399     }
0400 
0401     case RtemsSemReqObtain_Post_Action_SemSeizeWait: {
0402       /*
0403        * The calling task shall wait to seize the semaphore as specified by
0404        * spec:/score/sem/req/seize-wait.
0405        */
0406       ctx->tq_sem_ctx.get_count = TQSemGetCountClassic;
0407       ctx->tq_sem_ctx.set_count = TQSemSetCountClassic;
0408       ScoreSemReqSeizeWait_Run( &ctx->tq_sem_ctx );
0409       break;
0410     }
0411 
0412     case RtemsSemReqObtain_Post_Action_MtxSeizeTry: {
0413       /*
0414        * The calling task shall try to seize the mutex as specified by
0415        * spec:/score/mtx/req/seize-try where an enqueue blocks, a recursive
0416        * seize is allowed, and no locking protocol is used.
0417        */
0418       ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
0419       ctx->tq_mtx_ctx.protocol = TQ_MTX_NO_PROTOCOL;
0420       ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
0421       ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
0422       ScoreMtxReqSeizeTry_Run( &ctx->tq_mtx_ctx );
0423       break;
0424     }
0425 
0426     case RtemsSemReqObtain_Post_Action_MtxSeizeWait: {
0427       /*
0428        * The calling task shall wait to seize the mutex as specified by
0429        * spec:/score/mtx/req/seize-wait where an enqueue blocks, a recursive
0430        * seize is allowed, and no locking protocol is used.
0431        */
0432       ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
0433       ctx->tq_mtx_ctx.protocol = TQ_MTX_NO_PROTOCOL;
0434       ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
0435       ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
0436       ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
0437       break;
0438     }
0439 
0440     case RtemsSemReqObtain_Post_Action_InheritMtxSeizeTry: {
0441       /*
0442        * The calling task shall try to seize the mutex as specified by
0443        * spec:/score/mtx/req/seize-try where an enqueue blocks, a recursive
0444        * seize is allowed, and a priority inheritance protocol is used.
0445        */
0446       ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
0447       ctx->tq_mtx_ctx.protocol = TQ_MTX_NO_PROTOCOL;
0448       ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
0449       ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
0450       ScoreMtxReqSeizeTry_Run( &ctx->tq_mtx_ctx );
0451       break;
0452     }
0453 
0454     case RtemsSemReqObtain_Post_Action_InheritMtxSeizeWait: {
0455       /*
0456        * The calling task shall wait to seize the mutex as specified by
0457        * spec:/score/mtx/req/seize-wait where an enqueue blocks, a recursive
0458        * seize is allowed, and a priority inheritance protocol is used.
0459        */
0460       ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
0461       ctx->tq_mtx_ctx.protocol = TQ_MTX_NO_PROTOCOL;
0462       ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
0463       ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
0464       ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
0465       break;
0466     }
0467 
0468     case RtemsSemReqObtain_Post_Action_CeilingMtxSeizeTry: {
0469       /*
0470        * The calling task shall try to seize the mutex as specified by
0471        * spec:/score/mtx/req/seize-try where an enqueue blocks, a recursive
0472        * seize is allowed, and a priority ceiling is used.
0473        */
0474       ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
0475       ctx->tq_mtx_ctx.protocol = TQ_MTX_PRIORITY_CEILING;
0476       ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
0477       ctx->tq_mtx_ctx.priority_ceiling = PRIO_VERY_HIGH;
0478       ScoreMtxReqSeizeTry_Run( &ctx->tq_mtx_ctx );
0479       break;
0480     }
0481 
0482     case RtemsSemReqObtain_Post_Action_CeilingMtxSeizeWait: {
0483       /*
0484        * The calling task shall wait to seize the mutex as specified by
0485        * spec:/score/mtx/req/seize-wait where an enqueue blocks, a recursive
0486        * seize is allowed, and a priority ceiling is used.
0487        */
0488       ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
0489       ctx->tq_mtx_ctx.protocol = TQ_MTX_PRIORITY_CEILING;
0490       ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
0491       ctx->tq_mtx_ctx.priority_ceiling = PRIO_VERY_HIGH;
0492       ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
0493       break;
0494     }
0495 
0496     case RtemsSemReqObtain_Post_Action_MrsPMtxSeizeTry: {
0497       /*
0498        * The calling task shall try to seize the mutex as specified by
0499        * spec:/score/mtx/req/seize-try where an enqueue is sticky, a recursive
0500        * seize returns an error status, and a priority ceiling is used.
0501        */
0502       #if defined(RTEMS_SMP)
0503       ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_STICKY;
0504       ctx->tq_mtx_ctx.protocol = TQ_MTX_MRSP;
0505       ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_DEADLOCK;
0506       ctx->tq_mtx_ctx.priority_ceiling = PRIO_VERY_HIGH;
0507       ScoreMtxReqSeizeTry_Run( &ctx->tq_mtx_ctx );
0508       #else
0509       T_unreachable();
0510       #endif
0511       break;
0512     }
0513 
0514     case RtemsSemReqObtain_Post_Action_MrsPMtxSeizeWait: {
0515       /*
0516        * The calling task shall wait to seize the mutex as specified by
0517        * spec:/score/mtx/req/seize-wait where an enqueue is sticky, a recursive
0518        * seize returns an error status, and a priority ceiling is used.
0519        */
0520       #if defined(RTEMS_SMP)
0521       ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_STICKY;
0522       ctx->tq_mtx_ctx.protocol = TQ_MTX_MRSP;
0523       ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_DEADLOCK;
0524       ctx->tq_mtx_ctx.priority_ceiling = PRIO_VERY_HIGH;
0525       ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
0526       #else
0527       T_unreachable();
0528       #endif
0529       break;
0530     }
0531 
0532     case RtemsSemReqObtain_Post_Action_NA:
0533       break;
0534   }
0535 }
0536 
0537 static void RtemsSemReqObtain_Setup( RtemsSemReqObtain_Context *ctx )
0538 {
0539   memset( ctx, 0, sizeof( *ctx ) );
0540   ctx->tq_ctx.deadlock = TQ_DEADLOCK_STATUS;
0541   ctx->tq_ctx.enqueue_prepare = TQEnqueuePrepareDefault;
0542   ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
0543   ctx->tq_ctx.enqueue = TQEnqueueClassicSem;
0544   ctx->tq_ctx.surrender = TQSurrenderClassicSem;
0545   ctx->tq_ctx.get_owner = TQGetOwnerClassicSem;
0546   ctx->tq_ctx.convert_status = TQConvertStatusClassic;
0547   TQInitialize( &ctx->tq_ctx );
0548 }
0549 
0550 static void RtemsSemReqObtain_Setup_Wrap( void *arg )
0551 {
0552   RtemsSemReqObtain_Context *ctx;
0553 
0554   ctx = arg;
0555   ctx->Map.in_action_loop = false;
0556   RtemsSemReqObtain_Setup( ctx );
0557 }
0558 
0559 static void RtemsSemReqObtain_Teardown( RtemsSemReqObtain_Context *ctx )
0560 {
0561   TQDestroy( &ctx->tq_ctx );
0562 }
0563 
0564 static void RtemsSemReqObtain_Teardown_Wrap( void *arg )
0565 {
0566   RtemsSemReqObtain_Context *ctx;
0567 
0568   ctx = arg;
0569   ctx->Map.in_action_loop = false;
0570   RtemsSemReqObtain_Teardown( ctx );
0571 }
0572 
0573 static void RtemsSemReqObtain_Prepare( RtemsSemReqObtain_Context *ctx )
0574 {
0575   ctx->attribute_set = RTEMS_DEFAULT_ATTRIBUTES;
0576 }
0577 
0578 static void RtemsSemReqObtain_Action( RtemsSemReqObtain_Context *ctx )
0579 {
0580   rtems_status_code sc;
0581 
0582   sc = rtems_semaphore_create(
0583     NAME,
0584     1,
0585     ctx->attribute_set,
0586     PRIO_VERY_HIGH,
0587     &ctx->tq_ctx.thread_queue_id
0588   );
0589   T_rsc_success( sc );
0590 
0591   #if defined(RTEMS_SMP)
0592   if ( ( ctx->attribute_set & RTEMS_MULTIPROCESSOR_RESOURCE_SHARING ) != 0 ) {
0593     rtems_task_priority prio;
0594 
0595     sc = rtems_semaphore_set_priority(
0596       ctx->tq_ctx.thread_queue_id,
0597       SCHEDULER_B_ID,
0598       PRIO_VERY_HIGH,
0599       &prio
0600     );
0601     T_rsc_success( sc );
0602   }
0603   #endif
0604 }
0605 
0606 static void RtemsSemReqObtain_Cleanup( RtemsSemReqObtain_Context *ctx )
0607 {
0608   rtems_status_code sc;
0609   sc = rtems_semaphore_delete( ctx->tq_ctx.thread_queue_id ); T_rsc_success( sc );
0610 }
0611 
0612 static const RtemsSemReqObtain_Entry
0613 RtemsSemReqObtain_Entries[] = {
0614   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_InvId },
0615   { 1, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_NA },
0616   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_SemSeizeWait },
0617   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_SemSeizeTry },
0618   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_MtxSeizeWait },
0619   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_MtxSeizeTry },
0620   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_CeilingMtxSeizeWait },
0621   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_InheritMtxSeizeWait },
0622 #if defined(RTEMS_SMP)
0623   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_MrsPMtxSeizeWait },
0624 #else
0625   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_CeilingMtxSeizeWait },
0626 #endif
0627   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_CeilingMtxSeizeTry },
0628   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_InheritMtxSeizeTry },
0629 #if defined(RTEMS_SMP)
0630   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_MrsPMtxSeizeTry }
0631 #else
0632   { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_CeilingMtxSeizeTry }
0633 #endif
0634 };
0635 
0636 static const uint8_t
0637 RtemsSemReqObtain_Map[] = {
0638   3, 2, 2, 0, 0, 0, 3, 2, 2, 0, 0, 0, 3, 2, 2, 0, 0, 0, 3, 2, 2, 0, 0, 0, 5, 4,
0639   4, 0, 0, 0, 5, 4, 4, 0, 0, 0, 1, 1, 1, 1, 1, 1, 9, 6, 6, 0, 0, 0, 1, 1, 1, 1,
0640   1, 1, 10, 7, 7, 0, 0, 0, 1, 1, 1, 1, 1, 1, 11, 8, 8, 0, 0, 0
0641 };
0642 
0643 static size_t RtemsSemReqObtain_Scope( void *arg, char *buf, size_t n )
0644 {
0645   RtemsSemReqObtain_Context *ctx;
0646 
0647   ctx = arg;
0648 
0649   if ( ctx->Map.in_action_loop ) {
0650     return T_get_scope( RtemsSemReqObtain_PreDesc, buf, n, ctx->Map.pcs );
0651   }
0652 
0653   return 0;
0654 }
0655 
0656 static T_fixture RtemsSemReqObtain_Fixture = {
0657   .setup = RtemsSemReqObtain_Setup_Wrap,
0658   .stop = NULL,
0659   .teardown = RtemsSemReqObtain_Teardown_Wrap,
0660   .scope = RtemsSemReqObtain_Scope,
0661   .initial_context = &RtemsSemReqObtain_Instance
0662 };
0663 
0664 static inline RtemsSemReqObtain_Entry RtemsSemReqObtain_PopEntry(
0665   RtemsSemReqObtain_Context *ctx
0666 )
0667 {
0668   size_t index;
0669 
0670   index = ctx->Map.index;
0671   ctx->Map.index = index + 1;
0672   return RtemsSemReqObtain_Entries[
0673     RtemsSemReqObtain_Map[ index ]
0674   ];
0675 }
0676 
0677 static void RtemsSemReqObtain_TestVariant( RtemsSemReqObtain_Context *ctx )
0678 {
0679   RtemsSemReqObtain_Pre_Class_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0680   RtemsSemReqObtain_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0681   RtemsSemReqObtain_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0682   RtemsSemReqObtain_Pre_Wait_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0683   RtemsSemReqObtain_Action( ctx );
0684   RtemsSemReqObtain_Post_Action_Check( ctx, ctx->Map.entry.Post_Action );
0685 }
0686 
0687 /**
0688  * @fn void T_case_body_RtemsSemReqObtain( void )
0689  */
0690 T_TEST_CASE_FIXTURE( RtemsSemReqObtain, &RtemsSemReqObtain_Fixture )
0691 {
0692   RtemsSemReqObtain_Context *ctx;
0693 
0694   ctx = T_fixture_context();
0695   ctx->Map.in_action_loop = true;
0696   ctx->Map.index = 0;
0697 
0698   for (
0699     ctx->Map.pcs[ 0 ] = RtemsSemReqObtain_Pre_Class_Counting;
0700     ctx->Map.pcs[ 0 ] < RtemsSemReqObtain_Pre_Class_NA;
0701     ++ctx->Map.pcs[ 0 ]
0702   ) {
0703     for (
0704       ctx->Map.pcs[ 1 ] = RtemsSemReqObtain_Pre_Discipline_FIFO;
0705       ctx->Map.pcs[ 1 ] < RtemsSemReqObtain_Pre_Discipline_NA;
0706       ++ctx->Map.pcs[ 1 ]
0707     ) {
0708       for (
0709         ctx->Map.pcs[ 2 ] = RtemsSemReqObtain_Pre_Id_Valid;
0710         ctx->Map.pcs[ 2 ] < RtemsSemReqObtain_Pre_Id_NA;
0711         ++ctx->Map.pcs[ 2 ]
0712       ) {
0713         for (
0714           ctx->Map.pcs[ 3 ] = RtemsSemReqObtain_Pre_Wait_No;
0715           ctx->Map.pcs[ 3 ] < RtemsSemReqObtain_Pre_Wait_NA;
0716           ++ctx->Map.pcs[ 3 ]
0717         ) {
0718           ctx->Map.entry = RtemsSemReqObtain_PopEntry( ctx );
0719 
0720           if ( ctx->Map.entry.Skip ) {
0721             continue;
0722           }
0723 
0724           RtemsSemReqObtain_Prepare( ctx );
0725           RtemsSemReqObtain_TestVariant( ctx );
0726           RtemsSemReqObtain_Cleanup( ctx );
0727         }
0728       }
0729     }
0730   }
0731 }
0732 
0733 /** @} */