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 RtemsMessageReqUrgentSend
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 RtemsMessageReqUrgentSend spec:/rtems/message/req/urgent-send
0063  *
0064  * @ingroup TestsuitesValidationNoClock0
0065  *
0066  * @{
0067  */
0068 
0069 typedef enum {
0070   RtemsMessageReqUrgentSend_Pre_Buffer_Valid,
0071   RtemsMessageReqUrgentSend_Pre_Buffer_Null,
0072   RtemsMessageReqUrgentSend_Pre_Buffer_NA
0073 } RtemsMessageReqUrgentSend_Pre_Buffer;
0074 
0075 typedef enum {
0076   RtemsMessageReqUrgentSend_Pre_Id_Valid,
0077   RtemsMessageReqUrgentSend_Pre_Id_Invalid,
0078   RtemsMessageReqUrgentSend_Pre_Id_NA
0079 } RtemsMessageReqUrgentSend_Pre_Id;
0080 
0081 typedef enum {
0082   RtemsMessageReqUrgentSend_Pre_Size_Zero,
0083   RtemsMessageReqUrgentSend_Pre_Size_SomeSize,
0084   RtemsMessageReqUrgentSend_Pre_Size_MaxSize,
0085   RtemsMessageReqUrgentSend_Pre_Size_TooLarge,
0086   RtemsMessageReqUrgentSend_Pre_Size_NA
0087 } RtemsMessageReqUrgentSend_Pre_Size;
0088 
0089 typedef enum {
0090   RtemsMessageReqUrgentSend_Pre_MsgQueue_Empty,
0091   RtemsMessageReqUrgentSend_Pre_MsgQueue_One,
0092   RtemsMessageReqUrgentSend_Pre_MsgQueue_Several,
0093   RtemsMessageReqUrgentSend_Pre_MsgQueue_Full,
0094   RtemsMessageReqUrgentSend_Pre_MsgQueue_NA
0095 } RtemsMessageReqUrgentSend_Pre_MsgQueue;
0096 
0097 typedef enum {
0098   RtemsMessageReqUrgentSend_Pre_Receiver_Waiting,
0099   RtemsMessageReqUrgentSend_Pre_Receiver_No,
0100   RtemsMessageReqUrgentSend_Pre_Receiver_NA
0101 } RtemsMessageReqUrgentSend_Pre_Receiver;
0102 
0103 typedef enum {
0104   RtemsMessageReqUrgentSend_Pre_Directive_Send,
0105   RtemsMessageReqUrgentSend_Pre_Directive_Urgent,
0106   RtemsMessageReqUrgentSend_Pre_Directive_NA
0107 } RtemsMessageReqUrgentSend_Pre_Directive;
0108 
0109 typedef enum {
0110   RtemsMessageReqUrgentSend_Pre_Storage_Nop,
0111   RtemsMessageReqUrgentSend_Pre_Storage_NA
0112 } RtemsMessageReqUrgentSend_Pre_Storage;
0113 
0114 typedef enum {
0115   RtemsMessageReqUrgentSend_Post_Status_Ok,
0116   RtemsMessageReqUrgentSend_Post_Status_InvId,
0117   RtemsMessageReqUrgentSend_Post_Status_InvAddr,
0118   RtemsMessageReqUrgentSend_Post_Status_InvSize,
0119   RtemsMessageReqUrgentSend_Post_Status_TooMany,
0120   RtemsMessageReqUrgentSend_Post_Status_NA
0121 } RtemsMessageReqUrgentSend_Post_Status;
0122 
0123 typedef enum {
0124   RtemsMessageReqUrgentSend_Post_MsgQueue_Empty,
0125   RtemsMessageReqUrgentSend_Post_MsgQueue_One,
0126   RtemsMessageReqUrgentSend_Post_MsgQueue_Prepend,
0127   RtemsMessageReqUrgentSend_Post_MsgQueue_Append,
0128   RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
0129   RtemsMessageReqUrgentSend_Post_MsgQueue_NA
0130 } RtemsMessageReqUrgentSend_Post_MsgQueue;
0131 
0132 typedef enum {
0133   RtemsMessageReqUrgentSend_Post_Receiver_GotMsg,
0134   RtemsMessageReqUrgentSend_Post_Receiver_Waiting,
0135   RtemsMessageReqUrgentSend_Post_Receiver_NA
0136 } RtemsMessageReqUrgentSend_Post_Receiver;
0137 
0138 typedef struct {
0139   uint16_t Skip : 1;
0140   uint16_t Pre_Buffer_NA : 1;
0141   uint16_t Pre_Id_NA : 1;
0142   uint16_t Pre_Size_NA : 1;
0143   uint16_t Pre_MsgQueue_NA : 1;
0144   uint16_t Pre_Receiver_NA : 1;
0145   uint16_t Pre_Directive_NA : 1;
0146   uint16_t Pre_Storage_NA : 1;
0147   uint16_t Post_Status : 3;
0148   uint16_t Post_MsgQueue : 3;
0149   uint16_t Post_Receiver : 2;
0150 } RtemsMessageReqUrgentSend_Entry;
0151 
0152 #define MAXIMUM_PENDING_MESSAGES 3
0153 #define MAXIMUM_MESSAGE_SIZE 5
0154 
0155 /**
0156  * @brief Test context for spec:/rtems/message/req/urgent-send test case.
0157  */
0158 typedef struct {
0159   /**
0160    * @brief This member contains a valid ID of a message queue.
0161    */
0162   rtems_id message_queue_id;
0163 
0164   /**
0165    * @brief This member is used as storage area for the message queue.
0166    */
0167   RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE )
0168     storage_area[ MAXIMUM_PENDING_MESSAGES];
0169 
0170   /**
0171    * @brief This member contains always the same arbitrary number ``magic``.
0172    *
0173    * It is used for run-time type checking.
0174    */
0175   uint32_t magic;
0176 
0177   /**
0178    * @brief This member contains a number which is sent as next message.
0179    */
0180   uint8_t send_msg_counter;
0181 
0182   /**
0183    * @brief This member contains a buffer to receive messages from the queue.
0184    */
0185   uint8_t receive_buffer[ MAXIMUM_MESSAGE_SIZE ];
0186 
0187   /**
0188    * @brief This member contains a buffer to receive the messages size.
0189    */
0190   size_t receive_size;
0191 
0192   /**
0193    * @brief This member contains the returned status code of the receiver.
0194    */
0195   rtems_status_code receive_status;
0196 
0197   /**
0198    * @brief This member indicates whether the a receiver task should be started
0199    *   to receive a message.
0200    */
0201   bool is_receiver_waiting;
0202 
0203   /**
0204    * @brief This member contains the message to be sent by the action.
0205    */
0206   uint8_t send_message[ MAXIMUM_MESSAGE_SIZE ];
0207 
0208   /**
0209    * @brief This member specifies the directive to be called as action.
0210    *
0211    * This is either rtems_message_queue_send() or rtems_message_queue_urgent().
0212    */
0213   rtems_status_code (*action)( rtems_id id, const void *buffer, size_t size );
0214 
0215   /**
0216    * @brief This member specifies the ``id`` parameter for the action.
0217    */
0218   rtems_id id_param;
0219 
0220   /**
0221    * @brief This member specifies the ``buffer`` parameter for the action.
0222    */
0223   void *buffer_param;
0224 
0225   /**
0226    * @brief This member specifies the ``size`` parameter for the action.
0227    */
0228   size_t size_param;
0229 
0230   /**
0231    * @brief This member contains the returned status code of the action.
0232    */
0233   rtems_status_code status;
0234 
0235   /**
0236    * @brief This member contains the task identifier of the worker task.
0237    */
0238   rtems_id worker_id;
0239 
0240   /**
0241    * @brief This member contains a pointer to a function which is executed to
0242    *   check that the action has not changed the content of the message queue.
0243    */
0244   void (*check_msgq_unchanged)( void *ctx_in );
0245 
0246   struct {
0247     /**
0248      * @brief This member defines the pre-condition states for the next action.
0249      */
0250     size_t pcs[ 7 ];
0251 
0252     /**
0253      * @brief If this member is true, then the test action loop is executed.
0254      */
0255     bool in_action_loop;
0256 
0257     /**
0258      * @brief This member contains the next transition map index.
0259      */
0260     size_t index;
0261 
0262     /**
0263      * @brief This member contains the current transition map entry.
0264      */
0265     RtemsMessageReqUrgentSend_Entry entry;
0266 
0267     /**
0268      * @brief If this member is true, then the current transition variant
0269      *   should be skipped.
0270      */
0271     bool skip;
0272   } Map;
0273 } RtemsMessageReqUrgentSend_Context;
0274 
0275 static RtemsMessageReqUrgentSend_Context
0276   RtemsMessageReqUrgentSend_Instance;
0277 
0278 static const char * const RtemsMessageReqUrgentSend_PreDesc_Buffer[] = {
0279   "Valid",
0280   "Null",
0281   "NA"
0282 };
0283 
0284 static const char * const RtemsMessageReqUrgentSend_PreDesc_Id[] = {
0285   "Valid",
0286   "Invalid",
0287   "NA"
0288 };
0289 
0290 static const char * const RtemsMessageReqUrgentSend_PreDesc_Size[] = {
0291   "Zero",
0292   "SomeSize",
0293   "MaxSize",
0294   "TooLarge",
0295   "NA"
0296 };
0297 
0298 static const char * const RtemsMessageReqUrgentSend_PreDesc_MsgQueue[] = {
0299   "Empty",
0300   "One",
0301   "Several",
0302   "Full",
0303   "NA"
0304 };
0305 
0306 static const char * const RtemsMessageReqUrgentSend_PreDesc_Receiver[] = {
0307   "Waiting",
0308   "No",
0309   "NA"
0310 };
0311 
0312 static const char * const RtemsMessageReqUrgentSend_PreDesc_Directive[] = {
0313   "Send",
0314   "Urgent",
0315   "NA"
0316 };
0317 
0318 static const char * const RtemsMessageReqUrgentSend_PreDesc_Storage[] = {
0319   "Nop",
0320   "NA"
0321 };
0322 
0323 static const char * const * const RtemsMessageReqUrgentSend_PreDesc[] = {
0324   RtemsMessageReqUrgentSend_PreDesc_Buffer,
0325   RtemsMessageReqUrgentSend_PreDesc_Id,
0326   RtemsMessageReqUrgentSend_PreDesc_Size,
0327   RtemsMessageReqUrgentSend_PreDesc_MsgQueue,
0328   RtemsMessageReqUrgentSend_PreDesc_Receiver,
0329   RtemsMessageReqUrgentSend_PreDesc_Directive,
0330   RtemsMessageReqUrgentSend_PreDesc_Storage,
0331   NULL
0332 };
0333 
0334 typedef RtemsMessageReqUrgentSend_Context Context;
0335 static const uint32_t MAGIC = 0xA66FE31; /* an arbitrary number */
0336 static const rtems_interval TIMEOUT_TICKS = 1;
0337 static const rtems_event_set EVENT_RECEIVE = RTEMS_EVENT_17;
0338 
0339 static void Receive( Context *ctx )
0340 {
0341   ctx->receive_status = rtems_message_queue_receive(
0342     ctx->message_queue_id,
0343     ctx->receive_buffer,
0344     &ctx->receive_size,
0345     RTEMS_WAIT,
0346     TIMEOUT_TICKS
0347   );
0348 }
0349 
0350 static void WorkerTask( rtems_task_argument argument )
0351 {
0352   Context *ctx = (Context *) argument;
0353 
0354   while ( true ) {
0355     rtems_event_set events;
0356 
0357     events = ReceiveAnyEvents();
0358 
0359     if ( ( events & EVENT_RECEIVE ) != 0 ) {
0360       Receive( ctx );
0361     }
0362   }
0363 }
0364 
0365 static void CheckForNoMessage(
0366   Context *ctx,
0367   rtems_status_code status,
0368   uint8_t *message_buffer,
0369   size_t message_size
0370 )
0371 {
0372   (void) ctx;
0373   T_rsc( status, RTEMS_UNSATISFIED  );
0374 }
0375 
0376 static void CheckForFirstMessage(
0377   Context *ctx,
0378   rtems_status_code status,
0379   uint8_t *message_buffer,
0380   size_t message_size
0381 )
0382 {
0383   (void) ctx;
0384   T_rsc_success( status );
0385   T_eq_u32( message_size, 1 );
0386   T_eq_u8( message_buffer[0], 0 );
0387 }
0388 
0389 static void CheckForSecondMessage(
0390   Context *ctx,
0391   rtems_status_code status,
0392   uint8_t *message_buffer,
0393   size_t message_size
0394 )
0395 {
0396   (void) ctx;
0397   T_rsc_success( status );
0398   T_eq_u32( message_size, 3 );
0399   T_eq_u8( message_buffer[0], 1 );
0400   T_eq_u8( message_buffer[1], 1 );
0401   T_eq_u8( message_buffer[2], 1 );
0402 }
0403 
0404 static void CheckForThirdMessage(
0405   Context *ctx,
0406   rtems_status_code status,
0407   uint8_t *message_buffer,
0408   size_t message_size
0409 )
0410 {
0411   (void) ctx;
0412   T_rsc_success( status );
0413   T_eq_u32( message_size, 5 );
0414   T_eq_u8( message_buffer[0], 2 );
0415   T_eq_u8( message_buffer[1], 2 );
0416   T_eq_u8( message_buffer[2], 2 );
0417   T_eq_u8( message_buffer[3], 2 );
0418   T_eq_u8( message_buffer[4], 2 );
0419 }
0420 
0421 static void CheckForSendMessage(
0422   Context *ctx,
0423   rtems_status_code status,
0424   uint8_t *message_buffer,
0425   size_t message_size
0426 )
0427 {
0428   size_t i;
0429   T_rsc_success( status );
0430   T_eq_u32( message_size, ctx->size_param );
0431   for ( i = 0; i < ctx->size_param; ++i ) {
0432     T_eq_u8( message_buffer[i], ctx->send_message[i] );
0433   }
0434 }
0435 
0436 static void PopMessage(
0437   Context *ctx,
0438   void (*check_fn)(
0439     Context *ctx,
0440     rtems_status_code status,
0441     uint8_t *message_buffer,
0442     size_t message_size
0443   )
0444 )
0445 {
0446   rtems_status_code status;
0447   uint8_t message_buffer[ MAXIMUM_MESSAGE_SIZE ];
0448   size_t message_size;
0449 
0450   status = rtems_message_queue_receive(
0451     ctx->message_queue_id,
0452     &message_buffer,
0453     &message_size,
0454     RTEMS_LOCAL | RTEMS_NO_WAIT,
0455     RTEMS_NO_TIMEOUT
0456   );
0457 
0458  check_fn( ctx, status, message_buffer, message_size );
0459 }
0460 
0461 static void CheckForNoMessageInQueue( void *ctx_in )
0462 {}
0463 
0464 static void CheckForOneMessageInQueue( void *ctx_in )
0465 {
0466   Context *ctx = ctx_in;
0467   T_assert_eq_u32( ctx->magic, MAGIC ); /* Run-time type check */
0468   PopMessage( ctx, CheckForFirstMessage );
0469 }
0470 
0471 static void CheckForSeveralMessagesInQueue( void *ctx_in )
0472 {
0473   Context *ctx = ctx_in;
0474   T_assert_eq_u32( ctx->magic, MAGIC ); /* Run-time type check */
0475   PopMessage( ctx, CheckForFirstMessage );
0476   PopMessage( ctx, CheckForSecondMessage );
0477 }
0478 
0479 static void CheckForAllMessagesInQueue( void *ctx_in )
0480 {
0481   Context *ctx = ctx_in;
0482   T_assert_eq_u32( ctx->magic, MAGIC ); /* Run-time type check */
0483   PopMessage( ctx, CheckForFirstMessage );
0484   PopMessage( ctx, CheckForSecondMessage );
0485   PopMessage( ctx, CheckForThirdMessage );
0486 }
0487 
0488 static void SendMsg( Context *ctx )
0489 {
0490   rtems_status_code status;
0491   uint8_t msg[ MAXIMUM_MESSAGE_SIZE ];
0492 
0493   memset( msg, ctx->send_msg_counter, MAXIMUM_MESSAGE_SIZE );
0494   status = rtems_message_queue_send(
0495     ctx->message_queue_id,
0496     msg,
0497     ( ctx->send_msg_counter * 2 ) % MAXIMUM_MESSAGE_SIZE + 1
0498   );
0499   T_rsc_success( status );
0500   ++ctx->send_msg_counter;
0501 }
0502 
0503 static void RtemsMessageReqUrgentSend_Pre_Buffer_Prepare(
0504   RtemsMessageReqUrgentSend_Context   *ctx,
0505   RtemsMessageReqUrgentSend_Pre_Buffer state
0506 )
0507 {
0508   switch ( state ) {
0509     case RtemsMessageReqUrgentSend_Pre_Buffer_Valid: {
0510       /*
0511        * While the ``buffer`` parameter references a memory area where the
0512        * message to be sent is stored.
0513        */
0514       uint8_t i;
0515       for ( i = 0; i < MAXIMUM_MESSAGE_SIZE; ++i ) {
0516         ctx->send_message[i] = 42 + i;
0517       }
0518       ctx->buffer_param = &ctx->send_message;
0519       break;
0520     }
0521 
0522     case RtemsMessageReqUrgentSend_Pre_Buffer_Null: {
0523       /*
0524        * While the ``buffer`` parameter is NULL.
0525        */
0526       ctx->buffer_param = NULL;
0527       break;
0528     }
0529 
0530     case RtemsMessageReqUrgentSend_Pre_Buffer_NA:
0531       break;
0532   }
0533 }
0534 
0535 static void RtemsMessageReqUrgentSend_Pre_Id_Prepare(
0536   RtemsMessageReqUrgentSend_Context *ctx,
0537   RtemsMessageReqUrgentSend_Pre_Id   state
0538 )
0539 {
0540   switch ( state ) {
0541     case RtemsMessageReqUrgentSend_Pre_Id_Valid: {
0542       /*
0543        * While the ``id`` parameter is valid.
0544        */
0545       ctx->id_param = ctx->message_queue_id;
0546       break;
0547     }
0548 
0549     case RtemsMessageReqUrgentSend_Pre_Id_Invalid: {
0550       /*
0551        * While the ``id`` parameter is invalid.
0552        */
0553       ctx->id_param = RTEMS_ID_NONE;
0554       break;
0555     }
0556 
0557     case RtemsMessageReqUrgentSend_Pre_Id_NA:
0558       break;
0559   }
0560 }
0561 
0562 static void RtemsMessageReqUrgentSend_Pre_Size_Prepare(
0563   RtemsMessageReqUrgentSend_Context *ctx,
0564   RtemsMessageReqUrgentSend_Pre_Size state
0565 )
0566 {
0567   switch ( state ) {
0568     case RtemsMessageReqUrgentSend_Pre_Size_Zero: {
0569       /*
0570        * While the ``size`` parameter is 0.
0571        */
0572       ctx->size_param = 0;
0573       break;
0574     }
0575 
0576     case RtemsMessageReqUrgentSend_Pre_Size_SomeSize: {
0577       /*
0578        * While the ``size`` parameter has a value between 0 and the maximum
0579        * message size.
0580        */
0581       ctx->size_param = MAXIMUM_MESSAGE_SIZE / 2 + 1;
0582       break;
0583     }
0584 
0585     case RtemsMessageReqUrgentSend_Pre_Size_MaxSize: {
0586       /*
0587        * While the ``size`` parameter has a value of the maximum message size.
0588        */
0589       ctx->size_param = MAXIMUM_MESSAGE_SIZE;
0590       break;
0591     }
0592 
0593     case RtemsMessageReqUrgentSend_Pre_Size_TooLarge: {
0594       /*
0595        * While the ``size`` parameter has a value greater than the maximum
0596        * message size.
0597        */
0598       ctx->size_param = MAXIMUM_MESSAGE_SIZE + 1;
0599       break;
0600     }
0601 
0602     case RtemsMessageReqUrgentSend_Pre_Size_NA:
0603       break;
0604   }
0605 }
0606 
0607 static void RtemsMessageReqUrgentSend_Pre_MsgQueue_Prepare(
0608   RtemsMessageReqUrgentSend_Context     *ctx,
0609   RtemsMessageReqUrgentSend_Pre_MsgQueue state
0610 )
0611 {
0612   switch ( state ) {
0613     case RtemsMessageReqUrgentSend_Pre_MsgQueue_Empty: {
0614       /*
0615        * While there is no message in the message queue.
0616        */
0617       /* Message queue is already empty. */
0618       ctx->check_msgq_unchanged = CheckForNoMessageInQueue;
0619       break;
0620     }
0621 
0622     case RtemsMessageReqUrgentSend_Pre_MsgQueue_One: {
0623       /*
0624        * While there is exactly one message in the message queue.
0625        */
0626       SendMsg( ctx );
0627       ctx->check_msgq_unchanged = CheckForOneMessageInQueue;
0628       break;
0629     }
0630 
0631     case RtemsMessageReqUrgentSend_Pre_MsgQueue_Several: {
0632       /*
0633        * While there are more than one and less than maximum pending messages
0634        * in the message queue.
0635        */
0636       SendMsg( ctx );
0637       SendMsg( ctx );
0638       ctx->check_msgq_unchanged = CheckForSeveralMessagesInQueue;
0639       break;
0640     }
0641 
0642     case RtemsMessageReqUrgentSend_Pre_MsgQueue_Full: {
0643       /*
0644        * While there are maximum pending messages in the message queue.
0645        */
0646       SendMsg( ctx );
0647       SendMsg( ctx );
0648       SendMsg( ctx );
0649       ctx->check_msgq_unchanged = CheckForAllMessagesInQueue;
0650       break;
0651     }
0652 
0653     case RtemsMessageReqUrgentSend_Pre_MsgQueue_NA:
0654       break;
0655   }
0656 }
0657 
0658 static void RtemsMessageReqUrgentSend_Pre_Receiver_Prepare(
0659   RtemsMessageReqUrgentSend_Context     *ctx,
0660   RtemsMessageReqUrgentSend_Pre_Receiver state
0661 )
0662 {
0663   switch ( state ) {
0664     case RtemsMessageReqUrgentSend_Pre_Receiver_Waiting: {
0665       /*
0666        * While a receiver is waiting to receive a message.
0667        */
0668       ctx->is_receiver_waiting = true;
0669       break;
0670     }
0671 
0672     case RtemsMessageReqUrgentSend_Pre_Receiver_No: {
0673       /*
0674        * While no receiver is waiting to receive a message.
0675        */
0676       ctx->is_receiver_waiting = false;
0677       break;
0678     }
0679 
0680     case RtemsMessageReqUrgentSend_Pre_Receiver_NA:
0681       break;
0682   }
0683 }
0684 
0685 static void RtemsMessageReqUrgentSend_Pre_Directive_Prepare(
0686   RtemsMessageReqUrgentSend_Context      *ctx,
0687   RtemsMessageReqUrgentSend_Pre_Directive state
0688 )
0689 {
0690   switch ( state ) {
0691     case RtemsMessageReqUrgentSend_Pre_Directive_Send: {
0692       /*
0693        * While the directive rtems_message_queue_send() is called.
0694        */
0695       ctx->action = rtems_message_queue_send;
0696       break;
0697     }
0698 
0699     case RtemsMessageReqUrgentSend_Pre_Directive_Urgent: {
0700       /*
0701        * While the directive rtems_message_queue_urgent() is called.
0702        */
0703       ctx->action = rtems_message_queue_urgent;
0704       break;
0705     }
0706 
0707     case RtemsMessageReqUrgentSend_Pre_Directive_NA:
0708       break;
0709   }
0710 }
0711 
0712 static void RtemsMessageReqUrgentSend_Pre_Storage_Prepare(
0713   RtemsMessageReqUrgentSend_Context    *ctx,
0714   RtemsMessageReqUrgentSend_Pre_Storage state
0715 )
0716 {
0717   switch ( state ) {
0718     case RtemsMessageReqUrgentSend_Pre_Storage_Nop: {
0719       /*
0720        * While the memory area to which a pointer is provided as member
0721        * storage_area of type rtems_message_queue_config when the message queue
0722        * is constructed by rtems_message_queue_construct() is altered only by
0723        * the RTEMS operating system.
0724        */
0725       /* Only a requirement text. */
0726       break;
0727     }
0728 
0729     case RtemsMessageReqUrgentSend_Pre_Storage_NA:
0730       break;
0731   }
0732 }
0733 
0734 static void RtemsMessageReqUrgentSend_Post_Status_Check(
0735   RtemsMessageReqUrgentSend_Context    *ctx,
0736   RtemsMessageReqUrgentSend_Post_Status state
0737 )
0738 {
0739   switch ( state ) {
0740     case RtemsMessageReqUrgentSend_Post_Status_Ok: {
0741       /*
0742        * The return status of the called directive (rtems_message_queue_send()
0743        * or rtems_message_queue_urgent()) shall be RTEMS_SUCCESSFUL
0744        */
0745       T_rsc_success( ctx->status );
0746       break;
0747     }
0748 
0749     case RtemsMessageReqUrgentSend_Post_Status_InvId: {
0750       /*
0751        * The return status of the called directive (rtems_message_queue_send()
0752        * or rtems_message_queue_urgent()) shall be RTEMS_INVALID_ID.
0753        */
0754       T_rsc( ctx->status, RTEMS_INVALID_ID );
0755       break;
0756     }
0757 
0758     case RtemsMessageReqUrgentSend_Post_Status_InvAddr: {
0759       /*
0760        * The return status of the called directive (rtems_message_queue_send()
0761        * or rtems_message_queue_urgent()) shall be RTEMS_INVALID_ADDRESS.
0762        */
0763       T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0764       break;
0765     }
0766 
0767     case RtemsMessageReqUrgentSend_Post_Status_InvSize: {
0768       /*
0769        * The return status of the called directive (rtems_message_queue_send()
0770        * or rtems_message_queue_urgent()) shall be RTEMS_INVALID_SIZE.
0771        */
0772       T_rsc( ctx->status, RTEMS_INVALID_SIZE );
0773       break;
0774     }
0775 
0776     case RtemsMessageReqUrgentSend_Post_Status_TooMany: {
0777       /*
0778        * The return status of the called directive (rtems_message_queue_send()
0779        * or rtems_message_queue_urgent()) shall be RTEMS_TOO_MANY.
0780        */
0781       T_rsc( ctx->status, RTEMS_TOO_MANY );
0782       break;
0783     }
0784 
0785     case RtemsMessageReqUrgentSend_Post_Status_NA:
0786       break;
0787   }
0788 }
0789 
0790 static void RtemsMessageReqUrgentSend_Post_MsgQueue_Check(
0791   RtemsMessageReqUrgentSend_Context      *ctx,
0792   RtemsMessageReqUrgentSend_Post_MsgQueue state
0793 )
0794 {
0795   switch ( state ) {
0796     case RtemsMessageReqUrgentSend_Post_MsgQueue_Empty: {
0797       /*
0798        * The message queue shall be empty after the return of the
0799        * rtems_message_queue_send() or rtems_message_queue_urgent() call.
0800        */
0801       PopMessage( ctx, CheckForNoMessage );
0802       break;
0803     }
0804 
0805     case RtemsMessageReqUrgentSend_Post_MsgQueue_One: {
0806       /*
0807        * The message queue shall contain only the send message after the return
0808        * of the rtems_message_queue_send() or rtems_message_queue_urgent()
0809        * call.
0810        */
0811       PopMessage( ctx, CheckForSendMessage );
0812       PopMessage( ctx, CheckForNoMessage );
0813       break;
0814     }
0815 
0816     case RtemsMessageReqUrgentSend_Post_MsgQueue_Prepend: {
0817       /*
0818        * The message queue shall contain the message send by the last call to
0819        * rtems_message_queue_urgent() as first message followed by all the
0820        * messages which were in the message queue before that call (in the same
0821        * order and each message with the same content and size).
0822        */
0823       PopMessage( ctx, CheckForSendMessage );
0824       ctx->check_msgq_unchanged( ctx );
0825       PopMessage( ctx, CheckForNoMessage );
0826       break;
0827     }
0828 
0829     case RtemsMessageReqUrgentSend_Post_MsgQueue_Append: {
0830       /*
0831        * The message queue shall contain the message send by the last call to
0832        * rtems_message_queue_send() as last message preceded by all the
0833        * messages which were in the message queue before that call (in the same
0834        * order and each message with the same content and size).
0835        */
0836       ctx->check_msgq_unchanged( ctx );
0837       PopMessage( ctx, CheckForSendMessage );
0838       PopMessage( ctx, CheckForNoMessage );
0839       break;
0840     }
0841 
0842     case RtemsMessageReqUrgentSend_Post_MsgQueue_Nop: {
0843       /*
0844        * Objects referenced by the ``id`` parameter in past call to
0845        * rtems_message_queue_send() or rtems_message_queue_urgent() shall not
0846        * be accessed by that call (see also Nop).
0847        */
0848       ctx->check_msgq_unchanged( ctx );
0849       PopMessage( ctx, CheckForNoMessage );
0850       break;
0851     }
0852 
0853     case RtemsMessageReqUrgentSend_Post_MsgQueue_NA:
0854       break;
0855   }
0856 }
0857 
0858 static void RtemsMessageReqUrgentSend_Post_Receiver_Check(
0859   RtemsMessageReqUrgentSend_Context      *ctx,
0860   RtemsMessageReqUrgentSend_Post_Receiver state
0861 )
0862 {
0863   switch ( state ) {
0864     case RtemsMessageReqUrgentSend_Post_Receiver_GotMsg: {
0865       /*
0866        * The receiver shall receive the message send by the last call to the
0867        * rtems_message_queue_send() or rtems_message_queue_urgent() directive.
0868        */
0869       CheckForSendMessage(
0870         ctx,
0871         ctx->receive_status,
0872         ctx->receive_buffer,
0873         ctx->receive_size
0874       );
0875       break;
0876     }
0877 
0878     case RtemsMessageReqUrgentSend_Post_Receiver_Waiting: {
0879       /*
0880        * The receiver shall still wait to receive a message after the last call
0881        * to the rtems_message_queue_send() or rtems_message_queue_urgent()
0882        * directive.
0883        */
0884       T_rsc( ctx->receive_status, RTEMS_TIMEOUT );
0885       break;
0886     }
0887 
0888     case RtemsMessageReqUrgentSend_Post_Receiver_NA:
0889       break;
0890   }
0891 }
0892 
0893 static void RtemsMessageReqUrgentSend_Setup(
0894   RtemsMessageReqUrgentSend_Context *ctx
0895 )
0896 {
0897   ctx->magic   = MAGIC;
0898 
0899   SetSelfPriority( PRIO_NORMAL );
0900   ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
0901   StartTask( ctx->worker_id, WorkerTask, ctx );
0902 }
0903 
0904 static void RtemsMessageReqUrgentSend_Setup_Wrap( void *arg )
0905 {
0906   RtemsMessageReqUrgentSend_Context *ctx;
0907 
0908   ctx = arg;
0909   ctx->Map.in_action_loop = false;
0910   RtemsMessageReqUrgentSend_Setup( ctx );
0911 }
0912 
0913 static void RtemsMessageReqUrgentSend_Teardown(
0914   RtemsMessageReqUrgentSend_Context *ctx
0915 )
0916 {
0917   DeleteTask( ctx->worker_id );
0918   RestoreRunnerPriority();
0919 }
0920 
0921 static void RtemsMessageReqUrgentSend_Teardown_Wrap( void *arg )
0922 {
0923   RtemsMessageReqUrgentSend_Context *ctx;
0924 
0925   ctx = arg;
0926   ctx->Map.in_action_loop = false;
0927   RtemsMessageReqUrgentSend_Teardown( ctx );
0928 }
0929 
0930 static void RtemsMessageReqUrgentSend_Prepare(
0931   RtemsMessageReqUrgentSend_Context *ctx
0932 )
0933 {
0934   rtems_status_code status;
0935 
0936   ctx->send_msg_counter = 0;
0937 
0938   rtems_message_queue_config config = {
0939     .name                     = rtems_build_name( 'M', 'S', 'G', 'Q' ),
0940     .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES,
0941     .maximum_message_size     = MAXIMUM_MESSAGE_SIZE,
0942     .storage_area             = ctx->storage_area,
0943     .storage_size             = sizeof( ctx->storage_area ),
0944     .storage_free             = NULL,
0945     .attributes               = RTEMS_DEFAULT_ATTRIBUTES
0946   };
0947 
0948   status = rtems_message_queue_construct(
0949     &config,
0950     &ctx->message_queue_id
0951   );
0952   T_rsc_success( status );
0953 }
0954 
0955 static void RtemsMessageReqUrgentSend_Action(
0956   RtemsMessageReqUrgentSend_Context *ctx
0957 )
0958 {
0959   if ( ctx->is_receiver_waiting ) {
0960     SendEvents( ctx->worker_id, EVENT_RECEIVE );
0961   }
0962 
0963   ctx->status = (ctx->action)(
0964     ctx->id_param,
0965     ctx->buffer_param,
0966     ctx->size_param
0967   );
0968 
0969   if ( ctx->is_receiver_waiting ) {
0970     FinalClockTick();
0971   }
0972 }
0973 
0974 static void RtemsMessageReqUrgentSend_Cleanup(
0975   RtemsMessageReqUrgentSend_Context *ctx
0976 )
0977 {
0978   T_rsc_success( rtems_message_queue_delete( ctx->message_queue_id ) );
0979 }
0980 
0981 static const RtemsMessageReqUrgentSend_Entry
0982 RtemsMessageReqUrgentSend_Entries[] = {
0983   { 1, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_NA,
0984     RtemsMessageReqUrgentSend_Post_MsgQueue_NA,
0985     RtemsMessageReqUrgentSend_Post_Receiver_NA },
0986   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvAddr,
0987     RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
0988     RtemsMessageReqUrgentSend_Post_Receiver_NA },
0989   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvId,
0990     RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
0991     RtemsMessageReqUrgentSend_Post_Receiver_NA },
0992   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvAddr,
0993     RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
0994     RtemsMessageReqUrgentSend_Post_Receiver_Waiting },
0995   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvSize,
0996     RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
0997     RtemsMessageReqUrgentSend_Post_Receiver_NA },
0998   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvId,
0999     RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
1000     RtemsMessageReqUrgentSend_Post_Receiver_Waiting },
1001   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_Ok,
1002     RtemsMessageReqUrgentSend_Post_MsgQueue_Empty,
1003     RtemsMessageReqUrgentSend_Post_Receiver_GotMsg },
1004   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_Ok,
1005     RtemsMessageReqUrgentSend_Post_MsgQueue_One,
1006     RtemsMessageReqUrgentSend_Post_Receiver_NA },
1007   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_Ok,
1008     RtemsMessageReqUrgentSend_Post_MsgQueue_Append,
1009     RtemsMessageReqUrgentSend_Post_Receiver_NA },
1010   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_Ok,
1011     RtemsMessageReqUrgentSend_Post_MsgQueue_Prepend,
1012     RtemsMessageReqUrgentSend_Post_Receiver_NA },
1013   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_TooMany,
1014     RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
1015     RtemsMessageReqUrgentSend_Post_Receiver_NA },
1016   { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvSize,
1017     RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
1018     RtemsMessageReqUrgentSend_Post_Receiver_Waiting }
1019 };
1020 
1021 static const uint8_t
1022 RtemsMessageReqUrgentSend_Map[] = {
1023   6, 6, 7, 7, 0, 0, 8, 9, 0, 0, 8, 9, 0, 0, 10, 10, 6, 6, 7, 7, 0, 0, 8, 9, 0,
1024   0, 8, 9, 0, 0, 10, 10, 6, 6, 7, 7, 0, 0, 8, 9, 0, 0, 8, 9, 0, 0, 10, 10, 11,
1025   11, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 5, 5, 2, 2, 0, 0, 2, 2, 0, 0,
1026   2, 2, 0, 0, 2, 2, 5, 5, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 5, 5, 2, 2,
1027   0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 5, 5, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0,
1028   2, 2, 3, 3, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 1, 1, 0, 0, 1, 1,
1029   0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3,
1030   1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
1031   0, 0, 1, 1, 3, 3, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 1, 1, 0, 0,
1032   1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1
1033 };
1034 
1035 static size_t RtemsMessageReqUrgentSend_Scope( void *arg, char *buf, size_t n )
1036 {
1037   RtemsMessageReqUrgentSend_Context *ctx;
1038 
1039   ctx = arg;
1040 
1041   if ( ctx->Map.in_action_loop ) {
1042     return T_get_scope(
1043       RtemsMessageReqUrgentSend_PreDesc,
1044       buf,
1045       n,
1046       ctx->Map.pcs
1047     );
1048   }
1049 
1050   return 0;
1051 }
1052 
1053 static T_fixture RtemsMessageReqUrgentSend_Fixture = {
1054   .setup = RtemsMessageReqUrgentSend_Setup_Wrap,
1055   .stop = NULL,
1056   .teardown = RtemsMessageReqUrgentSend_Teardown_Wrap,
1057   .scope = RtemsMessageReqUrgentSend_Scope,
1058   .initial_context = &RtemsMessageReqUrgentSend_Instance
1059 };
1060 
1061 static inline RtemsMessageReqUrgentSend_Entry
1062 RtemsMessageReqUrgentSend_PopEntry( RtemsMessageReqUrgentSend_Context *ctx )
1063 {
1064   size_t index;
1065 
1066   index = ctx->Map.index;
1067   ctx->Map.index = index + 1;
1068   return RtemsMessageReqUrgentSend_Entries[
1069     RtemsMessageReqUrgentSend_Map[ index ]
1070   ];
1071 }
1072 
1073 static void RtemsMessageReqUrgentSend_TestVariant(
1074   RtemsMessageReqUrgentSend_Context *ctx
1075 )
1076 {
1077   RtemsMessageReqUrgentSend_Pre_Buffer_Prepare( ctx, ctx->Map.pcs[ 0 ] );
1078   RtemsMessageReqUrgentSend_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
1079   RtemsMessageReqUrgentSend_Pre_Size_Prepare( ctx, ctx->Map.pcs[ 2 ] );
1080   RtemsMessageReqUrgentSend_Pre_MsgQueue_Prepare( ctx, ctx->Map.pcs[ 3 ] );
1081   RtemsMessageReqUrgentSend_Pre_Receiver_Prepare( ctx, ctx->Map.pcs[ 4 ] );
1082   RtemsMessageReqUrgentSend_Pre_Directive_Prepare( ctx, ctx->Map.pcs[ 5 ] );
1083   RtemsMessageReqUrgentSend_Pre_Storage_Prepare( ctx, ctx->Map.pcs[ 6 ] );
1084   RtemsMessageReqUrgentSend_Action( ctx );
1085   RtemsMessageReqUrgentSend_Post_Status_Check(
1086     ctx,
1087     ctx->Map.entry.Post_Status
1088   );
1089   RtemsMessageReqUrgentSend_Post_MsgQueue_Check(
1090     ctx,
1091     ctx->Map.entry.Post_MsgQueue
1092   );
1093   RtemsMessageReqUrgentSend_Post_Receiver_Check(
1094     ctx,
1095     ctx->Map.entry.Post_Receiver
1096   );
1097 }
1098 
1099 /**
1100  * @fn void T_case_body_RtemsMessageReqUrgentSend( void )
1101  */
1102 T_TEST_CASE_FIXTURE(
1103   RtemsMessageReqUrgentSend,
1104   &RtemsMessageReqUrgentSend_Fixture
1105 )
1106 {
1107   RtemsMessageReqUrgentSend_Context *ctx;
1108 
1109   ctx = T_fixture_context();
1110   ctx->Map.in_action_loop = true;
1111   ctx->Map.index = 0;
1112 
1113   for (
1114     ctx->Map.pcs[ 0 ] = RtemsMessageReqUrgentSend_Pre_Buffer_Valid;
1115     ctx->Map.pcs[ 0 ] < RtemsMessageReqUrgentSend_Pre_Buffer_NA;
1116     ++ctx->Map.pcs[ 0 ]
1117   ) {
1118     for (
1119       ctx->Map.pcs[ 1 ] = RtemsMessageReqUrgentSend_Pre_Id_Valid;
1120       ctx->Map.pcs[ 1 ] < RtemsMessageReqUrgentSend_Pre_Id_NA;
1121       ++ctx->Map.pcs[ 1 ]
1122     ) {
1123       for (
1124         ctx->Map.pcs[ 2 ] = RtemsMessageReqUrgentSend_Pre_Size_Zero;
1125         ctx->Map.pcs[ 2 ] < RtemsMessageReqUrgentSend_Pre_Size_NA;
1126         ++ctx->Map.pcs[ 2 ]
1127       ) {
1128         for (
1129           ctx->Map.pcs[ 3 ] = RtemsMessageReqUrgentSend_Pre_MsgQueue_Empty;
1130           ctx->Map.pcs[ 3 ] < RtemsMessageReqUrgentSend_Pre_MsgQueue_NA;
1131           ++ctx->Map.pcs[ 3 ]
1132         ) {
1133           for (
1134             ctx->Map.pcs[ 4 ] = RtemsMessageReqUrgentSend_Pre_Receiver_Waiting;
1135             ctx->Map.pcs[ 4 ] < RtemsMessageReqUrgentSend_Pre_Receiver_NA;
1136             ++ctx->Map.pcs[ 4 ]
1137           ) {
1138             for (
1139               ctx->Map.pcs[ 5 ] = RtemsMessageReqUrgentSend_Pre_Directive_Send;
1140               ctx->Map.pcs[ 5 ] < RtemsMessageReqUrgentSend_Pre_Directive_NA;
1141               ++ctx->Map.pcs[ 5 ]
1142             ) {
1143               for (
1144                 ctx->Map.pcs[ 6 ] = RtemsMessageReqUrgentSend_Pre_Storage_Nop;
1145                 ctx->Map.pcs[ 6 ] < RtemsMessageReqUrgentSend_Pre_Storage_NA;
1146                 ++ctx->Map.pcs[ 6 ]
1147               ) {
1148                 ctx->Map.entry = RtemsMessageReqUrgentSend_PopEntry( ctx );
1149 
1150                 if ( ctx->Map.entry.Skip ) {
1151                   continue;
1152                 }
1153 
1154                 RtemsMessageReqUrgentSend_Prepare( ctx );
1155                 RtemsMessageReqUrgentSend_TestVariant( ctx );
1156                 RtemsMessageReqUrgentSend_Cleanup( ctx );
1157               }
1158             }
1159           }
1160         }
1161       }
1162     }
1163   }
1164 }
1165 
1166 /** @} */