Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RtemsMessageReqFlushPending
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 
0057 #include "tx-support.h"
0058 
0059 #include <rtems/test.h>
0060 
0061 /**
0062  * @defgroup RtemsMessageReqFlushPending spec:/rtems/message/req/flush-pending
0063  *
0064  * @ingroup TestsuitesValidationNoClock0
0065  *
0066  * @{
0067  */
0068 
0069 typedef enum {
0070   RtemsMessageReqFlushPending_Pre_Count_Valid,
0071   RtemsMessageReqFlushPending_Pre_Count_Null,
0072   RtemsMessageReqFlushPending_Pre_Count_NA
0073 } RtemsMessageReqFlushPending_Pre_Count;
0074 
0075 typedef enum {
0076   RtemsMessageReqFlushPending_Pre_Id_Valid,
0077   RtemsMessageReqFlushPending_Pre_Id_Invalid,
0078   RtemsMessageReqFlushPending_Pre_Id_NA
0079 } RtemsMessageReqFlushPending_Pre_Id;
0080 
0081 typedef enum {
0082   RtemsMessageReqFlushPending_Pre_MsgQueue_Empty,
0083   RtemsMessageReqFlushPending_Pre_MsgQueue_Several,
0084   RtemsMessageReqFlushPending_Pre_MsgQueue_NA
0085 } RtemsMessageReqFlushPending_Pre_MsgQueue;
0086 
0087 typedef enum {
0088   RtemsMessageReqFlushPending_Pre_Receivers_Waiting,
0089   RtemsMessageReqFlushPending_Pre_Receivers_None,
0090   RtemsMessageReqFlushPending_Pre_Receivers_NA
0091 } RtemsMessageReqFlushPending_Pre_Receivers;
0092 
0093 typedef enum {
0094   RtemsMessageReqFlushPending_Pre_Directive_Flush,
0095   RtemsMessageReqFlushPending_Pre_Directive_Pending,
0096   RtemsMessageReqFlushPending_Pre_Directive_NA
0097 } RtemsMessageReqFlushPending_Pre_Directive;
0098 
0099 typedef enum {
0100   RtemsMessageReqFlushPending_Pre_Storage_Nop,
0101   RtemsMessageReqFlushPending_Pre_Storage_NA
0102 } RtemsMessageReqFlushPending_Pre_Storage;
0103 
0104 typedef enum {
0105   RtemsMessageReqFlushPending_Post_Status_Ok,
0106   RtemsMessageReqFlushPending_Post_Status_InvId,
0107   RtemsMessageReqFlushPending_Post_Status_InvAddr,
0108   RtemsMessageReqFlushPending_Post_Status_NA
0109 } RtemsMessageReqFlushPending_Post_Status;
0110 
0111 typedef enum {
0112   RtemsMessageReqFlushPending_Post_Count_Zero,
0113   RtemsMessageReqFlushPending_Post_Count_Set,
0114   RtemsMessageReqFlushPending_Post_Count_Nop,
0115   RtemsMessageReqFlushPending_Post_Count_NA
0116 } RtemsMessageReqFlushPending_Post_Count;
0117 
0118 typedef enum {
0119   RtemsMessageReqFlushPending_Post_MsgQueue_Empty,
0120   RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
0121   RtemsMessageReqFlushPending_Post_MsgQueue_NA
0122 } RtemsMessageReqFlushPending_Post_MsgQueue;
0123 
0124 typedef enum {
0125   RtemsMessageReqFlushPending_Post_Receivers_Nop,
0126   RtemsMessageReqFlushPending_Post_Receivers_NA
0127 } RtemsMessageReqFlushPending_Post_Receivers;
0128 
0129 typedef struct {
0130   uint16_t Skip : 1;
0131   uint16_t Pre_Count_NA : 1;
0132   uint16_t Pre_Id_NA : 1;
0133   uint16_t Pre_MsgQueue_NA : 1;
0134   uint16_t Pre_Receivers_NA : 1;
0135   uint16_t Pre_Directive_NA : 1;
0136   uint16_t Pre_Storage_NA : 1;
0137   uint16_t Post_Status : 2;
0138   uint16_t Post_Count : 2;
0139   uint16_t Post_MsgQueue : 2;
0140   uint16_t Post_Receivers : 1;
0141 } RtemsMessageReqFlushPending_Entry;
0142 
0143 #define MAXIMUM_PENDING_MESSAGES 3
0144 #define MAXIMUM_MESSAGE_SIZE     5
0145 #define NUMBER_OF_WORKERS        3
0146 
0147 /**
0148  * @brief Test context for spec:/rtems/message/req/flush-pending test case.
0149  */
0150 typedef struct {
0151   /**
0152    * @brief This member contains a valid ID of a message queue.
0153    */
0154   rtems_id message_queue_id;
0155 
0156   /**
0157    * @brief This member is used as storage area for the message queue.
0158    */
0159   RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE )
0160     storage_area[ MAXIMUM_PENDING_MESSAGES ];
0161 
0162   /**
0163    * @brief This member contains the returned status codes of the receivers.
0164    */
0165   rtems_status_code receive_status[ NUMBER_OF_WORKERS ];
0166 
0167   /**
0168    * @brief This member specifies the directive to be called as action.
0169    *
0170    * This is either rtems_message_queue_flush() or
0171    * rtems_message_queue_get_number_pending().
0172    */
0173   rtems_status_code (*action)( rtems_id id, uint32_t *count );
0174 
0175   /**
0176    * @brief This member specifies the ``id`` parameter of the action.
0177    */
0178   rtems_id id_param;
0179 
0180   /**
0181    * @brief This member specifies the ``count`` parameter of the action.
0182    */
0183   uint32_t *count_param;
0184 
0185   /**
0186    * @brief This member contains the returned status code of the action.
0187    */
0188   rtems_status_code status;
0189 
0190   /**
0191    * @brief This member contains the value returned in parameter ``count`` of
0192    *   the action.
0193    */
0194   uint32_t count;
0195 
0196   /**
0197    * @brief This member contains the task identifiers of the worker tasks.
0198    */
0199   rtems_id worker_id[ NUMBER_OF_WORKERS ];
0200 
0201   /**
0202    * @brief This member contains a pointer to a function which is executed to
0203    *   check that the action has not changed the content of the message queue.
0204    */
0205   void (*check_msgq_unchanged)( void *ctx_in );
0206 
0207   struct {
0208     /**
0209      * @brief This member defines the pre-condition states for the next action.
0210      */
0211     size_t pcs[ 6 ];
0212 
0213     /**
0214      * @brief If this member is true, then the test action loop is executed.
0215      */
0216     bool in_action_loop;
0217 
0218     /**
0219      * @brief This member contains the next transition map index.
0220      */
0221     size_t index;
0222 
0223     /**
0224      * @brief This member contains the current transition map entry.
0225      */
0226     RtemsMessageReqFlushPending_Entry entry;
0227 
0228     /**
0229      * @brief If this member is true, then the current transition variant
0230      *   should be skipped.
0231      */
0232     bool skip;
0233   } Map;
0234 } RtemsMessageReqFlushPending_Context;
0235 
0236 static RtemsMessageReqFlushPending_Context
0237   RtemsMessageReqFlushPending_Instance;
0238 
0239 static const char * const RtemsMessageReqFlushPending_PreDesc_Count[] = {
0240   "Valid",
0241   "Null",
0242   "NA"
0243 };
0244 
0245 static const char * const RtemsMessageReqFlushPending_PreDesc_Id[] = {
0246   "Valid",
0247   "Invalid",
0248   "NA"
0249 };
0250 
0251 static const char * const RtemsMessageReqFlushPending_PreDesc_MsgQueue[] = {
0252   "Empty",
0253   "Several",
0254   "NA"
0255 };
0256 
0257 static const char * const RtemsMessageReqFlushPending_PreDesc_Receivers[] = {
0258   "Waiting",
0259   "None",
0260   "NA"
0261 };
0262 
0263 static const char * const RtemsMessageReqFlushPending_PreDesc_Directive[] = {
0264   "Flush",
0265   "Pending",
0266   "NA"
0267 };
0268 
0269 static const char * const RtemsMessageReqFlushPending_PreDesc_Storage[] = {
0270   "Nop",
0271   "NA"
0272 };
0273 
0274 static const char * const * const RtemsMessageReqFlushPending_PreDesc[] = {
0275   RtemsMessageReqFlushPending_PreDesc_Count,
0276   RtemsMessageReqFlushPending_PreDesc_Id,
0277   RtemsMessageReqFlushPending_PreDesc_MsgQueue,
0278   RtemsMessageReqFlushPending_PreDesc_Receivers,
0279   RtemsMessageReqFlushPending_PreDesc_Directive,
0280   RtemsMessageReqFlushPending_PreDesc_Storage,
0281   NULL
0282 };
0283 
0284 typedef RtemsMessageReqFlushPending_Context Context;
0285 static const uint32_t NUMBER_OF_PENDING_MESSAGES = 2;
0286 static const rtems_interval TIMEOUT_TICKS = 1;
0287 static const rtems_event_set EVENT_RECEIVE = RTEMS_EVENT_17;
0288 static const uint8_t queued_message[] = { 200, 201, 202 };
0289 
0290 static void Receive( Context *ctx, size_t worker_index )
0291 {
0292   size_t size;
0293   uint8_t buffer[ MAXIMUM_MESSAGE_SIZE ];
0294 
0295   ctx->receive_status[worker_index] = rtems_message_queue_receive(
0296     ctx->message_queue_id,
0297     buffer,
0298     &size,
0299     RTEMS_WAIT,
0300     TIMEOUT_TICKS
0301   );
0302 }
0303 
0304 static void WorkerTask( rtems_task_argument argument )
0305 {
0306   static size_t worker_number = 0;
0307   size_t worker_index = worker_number++;
0308   Context *ctx = (Context *) argument;
0309 
0310   while ( true ) {
0311     ReceiveAnyEvents();
0312     Receive( ctx, worker_index );
0313   }
0314 }
0315 
0316 static void CheckForNoMessage(
0317   Context *ctx,
0318   rtems_status_code status,
0319   uint8_t *message_buffer,
0320   size_t message_size
0321 )
0322 {
0323   (void) ctx;
0324   (void) message_buffer;
0325   (void) message_size;
0326   T_rsc( status, RTEMS_UNSATISFIED  );
0327 }
0328 
0329 static void CheckForQueuedMessage(
0330   Context *ctx,
0331   rtems_status_code status,
0332   uint8_t *message_buffer,
0333   size_t message_size
0334 )
0335 {
0336   (void) ctx;
0337   T_rsc_success( status );
0338   T_eq_u32( message_size, sizeof( queued_message ) );
0339   T_eq_mem( message_buffer, queued_message, sizeof( queued_message ) );
0340 }
0341 
0342 static void PopMessage(
0343   Context *ctx,
0344   void (*check_fn)(
0345     Context *ctx,
0346     rtems_status_code status,
0347     uint8_t *message_buffer,
0348     size_t message_size
0349   )
0350 )
0351 {
0352   rtems_status_code status;
0353   uint8_t message_buffer[ MAXIMUM_MESSAGE_SIZE ];
0354   size_t message_size;
0355 
0356   status = rtems_message_queue_receive(
0357     ctx->message_queue_id,
0358     &message_buffer,
0359     &message_size,
0360     RTEMS_LOCAL | RTEMS_NO_WAIT,
0361     RTEMS_NO_TIMEOUT
0362   );
0363 
0364  check_fn( ctx, status, message_buffer, message_size );
0365 }
0366 
0367 static void CheckForNoMessageInQueue( void *ctx_in )
0368 {
0369   Context *ctx = ctx_in;
0370   PopMessage( ctx, CheckForNoMessage );
0371 }
0372 
0373 static void CheckForSeveralMessagesInQueue( void *ctx_in )
0374 {
0375   Context *ctx = ctx_in;
0376   uint32_t i;
0377   for ( i = 0; i < NUMBER_OF_PENDING_MESSAGES; ++i ) {
0378     PopMessage( ctx, CheckForQueuedMessage );
0379   }
0380   PopMessage( ctx, CheckForNoMessage );
0381 }
0382 
0383 static void SendMsg( Context *ctx )
0384 {
0385   rtems_status_code status;
0386 
0387   status = rtems_message_queue_send(
0388     ctx->message_queue_id,
0389     queued_message,
0390     sizeof( queued_message )
0391   );
0392   T_rsc_success( status );
0393 }
0394 
0395 static void RtemsMessageReqFlushPending_Pre_Count_Prepare(
0396   RtemsMessageReqFlushPending_Context  *ctx,
0397   RtemsMessageReqFlushPending_Pre_Count state
0398 )
0399 {
0400   switch ( state ) {
0401     case RtemsMessageReqFlushPending_Pre_Count_Valid: {
0402       /*
0403        * While the ``count`` parameter references an ``uint32_t`` object.
0404        */
0405       ctx->count_param = &ctx->count;
0406       break;
0407     }
0408 
0409     case RtemsMessageReqFlushPending_Pre_Count_Null: {
0410       /*
0411        * While the ``count`` parameter is NULL.
0412        */
0413       ctx->count_param = NULL;
0414       break;
0415     }
0416 
0417     case RtemsMessageReqFlushPending_Pre_Count_NA:
0418       break;
0419   }
0420 }
0421 
0422 static void RtemsMessageReqFlushPending_Pre_Id_Prepare(
0423   RtemsMessageReqFlushPending_Context *ctx,
0424   RtemsMessageReqFlushPending_Pre_Id   state
0425 )
0426 {
0427   switch ( state ) {
0428     case RtemsMessageReqFlushPending_Pre_Id_Valid: {
0429       /*
0430        * While the ``id`` parameter is valid.
0431        */
0432       ctx->id_param = ctx->message_queue_id;
0433       break;
0434     }
0435 
0436     case RtemsMessageReqFlushPending_Pre_Id_Invalid: {
0437       /*
0438        * While the ``id`` parameter is invalid.
0439        */
0440       ctx->id_param = RTEMS_ID_NONE;
0441       break;
0442     }
0443 
0444     case RtemsMessageReqFlushPending_Pre_Id_NA:
0445       break;
0446   }
0447 }
0448 
0449 static void RtemsMessageReqFlushPending_Pre_MsgQueue_Prepare(
0450   RtemsMessageReqFlushPending_Context     *ctx,
0451   RtemsMessageReqFlushPending_Pre_MsgQueue state
0452 )
0453 {
0454   switch ( state ) {
0455     case RtemsMessageReqFlushPending_Pre_MsgQueue_Empty: {
0456       /*
0457        * While there is no message in the message queue.
0458        */
0459       /* Message queue is already empty. */
0460       ctx->check_msgq_unchanged = CheckForNoMessageInQueue;
0461       break;
0462     }
0463 
0464     case RtemsMessageReqFlushPending_Pre_MsgQueue_Several: {
0465       /*
0466        * While there are messages in the message queue.
0467        */
0468       uint32_t i;
0469       for ( i = 0; i < NUMBER_OF_PENDING_MESSAGES; ++i ) {
0470         SendMsg( ctx );
0471       }
0472       ctx->check_msgq_unchanged = CheckForSeveralMessagesInQueue;
0473       break;
0474     }
0475 
0476     case RtemsMessageReqFlushPending_Pre_MsgQueue_NA:
0477       break;
0478   }
0479 }
0480 
0481 static void RtemsMessageReqFlushPending_Pre_Receivers_Prepare(
0482   RtemsMessageReqFlushPending_Context      *ctx,
0483   RtemsMessageReqFlushPending_Pre_Receivers state
0484 )
0485 {
0486   switch ( state ) {
0487     case RtemsMessageReqFlushPending_Pre_Receivers_Waiting: {
0488       /*
0489        * While one or more receivers are waiting to receive a message.
0490        */
0491       size_t i;
0492       for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
0493         SendEvents( ctx->worker_id[i], EVENT_RECEIVE );
0494       }
0495       break;
0496     }
0497 
0498     case RtemsMessageReqFlushPending_Pre_Receivers_None: {
0499       /*
0500        * While no receiver is waiting to receive a message.
0501        */
0502       /* There is already no receiver waiting. */
0503       break;
0504     }
0505 
0506     case RtemsMessageReqFlushPending_Pre_Receivers_NA:
0507       break;
0508   }
0509 }
0510 
0511 static void RtemsMessageReqFlushPending_Pre_Directive_Prepare(
0512   RtemsMessageReqFlushPending_Context      *ctx,
0513   RtemsMessageReqFlushPending_Pre_Directive state
0514 )
0515 {
0516   switch ( state ) {
0517     case RtemsMessageReqFlushPending_Pre_Directive_Flush: {
0518       /*
0519        * While the directive rtems_message_queue_flush() is called.
0520        */
0521       ctx->action = rtems_message_queue_flush;
0522       break;
0523     }
0524 
0525     case RtemsMessageReqFlushPending_Pre_Directive_Pending: {
0526       /*
0527        * While the directive rtems_message_queue_get_number_pending() is
0528        * called.
0529        */
0530       ctx->action = rtems_message_queue_get_number_pending;
0531       break;
0532     }
0533 
0534     case RtemsMessageReqFlushPending_Pre_Directive_NA:
0535       break;
0536   }
0537 }
0538 
0539 static void RtemsMessageReqFlushPending_Pre_Storage_Prepare(
0540   RtemsMessageReqFlushPending_Context    *ctx,
0541   RtemsMessageReqFlushPending_Pre_Storage state
0542 )
0543 {
0544   switch ( state ) {
0545     case RtemsMessageReqFlushPending_Pre_Storage_Nop: {
0546       /*
0547        * While the memory area to which a pointer is provided as member
0548        * storage_area of type rtems_message_queue_config when the message queue
0549        * is constructed by rtems_message_queue_construct() is altered only by
0550        * the RTEMS operating system.
0551        */
0552       /* Only a requirement text. */
0553       break;
0554     }
0555 
0556     case RtemsMessageReqFlushPending_Pre_Storage_NA:
0557       break;
0558   }
0559 }
0560 
0561 static void RtemsMessageReqFlushPending_Post_Status_Check(
0562   RtemsMessageReqFlushPending_Context    *ctx,
0563   RtemsMessageReqFlushPending_Post_Status state
0564 )
0565 {
0566   switch ( state ) {
0567     case RtemsMessageReqFlushPending_Post_Status_Ok: {
0568       /*
0569        * The return status of the called directive (rtems_message_queue_flush()
0570        * or rtems_message_queue_get_number_pending()) shall be RTEMS_SUCCESSFUL
0571        */
0572       T_rsc_success( ctx->status );
0573       break;
0574     }
0575 
0576     case RtemsMessageReqFlushPending_Post_Status_InvId: {
0577       /*
0578        * The return status of the called directive (rtems_message_queue_flush()
0579        * or rtems_message_queue_get_number_pending()) shall be
0580        * RTEMS_INVALID_ID.
0581        */
0582       T_rsc( ctx->status, RTEMS_INVALID_ID );
0583       break;
0584     }
0585 
0586     case RtemsMessageReqFlushPending_Post_Status_InvAddr: {
0587       /*
0588        * The return status of the called directive (rtems_message_queue_flush()
0589        * or rtems_message_queue_get_number_pending()) shall be
0590        * RTEMS_INVALID_ADDRESS.
0591        */
0592       T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0593       break;
0594     }
0595 
0596     case RtemsMessageReqFlushPending_Post_Status_NA:
0597       break;
0598   }
0599 }
0600 
0601 static void RtemsMessageReqFlushPending_Post_Count_Check(
0602   RtemsMessageReqFlushPending_Context   *ctx,
0603   RtemsMessageReqFlushPending_Post_Count state
0604 )
0605 {
0606   switch ( state ) {
0607     case RtemsMessageReqFlushPending_Post_Count_Zero: {
0608       /*
0609        * The value of the object referenced by the ``count`` parameter shall be
0610        * 0 after the return of the rtems_message_queue_flush() or
0611        * rtems_message_queue_get_number_pending() call.
0612        */
0613       T_eq_u32( ctx->count, 0 );
0614       break;
0615     }
0616 
0617     case RtemsMessageReqFlushPending_Post_Count_Set: {
0618       /*
0619        * The rtems_message_queue_get_number_pending() directive shall set the
0620        * value of the object referenced by the ``count`` parameter to the
0621        * number of messages present in the message queue at a point in time
0622        * during the single execution of the
0623        * rtems_message_queue_get_number_pending() directive.
0624        *
0625        * The rtems_message_queue_flush() directive shall set the value of the
0626        * object referenced by the ``count`` parameter to the number of messages
0627        * it removed from the message queue during the single execution of the
0628        * rtems_message_queue_flush() directive.
0629        */
0630       T_eq_u32( ctx->count, NUMBER_OF_PENDING_MESSAGES );
0631       break;
0632     }
0633 
0634     case RtemsMessageReqFlushPending_Post_Count_Nop: {
0635       /*
0636        * The value of the object referenced by the ``count`` parameter in past
0637        * call to rtems_message_queue_flush() or
0638        * rtems_message_queue_get_number_pending() shall not be accessed by the
0639        * rtems_message_queue_flush() or
0640        * rtems_message_queue_get_number_pending() call (see also Nop).
0641        */
0642       T_eq_u32( ctx->count, UINT8_MAX );
0643       break;
0644     }
0645 
0646     case RtemsMessageReqFlushPending_Post_Count_NA:
0647       break;
0648   }
0649 }
0650 
0651 static void RtemsMessageReqFlushPending_Post_MsgQueue_Check(
0652   RtemsMessageReqFlushPending_Context      *ctx,
0653   RtemsMessageReqFlushPending_Post_MsgQueue state
0654 )
0655 {
0656   switch ( state ) {
0657     case RtemsMessageReqFlushPending_Post_MsgQueue_Empty: {
0658       /*
0659        * The message queue shall contain no messages after the last call to
0660        * ``id``.
0661        */
0662       PopMessage( ctx, CheckForNoMessage );
0663       break;
0664     }
0665 
0666     case RtemsMessageReqFlushPending_Post_MsgQueue_Nop: {
0667       /*
0668        * Objects referenced by the ``id`` parameter in the past call to
0669        * rtems_message_queue_flush() or
0670        * rtems_message_queue_get_number_pending() shall not be changed by that
0671        * call (see also Nop).
0672        */
0673       ctx->check_msgq_unchanged( ctx );
0674       break;
0675     }
0676 
0677     case RtemsMessageReqFlushPending_Post_MsgQueue_NA:
0678       break;
0679   }
0680 }
0681 
0682 static void RtemsMessageReqFlushPending_Post_Receivers_Check(
0683   RtemsMessageReqFlushPending_Context       *ctx,
0684   RtemsMessageReqFlushPending_Post_Receivers state
0685 )
0686 {
0687   switch ( state ) {
0688     case RtemsMessageReqFlushPending_Post_Receivers_Nop: {
0689       /*
0690        * The receivers waiting for a message at the message queue shall not be
0691        * affected by the call to the rtems_message_queue_flush() or
0692        * rtems_message_queue_get_number_pending() directive.
0693        */
0694       size_t i;
0695       for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
0696         T_rsc( ctx->receive_status[i], RTEMS_TIMEOUT );
0697       }
0698       break;
0699     }
0700 
0701     case RtemsMessageReqFlushPending_Post_Receivers_NA:
0702       break;
0703   }
0704 }
0705 
0706 static void RtemsMessageReqFlushPending_Setup(
0707   RtemsMessageReqFlushPending_Context *ctx
0708 )
0709 {
0710   size_t i;
0711   SetSelfPriority( PRIO_NORMAL );
0712 
0713   for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
0714     ctx->worker_id[i] = CreateTask( "WORK", PRIO_HIGH );
0715     StartTask( ctx->worker_id[i], WorkerTask, ctx );
0716   }
0717 }
0718 
0719 static void RtemsMessageReqFlushPending_Setup_Wrap( void *arg )
0720 {
0721   RtemsMessageReqFlushPending_Context *ctx;
0722 
0723   ctx = arg;
0724   ctx->Map.in_action_loop = false;
0725   RtemsMessageReqFlushPending_Setup( ctx );
0726 }
0727 
0728 static void RtemsMessageReqFlushPending_Teardown(
0729   RtemsMessageReqFlushPending_Context *ctx
0730 )
0731 {
0732   size_t i;
0733 
0734   for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
0735     DeleteTask( ctx->worker_id[i] );
0736   }
0737   RestoreRunnerPriority();
0738 }
0739 
0740 static void RtemsMessageReqFlushPending_Teardown_Wrap( void *arg )
0741 {
0742   RtemsMessageReqFlushPending_Context *ctx;
0743 
0744   ctx = arg;
0745   ctx->Map.in_action_loop = false;
0746   RtemsMessageReqFlushPending_Teardown( ctx );
0747 }
0748 
0749 static void RtemsMessageReqFlushPending_Prepare(
0750   RtemsMessageReqFlushPending_Context *ctx
0751 )
0752 {
0753   rtems_status_code status;
0754 
0755   rtems_message_queue_config config = {
0756     .name                     = rtems_build_name( 'M', 'S', 'G', 'Q' ),
0757     .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES,
0758     .maximum_message_size     = MAXIMUM_MESSAGE_SIZE,
0759     .storage_area             = ctx->storage_area,
0760     .storage_size             = sizeof( ctx->storage_area ),
0761     .storage_free             = NULL,
0762     .attributes               = RTEMS_DEFAULT_ATTRIBUTES
0763   };
0764 
0765   status = rtems_message_queue_construct(
0766     &config,
0767     &ctx->message_queue_id
0768   );
0769   T_rsc_success( status );
0770 
0771   ctx->count = UINT8_MAX;
0772 }
0773 
0774 static void RtemsMessageReqFlushPending_Action(
0775   RtemsMessageReqFlushPending_Context *ctx
0776 )
0777 {
0778   ctx->status = (ctx->action)(
0779     ctx->id_param,
0780     ctx->count_param
0781   );
0782 
0783   FinalClockTick();
0784 }
0785 
0786 static void RtemsMessageReqFlushPending_Cleanup(
0787   RtemsMessageReqFlushPending_Context *ctx
0788 )
0789 {
0790   T_rsc_success( rtems_message_queue_delete( ctx->message_queue_id ) );
0791 }
0792 
0793 static const RtemsMessageReqFlushPending_Entry
0794 RtemsMessageReqFlushPending_Entries[] = {
0795   { 1, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_NA,
0796     RtemsMessageReqFlushPending_Post_Count_NA,
0797     RtemsMessageReqFlushPending_Post_MsgQueue_NA,
0798     RtemsMessageReqFlushPending_Post_Receivers_NA },
0799   { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_InvAddr,
0800     RtemsMessageReqFlushPending_Post_Count_Nop,
0801     RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
0802     RtemsMessageReqFlushPending_Post_Receivers_NA },
0803   { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_InvId,
0804     RtemsMessageReqFlushPending_Post_Count_Nop,
0805     RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
0806     RtemsMessageReqFlushPending_Post_Receivers_NA },
0807   { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_InvAddr,
0808     RtemsMessageReqFlushPending_Post_Count_Nop,
0809     RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
0810     RtemsMessageReqFlushPending_Post_Receivers_Nop },
0811   { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_InvId,
0812     RtemsMessageReqFlushPending_Post_Count_Nop,
0813     RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
0814     RtemsMessageReqFlushPending_Post_Receivers_Nop },
0815   { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
0816     RtemsMessageReqFlushPending_Post_Count_Zero,
0817     RtemsMessageReqFlushPending_Post_MsgQueue_Empty,
0818     RtemsMessageReqFlushPending_Post_Receivers_Nop },
0819   { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
0820     RtemsMessageReqFlushPending_Post_Count_Zero,
0821     RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
0822     RtemsMessageReqFlushPending_Post_Receivers_Nop },
0823   { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
0824     RtemsMessageReqFlushPending_Post_Count_Zero,
0825     RtemsMessageReqFlushPending_Post_MsgQueue_Empty,
0826     RtemsMessageReqFlushPending_Post_Receivers_NA },
0827   { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
0828     RtemsMessageReqFlushPending_Post_Count_Zero,
0829     RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
0830     RtemsMessageReqFlushPending_Post_Receivers_NA },
0831   { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
0832     RtemsMessageReqFlushPending_Post_Count_Set,
0833     RtemsMessageReqFlushPending_Post_MsgQueue_Empty,
0834     RtemsMessageReqFlushPending_Post_Receivers_NA },
0835   { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
0836     RtemsMessageReqFlushPending_Post_Count_Set,
0837     RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
0838     RtemsMessageReqFlushPending_Post_Receivers_NA }
0839 };
0840 
0841 static const uint8_t
0842 RtemsMessageReqFlushPending_Map[] = {
0843   5, 6, 7, 8, 0, 0, 9, 10, 4, 4, 2, 2, 0, 0, 2, 2, 3, 3, 1, 1, 0, 0, 1, 1, 3,
0844   3, 1, 1, 0, 0, 1, 1
0845 };
0846 
0847 static size_t RtemsMessageReqFlushPending_Scope(
0848   void  *arg,
0849   char  *buf,
0850   size_t n
0851 )
0852 {
0853   RtemsMessageReqFlushPending_Context *ctx;
0854 
0855   ctx = arg;
0856 
0857   if ( ctx->Map.in_action_loop ) {
0858     return T_get_scope(
0859       RtemsMessageReqFlushPending_PreDesc,
0860       buf,
0861       n,
0862       ctx->Map.pcs
0863     );
0864   }
0865 
0866   return 0;
0867 }
0868 
0869 static T_fixture RtemsMessageReqFlushPending_Fixture = {
0870   .setup = RtemsMessageReqFlushPending_Setup_Wrap,
0871   .stop = NULL,
0872   .teardown = RtemsMessageReqFlushPending_Teardown_Wrap,
0873   .scope = RtemsMessageReqFlushPending_Scope,
0874   .initial_context = &RtemsMessageReqFlushPending_Instance
0875 };
0876 
0877 static inline RtemsMessageReqFlushPending_Entry
0878 RtemsMessageReqFlushPending_PopEntry(
0879   RtemsMessageReqFlushPending_Context *ctx
0880 )
0881 {
0882   size_t index;
0883 
0884   index = ctx->Map.index;
0885   ctx->Map.index = index + 1;
0886   return RtemsMessageReqFlushPending_Entries[
0887     RtemsMessageReqFlushPending_Map[ index ]
0888   ];
0889 }
0890 
0891 static void RtemsMessageReqFlushPending_TestVariant(
0892   RtemsMessageReqFlushPending_Context *ctx
0893 )
0894 {
0895   RtemsMessageReqFlushPending_Pre_Count_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0896   RtemsMessageReqFlushPending_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0897   RtemsMessageReqFlushPending_Pre_MsgQueue_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0898   RtemsMessageReqFlushPending_Pre_Receivers_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0899   RtemsMessageReqFlushPending_Pre_Directive_Prepare( ctx, ctx->Map.pcs[ 4 ] );
0900   RtemsMessageReqFlushPending_Pre_Storage_Prepare( ctx, ctx->Map.pcs[ 5 ] );
0901   RtemsMessageReqFlushPending_Action( ctx );
0902   RtemsMessageReqFlushPending_Post_Status_Check(
0903     ctx,
0904     ctx->Map.entry.Post_Status
0905   );
0906   RtemsMessageReqFlushPending_Post_Count_Check(
0907     ctx,
0908     ctx->Map.entry.Post_Count
0909   );
0910   RtemsMessageReqFlushPending_Post_MsgQueue_Check(
0911     ctx,
0912     ctx->Map.entry.Post_MsgQueue
0913   );
0914   RtemsMessageReqFlushPending_Post_Receivers_Check(
0915     ctx,
0916     ctx->Map.entry.Post_Receivers
0917   );
0918 }
0919 
0920 /**
0921  * @fn void T_case_body_RtemsMessageReqFlushPending( void )
0922  */
0923 T_TEST_CASE_FIXTURE(
0924   RtemsMessageReqFlushPending,
0925   &RtemsMessageReqFlushPending_Fixture
0926 )
0927 {
0928   RtemsMessageReqFlushPending_Context *ctx;
0929 
0930   ctx = T_fixture_context();
0931   ctx->Map.in_action_loop = true;
0932   ctx->Map.index = 0;
0933 
0934   for (
0935     ctx->Map.pcs[ 0 ] = RtemsMessageReqFlushPending_Pre_Count_Valid;
0936     ctx->Map.pcs[ 0 ] < RtemsMessageReqFlushPending_Pre_Count_NA;
0937     ++ctx->Map.pcs[ 0 ]
0938   ) {
0939     for (
0940       ctx->Map.pcs[ 1 ] = RtemsMessageReqFlushPending_Pre_Id_Valid;
0941       ctx->Map.pcs[ 1 ] < RtemsMessageReqFlushPending_Pre_Id_NA;
0942       ++ctx->Map.pcs[ 1 ]
0943     ) {
0944       for (
0945         ctx->Map.pcs[ 2 ] = RtemsMessageReqFlushPending_Pre_MsgQueue_Empty;
0946         ctx->Map.pcs[ 2 ] < RtemsMessageReqFlushPending_Pre_MsgQueue_NA;
0947         ++ctx->Map.pcs[ 2 ]
0948       ) {
0949         for (
0950           ctx->Map.pcs[ 3 ] = RtemsMessageReqFlushPending_Pre_Receivers_Waiting;
0951           ctx->Map.pcs[ 3 ] < RtemsMessageReqFlushPending_Pre_Receivers_NA;
0952           ++ctx->Map.pcs[ 3 ]
0953         ) {
0954           for (
0955             ctx->Map.pcs[ 4 ] = RtemsMessageReqFlushPending_Pre_Directive_Flush;
0956             ctx->Map.pcs[ 4 ] < RtemsMessageReqFlushPending_Pre_Directive_NA;
0957             ++ctx->Map.pcs[ 4 ]
0958           ) {
0959             for (
0960               ctx->Map.pcs[ 5 ] = RtemsMessageReqFlushPending_Pre_Storage_Nop;
0961               ctx->Map.pcs[ 5 ] < RtemsMessageReqFlushPending_Pre_Storage_NA;
0962               ++ctx->Map.pcs[ 5 ]
0963             ) {
0964               ctx->Map.entry = RtemsMessageReqFlushPending_PopEntry( ctx );
0965 
0966               if ( ctx->Map.entry.Skip ) {
0967                 continue;
0968               }
0969 
0970               RtemsMessageReqFlushPending_Prepare( ctx );
0971               RtemsMessageReqFlushPending_TestVariant( ctx );
0972               RtemsMessageReqFlushPending_Cleanup( ctx );
0973             }
0974           }
0975         }
0976       }
0977     }
0978   }
0979 }
0980 
0981 /** @} */