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 RtemsRatemonReqCancel
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 RtemsRatemonReqCancel spec:/rtems/ratemon/req/cancel
0063  *
0064  * @ingroup TestsuitesValidationNoClock0
0065  * @ingroup TestsuitesValidationOneCpu0
0066  *
0067  * @{
0068  */
0069 
0070 typedef enum {
0071   RtemsRatemonReqCancel_Pre_Id_Valid,
0072   RtemsRatemonReqCancel_Pre_Id_Invalid,
0073   RtemsRatemonReqCancel_Pre_Id_NA
0074 } RtemsRatemonReqCancel_Pre_Id;
0075 
0076 typedef enum {
0077   RtemsRatemonReqCancel_Pre_Caller_OwnerTask,
0078   RtemsRatemonReqCancel_Pre_Caller_OtherTask,
0079   RtemsRatemonReqCancel_Pre_Caller_NA
0080 } RtemsRatemonReqCancel_Pre_Caller;
0081 
0082 typedef enum {
0083   RtemsRatemonReqCancel_Pre_State_Inactive,
0084   RtemsRatemonReqCancel_Pre_State_Active,
0085   RtemsRatemonReqCancel_Pre_State_Expired,
0086   RtemsRatemonReqCancel_Pre_State_NA
0087 } RtemsRatemonReqCancel_Pre_State;
0088 
0089 typedef enum {
0090   RtemsRatemonReqCancel_Pre_Postponed_Zero,
0091   RtemsRatemonReqCancel_Pre_Postponed_One,
0092   RtemsRatemonReqCancel_Pre_Postponed_Several,
0093   RtemsRatemonReqCancel_Pre_Postponed_NA
0094 } RtemsRatemonReqCancel_Pre_Postponed;
0095 
0096 typedef enum {
0097   RtemsRatemonReqCancel_Post_Status_Ok,
0098   RtemsRatemonReqCancel_Post_Status_InvId,
0099   RtemsRatemonReqCancel_Post_Status_NotOwn,
0100   RtemsRatemonReqCancel_Post_Status_NA
0101 } RtemsRatemonReqCancel_Post_Status;
0102 
0103 typedef enum {
0104   RtemsRatemonReqCancel_Post_State_Inactive,
0105   RtemsRatemonReqCancel_Post_State_Nop,
0106   RtemsRatemonReqCancel_Post_State_NA
0107 } RtemsRatemonReqCancel_Post_State;
0108 
0109 typedef enum {
0110   RtemsRatemonReqCancel_Post_Postponed_Zero,
0111   RtemsRatemonReqCancel_Post_Postponed_Nop,
0112   RtemsRatemonReqCancel_Post_Postponed_NA
0113 } RtemsRatemonReqCancel_Post_Postponed;
0114 
0115 typedef enum {
0116   RtemsRatemonReqCancel_Post_Scheduler_Called,
0117   RtemsRatemonReqCancel_Post_Scheduler_Nop,
0118   RtemsRatemonReqCancel_Post_Scheduler_NA
0119 } RtemsRatemonReqCancel_Post_Scheduler;
0120 
0121 typedef struct {
0122   uint16_t Skip : 1;
0123   uint16_t Pre_Id_NA : 1;
0124   uint16_t Pre_Caller_NA : 1;
0125   uint16_t Pre_State_NA : 1;
0126   uint16_t Pre_Postponed_NA : 1;
0127   uint16_t Post_Status : 2;
0128   uint16_t Post_State : 2;
0129   uint16_t Post_Postponed : 2;
0130   uint16_t Post_Scheduler : 2;
0131 } RtemsRatemonReqCancel_Entry;
0132 
0133 /**
0134  * @brief Test context for spec:/rtems/ratemon/req/cancel test case.
0135  */
0136 typedef struct {
0137   /**
0138    * @brief This member contains a valid identifier of a period.
0139    */
0140   rtems_id period_id;
0141 
0142   /**
0143    * @brief This member is used to receive the
0144    *   rtems_rate_monotonic_period_status after the action.
0145    */
0146   rtems_rate_monotonic_period_status period_status;
0147 
0148   /**
0149    * @brief This member specifies the ``id`` parameter for the action.
0150    */
0151   rtems_id id_param;
0152 
0153   /**
0154    * @brief This member contains the returned status code of the action.
0155    */
0156   rtems_status_code status;
0157 
0158   /**
0159    * @brief This member contains the pointer to the function which executes the
0160    *   action.
0161    *
0162    * The action is either executed by the owner task or by the worker task
0163    * depending on the function pointer used here.  ``argument`` is a pointer to
0164    * this context structure.
0165    */
0166   void ( *do_action )( void *ctx );
0167 
0168   /**
0169    * @brief This member contains the task identifier of the owner task.
0170    */
0171   rtems_id task_id;
0172 
0173   /**
0174    * @brief This member contains the task identifier of the worker task (which
0175    *   is not the owner task).
0176    */
0177   rtems_id worker_id;
0178 
0179   /**
0180    * @brief This member contains a backup of the task priority before the
0181    *   execution of this test.
0182    */
0183   rtems_id original_priority;
0184 
0185   /**
0186    * @brief This member contains the number of postponed jobs before the
0187    *   action.
0188    */
0189   uint32_t postponed_jobs_count;
0190 
0191   /**
0192    * @brief This member contains the state before the action.
0193    */
0194   rtems_rate_monotonic_period_states previous_state;
0195 
0196   struct {
0197     /**
0198      * @brief This member defines the pre-condition indices for the next
0199      *   action.
0200      */
0201     size_t pci[ 4 ];
0202 
0203     /**
0204      * @brief This member defines the pre-condition states for the next action.
0205      */
0206     size_t pcs[ 4 ];
0207 
0208     /**
0209      * @brief If this member is true, then the test action loop is executed.
0210      */
0211     bool in_action_loop;
0212 
0213     /**
0214      * @brief This member contains the next transition map index.
0215      */
0216     size_t index;
0217 
0218     /**
0219      * @brief This member contains the current transition map entry.
0220      */
0221     RtemsRatemonReqCancel_Entry entry;
0222 
0223     /**
0224      * @brief If this member is true, then the current transition variant
0225      *   should be skipped.
0226      */
0227     bool skip;
0228   } Map;
0229 } RtemsRatemonReqCancel_Context;
0230 
0231 static RtemsRatemonReqCancel_Context
0232   RtemsRatemonReqCancel_Instance;
0233 
0234 static const char * const RtemsRatemonReqCancel_PreDesc_Id[] = {
0235   "Valid",
0236   "Invalid",
0237   "NA"
0238 };
0239 
0240 static const char * const RtemsRatemonReqCancel_PreDesc_Caller[] = {
0241   "OwnerTask",
0242   "OtherTask",
0243   "NA"
0244 };
0245 
0246 static const char * const RtemsRatemonReqCancel_PreDesc_State[] = {
0247   "Inactive",
0248   "Active",
0249   "Expired",
0250   "NA"
0251 };
0252 
0253 static const char * const RtemsRatemonReqCancel_PreDesc_Postponed[] = {
0254   "Zero",
0255   "One",
0256   "Several",
0257   "NA"
0258 };
0259 
0260 static const char * const * const RtemsRatemonReqCancel_PreDesc[] = {
0261   RtemsRatemonReqCancel_PreDesc_Id,
0262   RtemsRatemonReqCancel_PreDesc_Caller,
0263   RtemsRatemonReqCancel_PreDesc_State,
0264   RtemsRatemonReqCancel_PreDesc_Postponed,
0265   NULL
0266 };
0267 
0268 static const rtems_interval period_length = 5;
0269 static const rtems_task_priority background_task_priority = 100;
0270 static const rtems_task_priority foreground_task_priority = 10;
0271 static const rtems_event_set wake_main_task_event = RTEMS_EVENT_17;
0272 
0273 static void TickTheClock(
0274   RtemsRatemonReqCancel_Context *ctx,
0275   uint32_t ticks
0276 )
0277 {
0278   uint32_t i;
0279   for ( i = 0; i < ticks; ++i ) {
0280     TimecounterTick();
0281   }
0282 }
0283 
0284 static void Action( void *ctx_in )
0285 {
0286   RtemsRatemonReqCancel_Context *ctx = ctx_in;
0287   ctx->status = rtems_rate_monotonic_cancel( ctx->id_param );
0288 }
0289 
0290 static void WorkerTask( rtems_task_argument argument )
0291 {
0292   RtemsRatemonReqCancel_Context *ctx =
0293     (RtemsRatemonReqCancel_Context *) argument;
0294 
0295   if ( ctx != NULL ) {
0296     Action( ctx );
0297     T_rsc_success( rtems_event_send( ctx->task_id, wake_main_task_event ) );
0298   }
0299 
0300   T_rsc_success( rtems_task_suspend( RTEMS_SELF ) );
0301 }
0302 
0303 static void WorkerTaskAction( void *ctx_in )
0304 {
0305   rtems_status_code status;
0306   rtems_event_set event_set;
0307   RtemsRatemonReqCancel_Context *ctx = ctx_in;
0308 
0309   status = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
0310   T_rsc_success( status );
0311 
0312   /* Wait till the worker task finishes */
0313   status = rtems_event_receive(
0314     wake_main_task_event,
0315     RTEMS_DEFAULT_OPTIONS,
0316     RTEMS_NO_TIMEOUT,
0317     &event_set
0318   );
0319   T_rsc_success( status );
0320 }
0321 
0322 static void CreatePostponedJobs(
0323   RtemsRatemonReqCancel_Context *ctx,
0324   uint32_t jobs_count
0325 )
0326 {
0327   rtems_status_code status;
0328   ctx->postponed_jobs_count = jobs_count;
0329   if ( ctx->previous_state == RATE_MONOTONIC_ACTIVE ) {
0330     TickTheClock( ctx, ( jobs_count + 1 ) * period_length );
0331     status = rtems_rate_monotonic_period( ctx->period_id, period_length );
0332     T_rsc( status, RTEMS_TIMEOUT );
0333   } else {
0334     /* ctx->previous_state == RATE_MONOTONIC_INACTIVE || _EXPIRED */
0335     TickTheClock( ctx, jobs_count * period_length );
0336   }
0337 }
0338 
0339 static void RtemsRatemonReqCancel_Pre_Id_Prepare(
0340   RtemsRatemonReqCancel_Context *ctx,
0341   RtemsRatemonReqCancel_Pre_Id   state
0342 )
0343 {
0344   switch ( state ) {
0345     case RtemsRatemonReqCancel_Pre_Id_Valid: {
0346       /*
0347        * While the ``id`` parameter is valid.
0348        */
0349       ctx->id_param = ctx->period_id;
0350       break;
0351     }
0352 
0353     case RtemsRatemonReqCancel_Pre_Id_Invalid: {
0354       /*
0355        * While the ``id`` parameter is invalid.
0356        */
0357       ctx->id_param = RTEMS_ID_NONE;
0358       break;
0359     }
0360 
0361     case RtemsRatemonReqCancel_Pre_Id_NA:
0362       break;
0363   }
0364 }
0365 
0366 static void RtemsRatemonReqCancel_Pre_Caller_Prepare(
0367   RtemsRatemonReqCancel_Context   *ctx,
0368   RtemsRatemonReqCancel_Pre_Caller state
0369 )
0370 {
0371   switch ( state ) {
0372     case RtemsRatemonReqCancel_Pre_Caller_OwnerTask: {
0373       /*
0374        * While the task invoking rtems_rate_monotonic_cancel() is the task
0375        * which created the period - the owner task.
0376        */
0377       ctx->do_action = Action;
0378       break;
0379     }
0380 
0381     case RtemsRatemonReqCancel_Pre_Caller_OtherTask: {
0382       /*
0383        * While the task invoking rtems_rate_monotonic_cancel() is not the owner
0384        * task.
0385        */
0386       ctx->do_action = WorkerTaskAction;
0387       break;
0388     }
0389 
0390     case RtemsRatemonReqCancel_Pre_Caller_NA:
0391       break;
0392   }
0393 }
0394 
0395 static void RtemsRatemonReqCancel_Pre_State_Prepare(
0396   RtemsRatemonReqCancel_Context  *ctx,
0397   RtemsRatemonReqCancel_Pre_State state
0398 )
0399 {
0400   switch ( state ) {
0401     case RtemsRatemonReqCancel_Pre_State_Inactive: {
0402       /*
0403        * While the ``id`` parameter references an period object in inactive
0404        * state.
0405        */
0406       /* Nothing to do here as the period is newly created. */
0407       ctx->previous_state = RATE_MONOTONIC_INACTIVE;
0408       break;
0409     }
0410 
0411     case RtemsRatemonReqCancel_Pre_State_Active: {
0412       /*
0413        * While the ``id`` parameter references an period object in active
0414        * state.
0415        */
0416       rtems_status_code status;
0417       status = rtems_rate_monotonic_period( ctx->period_id, period_length );
0418       T_rsc_success( status );
0419       ctx->previous_state = RATE_MONOTONIC_ACTIVE;
0420       break;
0421     }
0422 
0423     case RtemsRatemonReqCancel_Pre_State_Expired: {
0424       /*
0425        * While the ``id`` parameter references an period object in expired
0426        * state.
0427        */
0428       rtems_status_code status;
0429       status = rtems_rate_monotonic_period( ctx->period_id, period_length );
0430       T_rsc_success( status );
0431       ctx->previous_state = RATE_MONOTONIC_EXPIRED;
0432       break;
0433     }
0434 
0435     case RtemsRatemonReqCancel_Pre_State_NA:
0436       break;
0437   }
0438 }
0439 
0440 static void RtemsRatemonReqCancel_Pre_Postponed_Prepare(
0441   RtemsRatemonReqCancel_Context      *ctx,
0442   RtemsRatemonReqCancel_Pre_Postponed state
0443 )
0444 {
0445   switch ( state ) {
0446     case RtemsRatemonReqCancel_Pre_Postponed_Zero: {
0447       /*
0448        * While the period is not in expired state.
0449        */
0450       ctx->postponed_jobs_count = 0;
0451       break;
0452     }
0453 
0454     case RtemsRatemonReqCancel_Pre_Postponed_One: {
0455       /*
0456        * While there is one postponed job.
0457        */
0458       CreatePostponedJobs( ctx, 1 );
0459       break;
0460     }
0461 
0462     case RtemsRatemonReqCancel_Pre_Postponed_Several: {
0463       /*
0464        * While there are two or more postponed jobs.
0465        */
0466       CreatePostponedJobs( ctx, 5 );
0467       break;
0468     }
0469 
0470     case RtemsRatemonReqCancel_Pre_Postponed_NA:
0471       break;
0472   }
0473 }
0474 
0475 static void RtemsRatemonReqCancel_Post_Status_Check(
0476   RtemsRatemonReqCancel_Context    *ctx,
0477   RtemsRatemonReqCancel_Post_Status state
0478 )
0479 {
0480   switch ( state ) {
0481     case RtemsRatemonReqCancel_Post_Status_Ok: {
0482       /*
0483        * The return status of rtems_rate_monotonic_cancel() shall be
0484        * RTEMS_SUCCESSFUL
0485        */
0486       T_rsc_success( ctx->status );
0487       break;
0488     }
0489 
0490     case RtemsRatemonReqCancel_Post_Status_InvId: {
0491       /*
0492        * The return status of rtems_rate_monotonic_cancel() shall be
0493        * RTEMS_INVALID_ID.
0494        */
0495       T_rsc( ctx->status, RTEMS_INVALID_ID );
0496       break;
0497     }
0498 
0499     case RtemsRatemonReqCancel_Post_Status_NotOwn: {
0500       /*
0501        * The return status of rtems_rate_monotonic_cancel() shall be
0502        * RTEMS_NOT_OWNER_OF_RESOURCE.
0503        */
0504       T_rsc( ctx->status, RTEMS_NOT_OWNER_OF_RESOURCE );
0505       break;
0506     }
0507 
0508     case RtemsRatemonReqCancel_Post_Status_NA:
0509       break;
0510   }
0511 }
0512 
0513 static void RtemsRatemonReqCancel_Post_State_Check(
0514   RtemsRatemonReqCancel_Context   *ctx,
0515   RtemsRatemonReqCancel_Post_State state
0516 )
0517 {
0518   switch ( state ) {
0519     case RtemsRatemonReqCancel_Post_State_Inactive: {
0520       /*
0521        * The state of the period shall be inactive after the return of the
0522        * rtems_rate_monotonic_cancel() call.
0523        */
0524       T_eq_int( ctx->period_status.state, RATE_MONOTONIC_INACTIVE );
0525       break;
0526     }
0527 
0528     case RtemsRatemonReqCancel_Post_State_Nop: {
0529       /*
0530        * Objects referenced by the ``id`` parameter in past calls to
0531        * rtems_rate_monotonic_cancel() shall not be accessed by the
0532        * rtems_rate_monotonic_cancel() call (see also Nop).
0533        */
0534       T_eq_u32( ctx->period_status.state, ctx->previous_state );
0535       break;
0536     }
0537 
0538     case RtemsRatemonReqCancel_Post_State_NA:
0539       break;
0540   }
0541 }
0542 
0543 static void RtemsRatemonReqCancel_Post_Postponed_Check(
0544   RtemsRatemonReqCancel_Context       *ctx,
0545   RtemsRatemonReqCancel_Post_Postponed state
0546 )
0547 {
0548   switch ( state ) {
0549     case RtemsRatemonReqCancel_Post_Postponed_Zero: {
0550       /*
0551        * There shall be no postponed jobs after the return of the
0552        * rtems_rate_monotonic_cancel() call.
0553        */
0554       T_eq_u32( ctx->period_status.postponed_jobs_count, 0 );
0555       break;
0556     }
0557 
0558     case RtemsRatemonReqCancel_Post_Postponed_Nop: {
0559       /*
0560        * Objects referenced by the ``id`` parameter in past calls to
0561        * rtems_rate_monotonic_cancel() shall not be accessed by the
0562        * rtems_rate_monotonic_cancel() call (see also Nop).
0563        */
0564       T_eq_u32( ctx->period_status.postponed_jobs_count,
0565         ctx->postponed_jobs_count );
0566       break;
0567     }
0568 
0569     case RtemsRatemonReqCancel_Post_Postponed_NA:
0570       break;
0571   }
0572 }
0573 
0574 static void RtemsRatemonReqCancel_Post_Scheduler_Check(
0575   RtemsRatemonReqCancel_Context       *ctx,
0576   RtemsRatemonReqCancel_Post_Scheduler state
0577 )
0578 {
0579   switch ( state ) {
0580     case RtemsRatemonReqCancel_Post_Scheduler_Called: {
0581       /*
0582        * The last call of the rtems_rate_monotonic_cancel() function shall
0583        * execute the ``cancel_job`` scheduler operation of the home scheduler.
0584        */
0585       /* Cannot be tested as the effect is unknown. */
0586       break;
0587     }
0588 
0589     case RtemsRatemonReqCancel_Post_Scheduler_Nop: {
0590       /*
0591        * The last call of the rtems_rate_monotonic_cancel() function shall not
0592        * execute any scheduler operation.
0593        */
0594       /* Cannot be tested as the effect is unknown. */
0595       break;
0596     }
0597 
0598     case RtemsRatemonReqCancel_Post_Scheduler_NA:
0599       break;
0600   }
0601 }
0602 
0603 static void RtemsRatemonReqCancel_Setup( RtemsRatemonReqCancel_Context *ctx )
0604 {
0605   rtems_status_code status;
0606   rtems_task_priority priority;
0607   rtems_event_set event_set;
0608   ctx->worker_id = RTEMS_INVALID_ID;
0609 
0610   status = rtems_task_ident(
0611     RTEMS_SELF,
0612     RTEMS_SEARCH_ALL_NODES,
0613     &ctx->task_id
0614   );
0615   T_rsc_success( status );
0616 
0617   status = rtems_task_set_priority(
0618     RTEMS_SELF,
0619     RTEMS_CURRENT_PRIORITY,
0620     &ctx->original_priority
0621   );
0622   T_rsc_success( status );
0623 
0624   status = rtems_task_set_priority(
0625     RTEMS_SELF,
0626     background_task_priority,
0627     &priority
0628   );
0629   T_rsc_success( status );
0630 
0631   status = rtems_task_create(
0632     rtems_build_name( 'W', 'O', 'R', 'K' ),
0633     foreground_task_priority,
0634     RTEMS_MINIMUM_STACK_SIZE,
0635     RTEMS_DEFAULT_MODES,
0636     RTEMS_DEFAULT_ATTRIBUTES,
0637     &ctx->worker_id
0638   );
0639   T_rsc_success( status );
0640 
0641   /* Defensive programming: clean away any pending events */
0642   status = rtems_event_receive(
0643     RTEMS_ALL_EVENTS,
0644     RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
0645     RTEMS_NO_TIMEOUT,
0646     &event_set
0647   );
0648   T_true( status == RTEMS_SUCCESSFUL || status == RTEMS_UNSATISFIED );
0649 
0650   status = rtems_task_start(
0651     ctx->worker_id,
0652     WorkerTask,
0653     (rtems_task_argument) NULL
0654   );
0655   T_rsc_success( status );
0656 }
0657 
0658 static void RtemsRatemonReqCancel_Setup_Wrap( void *arg )
0659 {
0660   RtemsRatemonReqCancel_Context *ctx;
0661 
0662   ctx = arg;
0663   ctx->Map.in_action_loop = false;
0664   RtemsRatemonReqCancel_Setup( ctx );
0665 }
0666 
0667 static void RtemsRatemonReqCancel_Teardown(
0668   RtemsRatemonReqCancel_Context *ctx
0669 )
0670 {
0671   rtems_status_code status;
0672   rtems_task_priority priority;
0673 
0674   T_rsc_success( rtems_task_delete( ctx->worker_id ) );
0675 
0676   status = rtems_task_set_priority(
0677     RTEMS_SELF,
0678     ctx->original_priority,
0679     &priority
0680   );
0681   T_rsc_success( status );
0682 }
0683 
0684 static void RtemsRatemonReqCancel_Teardown_Wrap( void *arg )
0685 {
0686   RtemsRatemonReqCancel_Context *ctx;
0687 
0688   ctx = arg;
0689   ctx->Map.in_action_loop = false;
0690   RtemsRatemonReqCancel_Teardown( ctx );
0691 }
0692 
0693 static void RtemsRatemonReqCancel_Prepare( RtemsRatemonReqCancel_Context *ctx )
0694 {
0695   rtems_status_code status;
0696   status =  rtems_rate_monotonic_create(
0697     rtems_build_name( 'R', 'M', 'O', 'N' ),
0698     &ctx->period_id
0699   );
0700   T_rsc_success( status );
0701 
0702   ctx->postponed_jobs_count = 0;
0703 }
0704 
0705 static void RtemsRatemonReqCancel_Action( RtemsRatemonReqCancel_Context *ctx )
0706 {
0707   rtems_status_code status;
0708 
0709   ctx->do_action( ctx );
0710 
0711   status = rtems_rate_monotonic_get_status(
0712     ctx->period_id,
0713     &ctx->period_status
0714   );
0715   T_rsc_success( status );
0716 }
0717 
0718 static void RtemsRatemonReqCancel_Cleanup( RtemsRatemonReqCancel_Context *ctx )
0719 {
0720   T_rsc_success( rtems_rate_monotonic_delete( ctx->period_id ) );
0721 }
0722 
0723 static const RtemsRatemonReqCancel_Entry
0724 RtemsRatemonReqCancel_Entries[] = {
0725   { 0, 0, 0, 0, 0, RtemsRatemonReqCancel_Post_Status_InvId,
0726     RtemsRatemonReqCancel_Post_State_Nop,
0727     RtemsRatemonReqCancel_Post_Postponed_Nop,
0728     RtemsRatemonReqCancel_Post_Scheduler_Nop },
0729   { 1, 0, 0, 0, 0, RtemsRatemonReqCancel_Post_Status_NA,
0730     RtemsRatemonReqCancel_Post_State_NA,
0731     RtemsRatemonReqCancel_Post_Postponed_NA,
0732     RtemsRatemonReqCancel_Post_Scheduler_NA },
0733   { 0, 0, 0, 0, 0, RtemsRatemonReqCancel_Post_Status_Ok,
0734     RtemsRatemonReqCancel_Post_State_Inactive,
0735     RtemsRatemonReqCancel_Post_Postponed_Zero,
0736     RtemsRatemonReqCancel_Post_Scheduler_Called },
0737   { 0, 0, 0, 0, 0, RtemsRatemonReqCancel_Post_Status_NotOwn,
0738     RtemsRatemonReqCancel_Post_State_Nop,
0739     RtemsRatemonReqCancel_Post_Postponed_Nop,
0740     RtemsRatemonReqCancel_Post_Scheduler_Nop },
0741   { 1, 0, 0, 0, 0, RtemsRatemonReqCancel_Post_Status_NA,
0742     RtemsRatemonReqCancel_Post_State_NA,
0743     RtemsRatemonReqCancel_Post_Postponed_NA,
0744     RtemsRatemonReqCancel_Post_Scheduler_NA },
0745   { 0, 0, 0, 0, 1, RtemsRatemonReqCancel_Post_Status_InvId,
0746     RtemsRatemonReqCancel_Post_State_Nop,
0747     RtemsRatemonReqCancel_Post_Postponed_Nop,
0748     RtemsRatemonReqCancel_Post_Scheduler_Nop },
0749   { 0, 0, 0, 0, 1, RtemsRatemonReqCancel_Post_Status_Ok,
0750     RtemsRatemonReqCancel_Post_State_Inactive,
0751     RtemsRatemonReqCancel_Post_Postponed_NA,
0752     RtemsRatemonReqCancel_Post_Scheduler_Called },
0753   { 0, 0, 0, 0, 1, RtemsRatemonReqCancel_Post_Status_NotOwn,
0754     RtemsRatemonReqCancel_Post_State_Nop,
0755     RtemsRatemonReqCancel_Post_Postponed_Nop,
0756     RtemsRatemonReqCancel_Post_Scheduler_Nop }
0757 };
0758 
0759 static const uint8_t
0760 RtemsRatemonReqCancel_Map[] = {
0761   6, 1, 1, 2, 2, 2, 4, 2, 2, 7, 1, 1, 3, 3, 3, 4, 3, 3, 5, 1, 1, 0, 0, 0, 4, 0,
0762   0, 5, 1, 1, 0, 0, 0, 4, 0, 0
0763 };
0764 
0765 static size_t RtemsRatemonReqCancel_Scope( void *arg, char *buf, size_t n )
0766 {
0767   RtemsRatemonReqCancel_Context *ctx;
0768 
0769   ctx = arg;
0770 
0771   if ( ctx->Map.in_action_loop ) {
0772     return T_get_scope( RtemsRatemonReqCancel_PreDesc, buf, n, ctx->Map.pcs );
0773   }
0774 
0775   return 0;
0776 }
0777 
0778 static T_fixture RtemsRatemonReqCancel_Fixture = {
0779   .setup = RtemsRatemonReqCancel_Setup_Wrap,
0780   .stop = NULL,
0781   .teardown = RtemsRatemonReqCancel_Teardown_Wrap,
0782   .scope = RtemsRatemonReqCancel_Scope,
0783   .initial_context = &RtemsRatemonReqCancel_Instance
0784 };
0785 
0786 static inline RtemsRatemonReqCancel_Entry RtemsRatemonReqCancel_PopEntry(
0787   RtemsRatemonReqCancel_Context *ctx
0788 )
0789 {
0790   size_t index;
0791 
0792   index = ctx->Map.index;
0793   ctx->Map.index = index + 1;
0794   return RtemsRatemonReqCancel_Entries[
0795     RtemsRatemonReqCancel_Map[ index ]
0796   ];
0797 }
0798 
0799 static void RtemsRatemonReqCancel_SetPreConditionStates(
0800   RtemsRatemonReqCancel_Context *ctx
0801 )
0802 {
0803   ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0804   ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0805   ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0806 
0807   if ( ctx->Map.entry.Pre_Postponed_NA ) {
0808     ctx->Map.pcs[ 3 ] = RtemsRatemonReqCancel_Pre_Postponed_NA;
0809   } else {
0810     ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
0811   }
0812 }
0813 
0814 static void RtemsRatemonReqCancel_TestVariant(
0815   RtemsRatemonReqCancel_Context *ctx
0816 )
0817 {
0818   RtemsRatemonReqCancel_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0819   RtemsRatemonReqCancel_Pre_Caller_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0820   RtemsRatemonReqCancel_Pre_State_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0821   RtemsRatemonReqCancel_Pre_Postponed_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0822   RtemsRatemonReqCancel_Action( ctx );
0823   RtemsRatemonReqCancel_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0824   RtemsRatemonReqCancel_Post_State_Check( ctx, ctx->Map.entry.Post_State );
0825   RtemsRatemonReqCancel_Post_Postponed_Check(
0826     ctx,
0827     ctx->Map.entry.Post_Postponed
0828   );
0829   RtemsRatemonReqCancel_Post_Scheduler_Check(
0830     ctx,
0831     ctx->Map.entry.Post_Scheduler
0832   );
0833 }
0834 
0835 /**
0836  * @fn void T_case_body_RtemsRatemonReqCancel( void )
0837  */
0838 T_TEST_CASE_FIXTURE( RtemsRatemonReqCancel, &RtemsRatemonReqCancel_Fixture )
0839 {
0840   RtemsRatemonReqCancel_Context *ctx;
0841 
0842   ctx = T_fixture_context();
0843   ctx->Map.in_action_loop = true;
0844   ctx->Map.index = 0;
0845 
0846   for (
0847     ctx->Map.pci[ 0 ] = RtemsRatemonReqCancel_Pre_Id_Valid;
0848     ctx->Map.pci[ 0 ] < RtemsRatemonReqCancel_Pre_Id_NA;
0849     ++ctx->Map.pci[ 0 ]
0850   ) {
0851     for (
0852       ctx->Map.pci[ 1 ] = RtemsRatemonReqCancel_Pre_Caller_OwnerTask;
0853       ctx->Map.pci[ 1 ] < RtemsRatemonReqCancel_Pre_Caller_NA;
0854       ++ctx->Map.pci[ 1 ]
0855     ) {
0856       for (
0857         ctx->Map.pci[ 2 ] = RtemsRatemonReqCancel_Pre_State_Inactive;
0858         ctx->Map.pci[ 2 ] < RtemsRatemonReqCancel_Pre_State_NA;
0859         ++ctx->Map.pci[ 2 ]
0860       ) {
0861         for (
0862           ctx->Map.pci[ 3 ] = RtemsRatemonReqCancel_Pre_Postponed_Zero;
0863           ctx->Map.pci[ 3 ] < RtemsRatemonReqCancel_Pre_Postponed_NA;
0864           ++ctx->Map.pci[ 3 ]
0865         ) {
0866           ctx->Map.entry = RtemsRatemonReqCancel_PopEntry( ctx );
0867 
0868           if ( ctx->Map.entry.Skip ) {
0869             continue;
0870           }
0871 
0872           RtemsRatemonReqCancel_SetPreConditionStates( ctx );
0873           RtemsRatemonReqCancel_Prepare( ctx );
0874           RtemsRatemonReqCancel_TestVariant( ctx );
0875           RtemsRatemonReqCancel_Cleanup( ctx );
0876         }
0877       }
0878     }
0879   }
0880 }
0881 
0882 /** @} */