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 RtemsSignalReqCatch
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 #include <rtems/score/smpbarrier.h>
0058 
0059 #include "tx-support.h"
0060 
0061 #include <rtems/test.h>
0062 
0063 /**
0064  * @defgroup RtemsSignalReqCatch spec:/rtems/signal/req/catch
0065  *
0066  * @ingroup TestsuitesValidationNoClock0
0067  * @ingroup TestsuitesValidationOneCpu0
0068  *
0069  * @{
0070  */
0071 
0072 typedef enum {
0073   RtemsSignalReqCatch_Pre_Pending_Yes,
0074   RtemsSignalReqCatch_Pre_Pending_No,
0075   RtemsSignalReqCatch_Pre_Pending_NA
0076 } RtemsSignalReqCatch_Pre_Pending;
0077 
0078 typedef enum {
0079   RtemsSignalReqCatch_Pre_Handler_Invalid,
0080   RtemsSignalReqCatch_Pre_Handler_Valid,
0081   RtemsSignalReqCatch_Pre_Handler_NA
0082 } RtemsSignalReqCatch_Pre_Handler;
0083 
0084 typedef enum {
0085   RtemsSignalReqCatch_Pre_Preempt_Yes,
0086   RtemsSignalReqCatch_Pre_Preempt_No,
0087   RtemsSignalReqCatch_Pre_Preempt_NA
0088 } RtemsSignalReqCatch_Pre_Preempt;
0089 
0090 typedef enum {
0091   RtemsSignalReqCatch_Pre_Timeslice_Yes,
0092   RtemsSignalReqCatch_Pre_Timeslice_No,
0093   RtemsSignalReqCatch_Pre_Timeslice_NA
0094 } RtemsSignalReqCatch_Pre_Timeslice;
0095 
0096 typedef enum {
0097   RtemsSignalReqCatch_Pre_ASR_Yes,
0098   RtemsSignalReqCatch_Pre_ASR_No,
0099   RtemsSignalReqCatch_Pre_ASR_NA
0100 } RtemsSignalReqCatch_Pre_ASR;
0101 
0102 typedef enum {
0103   RtemsSignalReqCatch_Pre_IntLvl_Zero,
0104   RtemsSignalReqCatch_Pre_IntLvl_Positive,
0105   RtemsSignalReqCatch_Pre_IntLvl_NA
0106 } RtemsSignalReqCatch_Pre_IntLvl;
0107 
0108 typedef enum {
0109   RtemsSignalReqCatch_Post_Status_Ok,
0110   RtemsSignalReqCatch_Post_Status_NotImplIntLvl,
0111   RtemsSignalReqCatch_Post_Status_NotImplIntLvlSMP,
0112   RtemsSignalReqCatch_Post_Status_NotImplNoPreempt,
0113   RtemsSignalReqCatch_Post_Status_NA
0114 } RtemsSignalReqCatch_Post_Status;
0115 
0116 typedef enum {
0117   RtemsSignalReqCatch_Post_ASRInfo_NopIntLvl,
0118   RtemsSignalReqCatch_Post_ASRInfo_NopIntLvlSMP,
0119   RtemsSignalReqCatch_Post_ASRInfo_NopNoPreempt,
0120   RtemsSignalReqCatch_Post_ASRInfo_New,
0121   RtemsSignalReqCatch_Post_ASRInfo_Inactive,
0122   RtemsSignalReqCatch_Post_ASRInfo_NA
0123 } RtemsSignalReqCatch_Post_ASRInfo;
0124 
0125 typedef struct {
0126   uint16_t Skip : 1;
0127   uint16_t Pre_Pending_NA : 1;
0128   uint16_t Pre_Handler_NA : 1;
0129   uint16_t Pre_Preempt_NA : 1;
0130   uint16_t Pre_Timeslice_NA : 1;
0131   uint16_t Pre_ASR_NA : 1;
0132   uint16_t Pre_IntLvl_NA : 1;
0133   uint16_t Post_Status : 3;
0134   uint16_t Post_ASRInfo : 3;
0135 } RtemsSignalReqCatch_Entry;
0136 
0137 /**
0138  * @brief Test context for spec:/rtems/signal/req/catch test case.
0139  */
0140 typedef struct {
0141   /**
0142    * @brief This member contains the object identifier of the runner task.
0143    */
0144   rtems_id runner_id;
0145 
0146   /**
0147    * @brief This member contains the object identifier of the worker task.
0148    */
0149   rtems_id worker_id;
0150 
0151   /**
0152    * @brief null If this member is non-zero, then rtems_signal_catch() is
0153    *   called with pending signals, otherwise it is called with no pending
0154    *   signals.
0155    */
0156   uint32_t pending_signals;
0157 
0158   /**
0159    * @brief This member provides a barrier to synchronize the runner and worker
0160    *   tasks.
0161    */
0162   SMP_barrier_Control barrier;
0163 
0164   /**
0165    * @brief This member is used for barrier operations done by the runner task.
0166    */
0167   SMP_barrier_State runner_barrier_state;
0168 
0169   /**
0170    * @brief When the default handler is called, this member is incremented.
0171    */
0172   uint32_t default_handler_calls;
0173 
0174   /**
0175    * @brief When the handler is called, this member is incremented.
0176    */
0177   uint32_t handler_calls;
0178 
0179   /**
0180    * @brief This member contains the mode observed in the last handler call.
0181    */
0182   rtems_mode handler_mode;
0183 
0184   /**
0185    * @brief This member specifies the normal task mode for the action.
0186    */
0187   rtems_mode normal_mode;
0188 
0189   /**
0190    * @brief This member specifies the handler for the action.
0191    */
0192   rtems_asr_entry handler;
0193 
0194   /**
0195    * @brief This member specifies the task mode for the action.
0196    */
0197   rtems_mode mode;
0198 
0199   /**
0200    * @brief This member contains the return status of the rtems_signal_catch()
0201    *   call of the action.
0202    */
0203   rtems_status_code catch_status;
0204 
0205   /**
0206    * @brief This member contains the return status of the rtems_signal_send()
0207    *   call of the action.
0208    */
0209   rtems_status_code send_status;
0210 
0211   struct {
0212     /**
0213      * @brief This member defines the pre-condition states for the next action.
0214      */
0215     size_t pcs[ 6 ];
0216 
0217     /**
0218      * @brief If this member is true, then the test action loop is executed.
0219      */
0220     bool in_action_loop;
0221 
0222     /**
0223      * @brief This member contains the next transition map index.
0224      */
0225     size_t index;
0226 
0227     /**
0228      * @brief This member contains the current transition map entry.
0229      */
0230     RtemsSignalReqCatch_Entry entry;
0231 
0232     /**
0233      * @brief If this member is true, then the current transition variant
0234      *   should be skipped.
0235      */
0236     bool skip;
0237   } Map;
0238 } RtemsSignalReqCatch_Context;
0239 
0240 static RtemsSignalReqCatch_Context
0241   RtemsSignalReqCatch_Instance;
0242 
0243 static const char * const RtemsSignalReqCatch_PreDesc_Pending[] = {
0244   "Yes",
0245   "No",
0246   "NA"
0247 };
0248 
0249 static const char * const RtemsSignalReqCatch_PreDesc_Handler[] = {
0250   "Invalid",
0251   "Valid",
0252   "NA"
0253 };
0254 
0255 static const char * const RtemsSignalReqCatch_PreDesc_Preempt[] = {
0256   "Yes",
0257   "No",
0258   "NA"
0259 };
0260 
0261 static const char * const RtemsSignalReqCatch_PreDesc_Timeslice[] = {
0262   "Yes",
0263   "No",
0264   "NA"
0265 };
0266 
0267 static const char * const RtemsSignalReqCatch_PreDesc_ASR[] = {
0268   "Yes",
0269   "No",
0270   "NA"
0271 };
0272 
0273 static const char * const RtemsSignalReqCatch_PreDesc_IntLvl[] = {
0274   "Zero",
0275   "Positive",
0276   "NA"
0277 };
0278 
0279 static const char * const * const RtemsSignalReqCatch_PreDesc[] = {
0280   RtemsSignalReqCatch_PreDesc_Pending,
0281   RtemsSignalReqCatch_PreDesc_Handler,
0282   RtemsSignalReqCatch_PreDesc_Preempt,
0283   RtemsSignalReqCatch_PreDesc_Timeslice,
0284   RtemsSignalReqCatch_PreDesc_ASR,
0285   RtemsSignalReqCatch_PreDesc_IntLvl,
0286   NULL
0287 };
0288 
0289 typedef RtemsSignalReqCatch_Context Context;
0290 
0291 static void DefaultHandler( rtems_signal_set signal_set )
0292 {
0293   Context *ctx;
0294 
0295   ctx = T_fixture_context();
0296   ++ctx->default_handler_calls;
0297 
0298   if ( ctx->pending_signals != 0 && ctx->default_handler_calls == 1 ) {
0299     T_eq_u32( signal_set, 0x600df00d );
0300   } else {
0301     T_eq_u32( signal_set, 0xdeadbeef );
0302   }
0303 }
0304 
0305 static void SignalHandler( rtems_signal_set signal_set )
0306 {
0307   Context          *ctx;
0308   rtems_status_code sc;
0309 
0310   ctx = T_fixture_context();
0311   ++ctx->handler_calls;
0312 
0313   sc = rtems_task_mode(
0314     RTEMS_DEFAULT_MODES,
0315     RTEMS_CURRENT_MODE,
0316     &ctx->handler_mode
0317   );
0318   T_rsc_success( sc );
0319 
0320   if ( ctx->pending_signals != 0 && ctx->handler_calls == 1 ) {
0321     T_eq_u32( signal_set, 0x600df00d );
0322   } else {
0323     T_eq_u32( signal_set, 0xdeadbeef );
0324   }
0325 }
0326 
0327 static void CheckNoASRChange( Context *ctx )
0328 {
0329   T_rsc_success( ctx->send_status );
0330   T_eq_u32( ctx->default_handler_calls, 1 + ctx->pending_signals );
0331   T_eq_u32( ctx->handler_calls, 0 );
0332   T_eq_u32( ctx->handler_mode, 0xffffffff );
0333 }
0334 
0335 static void CheckNewASRSettings( Context *ctx )
0336 {
0337   T_rsc_success( ctx->send_status );
0338   T_eq_u32( ctx->default_handler_calls, 0 );
0339   T_eq_u32( ctx->handler_calls, 1 + ctx->pending_signals );
0340   T_eq_u32( ctx->handler_mode, ctx->mode );
0341 }
0342 
0343 static void Worker( rtems_task_argument arg )
0344 {
0345   Context          *ctx;
0346   SMP_barrier_State barrier_state;
0347 
0348   ctx = (Context *) arg;
0349   _SMP_barrier_State_initialize( &barrier_state );
0350 
0351   while ( true ) {
0352     rtems_status_code sc;
0353 
0354     _SMP_barrier_Wait( &ctx->barrier, &barrier_state, 2 );
0355 
0356     sc = rtems_signal_send( ctx->runner_id, 0x600df00d );
0357     T_rsc_success( sc );
0358 
0359     _SMP_barrier_Wait( &ctx->barrier, &barrier_state, 2 );
0360   }
0361 }
0362 
0363 static void RtemsSignalReqCatch_Pre_Pending_Prepare(
0364   RtemsSignalReqCatch_Context    *ctx,
0365   RtemsSignalReqCatch_Pre_Pending state
0366 )
0367 {
0368   switch ( state ) {
0369     case RtemsSignalReqCatch_Pre_Pending_Yes: {
0370       /*
0371        * Where the system has more than one processor, while the calling task
0372        * has pending signals.
0373        *
0374        * Where the system has exactly one processor, while the calling task has
0375        * no pending signals.
0376        */
0377       if ( rtems_scheduler_get_processor_maximum() > 1 ) {
0378         ctx->pending_signals = 1;
0379       } else {
0380         ctx->pending_signals = 0;
0381       }
0382       break;
0383     }
0384 
0385     case RtemsSignalReqCatch_Pre_Pending_No: {
0386       /*
0387        * While the calling task has no pending signals.
0388        */
0389       ctx->pending_signals = 0;
0390       break;
0391     }
0392 
0393     case RtemsSignalReqCatch_Pre_Pending_NA:
0394       break;
0395   }
0396 }
0397 
0398 static void RtemsSignalReqCatch_Pre_Handler_Prepare(
0399   RtemsSignalReqCatch_Context    *ctx,
0400   RtemsSignalReqCatch_Pre_Handler state
0401 )
0402 {
0403   switch ( state ) {
0404     case RtemsSignalReqCatch_Pre_Handler_Invalid: {
0405       /*
0406        * While the ``asr_handler`` parameter is NULL.
0407        */
0408       ctx->handler = NULL;
0409       break;
0410     }
0411 
0412     case RtemsSignalReqCatch_Pre_Handler_Valid: {
0413       /*
0414        * While the ``asr_handler`` parameter is a valid ASR handler.
0415        */
0416       ctx->handler = SignalHandler;
0417       break;
0418     }
0419 
0420     case RtemsSignalReqCatch_Pre_Handler_NA:
0421       break;
0422   }
0423 }
0424 
0425 static void RtemsSignalReqCatch_Pre_Preempt_Prepare(
0426   RtemsSignalReqCatch_Context    *ctx,
0427   RtemsSignalReqCatch_Pre_Preempt state
0428 )
0429 {
0430   switch ( state ) {
0431     case RtemsSignalReqCatch_Pre_Preempt_Yes: {
0432       /*
0433        * While the ``mode_set`` parameter specifies that preemption is enabled.
0434        */
0435       if ( rtems_configuration_get_maximum_processors() == 1 ) {
0436         ctx->normal_mode |= RTEMS_NO_PREEMPT;
0437       }
0438       break;
0439     }
0440 
0441     case RtemsSignalReqCatch_Pre_Preempt_No: {
0442       /*
0443        * While the ``mode_set`` parameter specifies that preemption is
0444        * disabled.
0445        */
0446       ctx->mode |= RTEMS_NO_PREEMPT;
0447       break;
0448     }
0449 
0450     case RtemsSignalReqCatch_Pre_Preempt_NA:
0451       break;
0452   }
0453 }
0454 
0455 static void RtemsSignalReqCatch_Pre_Timeslice_Prepare(
0456   RtemsSignalReqCatch_Context      *ctx,
0457   RtemsSignalReqCatch_Pre_Timeslice state
0458 )
0459 {
0460   switch ( state ) {
0461     case RtemsSignalReqCatch_Pre_Timeslice_Yes: {
0462       /*
0463        * While the ``mode_set`` parameter specifies that timeslicing is
0464        * enabled.
0465        */
0466       ctx->mode |= RTEMS_TIMESLICE;
0467       break;
0468     }
0469 
0470     case RtemsSignalReqCatch_Pre_Timeslice_No: {
0471       /*
0472        * While the ``mode_set`` parameter specifies that timeslicing is
0473        * disabled.
0474        */
0475       ctx->normal_mode |= RTEMS_TIMESLICE;
0476       break;
0477     }
0478 
0479     case RtemsSignalReqCatch_Pre_Timeslice_NA:
0480       break;
0481   }
0482 }
0483 
0484 static void RtemsSignalReqCatch_Pre_ASR_Prepare(
0485   RtemsSignalReqCatch_Context *ctx,
0486   RtemsSignalReqCatch_Pre_ASR  state
0487 )
0488 {
0489   switch ( state ) {
0490     case RtemsSignalReqCatch_Pre_ASR_Yes: {
0491       /*
0492        * While the ``mode_set`` parameter specifies that ASR processing is
0493        * enabled.
0494        */
0495       /*
0496        * We cannot disable ASR processing at normal task level for this state.
0497        */
0498       break;
0499     }
0500 
0501     case RtemsSignalReqCatch_Pre_ASR_No: {
0502       /*
0503        * While the ``mode_set`` parameter specifies that ASR processing is
0504        * disabled.
0505        */
0506       ctx->mode |= RTEMS_NO_ASR;
0507       break;
0508     }
0509 
0510     case RtemsSignalReqCatch_Pre_ASR_NA:
0511       break;
0512   }
0513 }
0514 
0515 static void RtemsSignalReqCatch_Pre_IntLvl_Prepare(
0516   RtemsSignalReqCatch_Context   *ctx,
0517   RtemsSignalReqCatch_Pre_IntLvl state
0518 )
0519 {
0520   switch ( state ) {
0521     case RtemsSignalReqCatch_Pre_IntLvl_Zero: {
0522       /*
0523        * While the ``mode_set`` parameter specifies an interrupt level of zero.
0524        */
0525       #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE && !defined(RTEMS_SMP)
0526       ctx->normal_mode |= RTEMS_INTERRUPT_LEVEL( 1 );
0527       #endif
0528       break;
0529     }
0530 
0531     case RtemsSignalReqCatch_Pre_IntLvl_Positive: {
0532       /*
0533        * While the ``mode_set`` parameter specifies an interrupt level greater
0534        * than or equal to one and less than or equal to
0535        * CPU_MODES_INTERRUPT_MASK.
0536        */
0537       ctx->mode |= RTEMS_INTERRUPT_LEVEL( 1 );
0538       break;
0539     }
0540 
0541     case RtemsSignalReqCatch_Pre_IntLvl_NA:
0542       break;
0543   }
0544 }
0545 
0546 static void RtemsSignalReqCatch_Post_Status_Check(
0547   RtemsSignalReqCatch_Context    *ctx,
0548   RtemsSignalReqCatch_Post_Status state
0549 )
0550 {
0551   switch ( state ) {
0552     case RtemsSignalReqCatch_Post_Status_Ok: {
0553       /*
0554        * The return status of rtems_signal_catch() shall be RTEMS_SUCCESSFUL.
0555        */
0556       T_rsc_success( ctx->catch_status );
0557       break;
0558     }
0559 
0560     case RtemsSignalReqCatch_Post_Status_NotImplIntLvl: {
0561       /*
0562        * The return status of rtems_signal_catch() shall be
0563        * RTEMS_NOT_IMPLEMENTED.
0564        */
0565       T_rsc( ctx->catch_status, RTEMS_NOT_IMPLEMENTED );
0566       break;
0567     }
0568 
0569     case RtemsSignalReqCatch_Post_Status_NotImplIntLvlSMP: {
0570       /*
0571        * Where the system needs inter-processor interrupts, the return status
0572        * of rtems_signal_catch() shall be RTEMS_NOT_IMPLEMENTED.
0573        *
0574        * Where the system does not need inter-processor interrupts, the return
0575        * status of rtems_signal_catch() shall be RTEMS_SUCCESSFUL.
0576        */
0577       if ( rtems_configuration_get_maximum_processors() > 1 ) {
0578         T_rsc( ctx->catch_status, RTEMS_NOT_IMPLEMENTED );
0579       } else {
0580         T_rsc_success( ctx->catch_status );
0581       }
0582       break;
0583     }
0584 
0585     case RtemsSignalReqCatch_Post_Status_NotImplNoPreempt: {
0586       /*
0587        * Where the scheduler does not support the no-preempt mode, the return
0588        * status of rtems_signal_catch() shall be RTEMS_NOT_IMPLEMENTED.
0589        *
0590        * Where the scheduler does support the no-preempt mode, the return
0591        * status of rtems_signal_catch() shall be RTEMS_SUCCESSFUL.
0592        */
0593       if ( rtems_configuration_get_maximum_processors() > 1 ) {
0594         T_rsc( ctx->catch_status, RTEMS_NOT_IMPLEMENTED );
0595       } else {
0596         T_rsc_success( ctx->catch_status );
0597       }
0598       break;
0599     }
0600 
0601     case RtemsSignalReqCatch_Post_Status_NA:
0602       break;
0603   }
0604 }
0605 
0606 static void RtemsSignalReqCatch_Post_ASRInfo_Check(
0607   RtemsSignalReqCatch_Context     *ctx,
0608   RtemsSignalReqCatch_Post_ASRInfo state
0609 )
0610 {
0611   switch ( state ) {
0612     case RtemsSignalReqCatch_Post_ASRInfo_NopIntLvl: {
0613       /*
0614        * The ASR information of the caller of rtems_signal_catch() shall not be
0615        * changed by the rtems_signal_catch() call.
0616        */
0617       CheckNoASRChange( ctx );
0618       break;
0619     }
0620 
0621     case RtemsSignalReqCatch_Post_ASRInfo_NopIntLvlSMP: {
0622       /*
0623        * Where the system needs inter-processor interrupts, the ASR information
0624        * of the caller of rtems_signal_catch() shall not be changed by the
0625        * rtems_signal_catch() call.
0626        *
0627        * Where the system does not need inter-processor interrupts, the ASR
0628        * processing for the caller of rtems_signal_catch() shall be done using
0629        * the handler specified by ``asr_handler`` in the mode specified by
0630        * ``mode_set``.
0631        */
0632       if ( rtems_configuration_get_maximum_processors() > 1 ) {
0633         CheckNoASRChange( ctx );
0634       } else {
0635         CheckNewASRSettings( ctx );
0636       }
0637       break;
0638     }
0639 
0640     case RtemsSignalReqCatch_Post_ASRInfo_NopNoPreempt: {
0641       /*
0642        * Where the scheduler does not support the no-preempt mode, the ASR
0643        * information of the caller of rtems_signal_catch() shall not be changed
0644        * by the rtems_signal_catch() call.
0645        *
0646        * Where the scheduler does support the no-preempt mode, the ASR
0647        * processing for the caller of rtems_signal_catch() shall be done using
0648        * the handler specified by ``asr_handler`` in the mode specified by
0649        * ``mode_set``.
0650        */
0651       if ( rtems_configuration_get_maximum_processors() > 1 ) {
0652         CheckNoASRChange( ctx );
0653       } else {
0654         CheckNewASRSettings( ctx );
0655       }
0656       break;
0657     }
0658 
0659     case RtemsSignalReqCatch_Post_ASRInfo_New: {
0660       /*
0661        * The ASR processing for the caller of rtems_signal_catch() shall be
0662        * done using the handler specified by ``asr_handler`` in the mode
0663        * specified by ``mode_set``.
0664        */
0665       CheckNewASRSettings( ctx );
0666       break;
0667     }
0668 
0669     case RtemsSignalReqCatch_Post_ASRInfo_Inactive: {
0670       /*
0671        * The ASR processing for the caller of rtems_signal_catch() shall be
0672        * deactivated.
0673        *
0674        * The pending signals of the caller of rtems_signal_catch() shall be
0675        * cleared.
0676        */
0677       T_rsc( ctx->send_status, RTEMS_NOT_DEFINED );
0678       T_eq_u32( ctx->default_handler_calls, 0 );
0679       T_eq_u32( ctx->handler_calls, 0 );
0680       T_eq_u32( ctx->handler_mode, 0xffffffff );
0681       break;
0682     }
0683 
0684     case RtemsSignalReqCatch_Post_ASRInfo_NA:
0685       break;
0686   }
0687 }
0688 
0689 static void RtemsSignalReqCatch_Setup( RtemsSignalReqCatch_Context *ctx )
0690 {
0691   memset( ctx, 0, sizeof( *ctx ) );
0692   ctx->runner_id = rtems_task_self();
0693   _SMP_barrier_Control_initialize( &ctx->barrier );
0694   _SMP_barrier_State_initialize( &ctx->runner_barrier_state );
0695 
0696   if ( rtems_scheduler_get_processor_maximum() > 1 ) {
0697     rtems_status_code sc;
0698     rtems_id          scheduler_id;
0699 
0700     ctx->worker_id = CreateTask( "WORK", 1 );
0701 
0702     sc = rtems_scheduler_ident_by_processor( 1, &scheduler_id );
0703     T_assert_rsc_success( sc );
0704 
0705     sc = rtems_task_set_scheduler( ctx->worker_id, scheduler_id, 1 );
0706     T_assert_rsc_success( sc );
0707 
0708     StartTask( ctx->worker_id, Worker, ctx );
0709   }
0710 }
0711 
0712 static void RtemsSignalReqCatch_Setup_Wrap( void *arg )
0713 {
0714   RtemsSignalReqCatch_Context *ctx;
0715 
0716   ctx = arg;
0717   ctx->Map.in_action_loop = false;
0718   RtemsSignalReqCatch_Setup( ctx );
0719 }
0720 
0721 static void RtemsSignalReqCatch_Teardown( RtemsSignalReqCatch_Context *ctx )
0722 {
0723   DeleteTask( ctx->worker_id );
0724   RestoreRunnerASR();
0725 }
0726 
0727 static void RtemsSignalReqCatch_Teardown_Wrap( void *arg )
0728 {
0729   RtemsSignalReqCatch_Context *ctx;
0730 
0731   ctx = arg;
0732   ctx->Map.in_action_loop = false;
0733   RtemsSignalReqCatch_Teardown( ctx );
0734 }
0735 
0736 static void RtemsSignalReqCatch_Prepare( RtemsSignalReqCatch_Context *ctx )
0737 {
0738   rtems_status_code sc;
0739 
0740   ctx->default_handler_calls = 0;
0741   ctx->handler_calls = 0;
0742   ctx->handler_mode = 0xffffffff;
0743   ctx->normal_mode = RTEMS_DEFAULT_MODES;
0744   ctx->handler = NULL;
0745   ctx->mode = RTEMS_DEFAULT_MODES;
0746 
0747   sc = rtems_signal_catch( DefaultHandler, RTEMS_NO_ASR );
0748   T_rsc_success( sc );
0749 }
0750 
0751 static void RtemsSignalReqCatch_Action( RtemsSignalReqCatch_Context *ctx )
0752 {
0753   rtems_status_code sc;
0754   rtems_mode        mode;
0755 
0756   if ( ctx->pending_signals != 0 ) {
0757     rtems_interrupt_level level;
0758 
0759     rtems_interrupt_local_disable(level);
0760     _SMP_barrier_Wait( &ctx->barrier, &ctx->runner_barrier_state, 2 );
0761     _SMP_barrier_Wait( &ctx->barrier, &ctx->runner_barrier_state, 2 );
0762     ctx->catch_status = rtems_signal_catch( ctx->handler, ctx->mode );
0763     rtems_interrupt_local_enable(level);
0764   } else {
0765     ctx->catch_status = rtems_signal_catch( ctx->handler, ctx->mode );
0766   }
0767 
0768   sc = rtems_task_mode( ctx->normal_mode, RTEMS_ALL_MODE_MASKS, &mode );
0769   T_rsc_success( sc );
0770 
0771   ctx->send_status = rtems_signal_send( RTEMS_SELF, 0xdeadbeef );
0772 
0773   sc = rtems_task_mode( mode, RTEMS_ALL_MODE_MASKS, &mode );
0774   T_rsc_success( sc );
0775 }
0776 
0777 static const RtemsSignalReqCatch_Entry
0778 RtemsSignalReqCatch_Entries[] = {
0779   { 0, 0, 0, 0, 0, 0, 0, RtemsSignalReqCatch_Post_Status_Ok,
0780     RtemsSignalReqCatch_Post_ASRInfo_Inactive },
0781 #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
0782   { 0, 0, 0, 0, 0, 0, 0, RtemsSignalReqCatch_Post_Status_NotImplIntLvl,
0783     RtemsSignalReqCatch_Post_ASRInfo_NopIntLvl },
0784 #elif defined(RTEMS_SMP)
0785   { 0, 0, 0, 0, 0, 0, 0, RtemsSignalReqCatch_Post_Status_NotImplIntLvlSMP,
0786     RtemsSignalReqCatch_Post_ASRInfo_NopIntLvlSMP },
0787 #else
0788   { 0, 0, 0, 0, 0, 0, 0, RtemsSignalReqCatch_Post_Status_Ok,
0789     RtemsSignalReqCatch_Post_ASRInfo_New },
0790 #endif
0791   { 0, 0, 0, 0, 0, 0, 0, RtemsSignalReqCatch_Post_Status_Ok,
0792     RtemsSignalReqCatch_Post_ASRInfo_New },
0793 #if defined(RTEMS_SMP)
0794   { 0, 0, 0, 0, 0, 0, 0, RtemsSignalReqCatch_Post_Status_NotImplNoPreempt,
0795     RtemsSignalReqCatch_Post_ASRInfo_NopNoPreempt }
0796 #else
0797   { 0, 0, 0, 0, 0, 0, 0, RtemsSignalReqCatch_Post_Status_Ok,
0798     RtemsSignalReqCatch_Post_ASRInfo_New }
0799 #endif
0800 };
0801 
0802 static const uint8_t
0803 RtemsSignalReqCatch_Map[] = {
0804   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1,
0805   3, 1, 3, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1,
0806   2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1
0807 };
0808 
0809 static size_t RtemsSignalReqCatch_Scope( void *arg, char *buf, size_t n )
0810 {
0811   RtemsSignalReqCatch_Context *ctx;
0812 
0813   ctx = arg;
0814 
0815   if ( ctx->Map.in_action_loop ) {
0816     return T_get_scope( RtemsSignalReqCatch_PreDesc, buf, n, ctx->Map.pcs );
0817   }
0818 
0819   return 0;
0820 }
0821 
0822 static T_fixture RtemsSignalReqCatch_Fixture = {
0823   .setup = RtemsSignalReqCatch_Setup_Wrap,
0824   .stop = NULL,
0825   .teardown = RtemsSignalReqCatch_Teardown_Wrap,
0826   .scope = RtemsSignalReqCatch_Scope,
0827   .initial_context = &RtemsSignalReqCatch_Instance
0828 };
0829 
0830 static inline RtemsSignalReqCatch_Entry RtemsSignalReqCatch_PopEntry(
0831   RtemsSignalReqCatch_Context *ctx
0832 )
0833 {
0834   size_t index;
0835 
0836   index = ctx->Map.index;
0837   ctx->Map.index = index + 1;
0838   return RtemsSignalReqCatch_Entries[
0839     RtemsSignalReqCatch_Map[ index ]
0840   ];
0841 }
0842 
0843 static void RtemsSignalReqCatch_TestVariant( RtemsSignalReqCatch_Context *ctx )
0844 {
0845   RtemsSignalReqCatch_Pre_Pending_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0846   RtemsSignalReqCatch_Pre_Handler_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0847   RtemsSignalReqCatch_Pre_Preempt_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0848   RtemsSignalReqCatch_Pre_Timeslice_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0849   RtemsSignalReqCatch_Pre_ASR_Prepare( ctx, ctx->Map.pcs[ 4 ] );
0850   RtemsSignalReqCatch_Pre_IntLvl_Prepare( ctx, ctx->Map.pcs[ 5 ] );
0851   RtemsSignalReqCatch_Action( ctx );
0852   RtemsSignalReqCatch_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0853   RtemsSignalReqCatch_Post_ASRInfo_Check( ctx, ctx->Map.entry.Post_ASRInfo );
0854 }
0855 
0856 /**
0857  * @fn void T_case_body_RtemsSignalReqCatch( void )
0858  */
0859 T_TEST_CASE_FIXTURE( RtemsSignalReqCatch, &RtemsSignalReqCatch_Fixture )
0860 {
0861   RtemsSignalReqCatch_Context *ctx;
0862 
0863   ctx = T_fixture_context();
0864   ctx->Map.in_action_loop = true;
0865   ctx->Map.index = 0;
0866 
0867   for (
0868     ctx->Map.pcs[ 0 ] = RtemsSignalReqCatch_Pre_Pending_Yes;
0869     ctx->Map.pcs[ 0 ] < RtemsSignalReqCatch_Pre_Pending_NA;
0870     ++ctx->Map.pcs[ 0 ]
0871   ) {
0872     for (
0873       ctx->Map.pcs[ 1 ] = RtemsSignalReqCatch_Pre_Handler_Invalid;
0874       ctx->Map.pcs[ 1 ] < RtemsSignalReqCatch_Pre_Handler_NA;
0875       ++ctx->Map.pcs[ 1 ]
0876     ) {
0877       for (
0878         ctx->Map.pcs[ 2 ] = RtemsSignalReqCatch_Pre_Preempt_Yes;
0879         ctx->Map.pcs[ 2 ] < RtemsSignalReqCatch_Pre_Preempt_NA;
0880         ++ctx->Map.pcs[ 2 ]
0881       ) {
0882         for (
0883           ctx->Map.pcs[ 3 ] = RtemsSignalReqCatch_Pre_Timeslice_Yes;
0884           ctx->Map.pcs[ 3 ] < RtemsSignalReqCatch_Pre_Timeslice_NA;
0885           ++ctx->Map.pcs[ 3 ]
0886         ) {
0887           for (
0888             ctx->Map.pcs[ 4 ] = RtemsSignalReqCatch_Pre_ASR_Yes;
0889             ctx->Map.pcs[ 4 ] < RtemsSignalReqCatch_Pre_ASR_NA;
0890             ++ctx->Map.pcs[ 4 ]
0891           ) {
0892             for (
0893               ctx->Map.pcs[ 5 ] = RtemsSignalReqCatch_Pre_IntLvl_Zero;
0894               ctx->Map.pcs[ 5 ] < RtemsSignalReqCatch_Pre_IntLvl_NA;
0895               ++ctx->Map.pcs[ 5 ]
0896             ) {
0897               ctx->Map.entry = RtemsSignalReqCatch_PopEntry( ctx );
0898               RtemsSignalReqCatch_Prepare( ctx );
0899               RtemsSignalReqCatch_TestVariant( ctx );
0900             }
0901           }
0902         }
0903       }
0904     }
0905   }
0906 }
0907 
0908 /** @} */