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 RtemsRatemonReqTimeout
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/test-scheduler.h>
0056 #include <rtems/rtems/ratemonimpl.h>
0057 
0058 #include "tx-support.h"
0059 
0060 #include <rtems/test.h>
0061 
0062 /**
0063  * @defgroup RtemsRatemonReqTimeout spec:/rtems/ratemon/req/timeout
0064  *
0065  * @ingroup TestsuitesValidationNoClock0
0066  * @ingroup TestsuitesValidationOneCpu0
0067  *
0068  * @{
0069  */
0070 
0071 typedef enum {
0072   RtemsRatemonReqTimeout_Pre_WaitFor_PeriodSelf,
0073   RtemsRatemonReqTimeout_Pre_WaitFor_PeriodOther,
0074   RtemsRatemonReqTimeout_Pre_WaitFor_Other,
0075   RtemsRatemonReqTimeout_Pre_WaitFor_NA
0076 } RtemsRatemonReqTimeout_Pre_WaitFor;
0077 
0078 typedef enum {
0079   RtemsRatemonReqTimeout_Pre_WaitState_Blocked,
0080   RtemsRatemonReqTimeout_Pre_WaitState_IntendToBlock,
0081   RtemsRatemonReqTimeout_Pre_WaitState_NA
0082 } RtemsRatemonReqTimeout_Pre_WaitState;
0083 
0084 typedef enum {
0085   RtemsRatemonReqTimeout_Pre_PostponedJobs_Zero,
0086   RtemsRatemonReqTimeout_Pre_PostponedJobs_NotZeroOrMax,
0087   RtemsRatemonReqTimeout_Pre_PostponedJobs_Max,
0088   RtemsRatemonReqTimeout_Pre_PostponedJobs_NA
0089 } RtemsRatemonReqTimeout_Pre_PostponedJobs;
0090 
0091 typedef enum {
0092   RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
0093   RtemsRatemonReqTimeout_Post_PostponedJobs_PlusOne,
0094   RtemsRatemonReqTimeout_Post_PostponedJobs_NA
0095 } RtemsRatemonReqTimeout_Post_PostponedJobs;
0096 
0097 typedef enum {
0098   RtemsRatemonReqTimeout_Post_ReleaseJob_Yes,
0099   RtemsRatemonReqTimeout_Post_ReleaseJob_No,
0100   RtemsRatemonReqTimeout_Post_ReleaseJob_NA
0101 } RtemsRatemonReqTimeout_Post_ReleaseJob;
0102 
0103 typedef enum {
0104   RtemsRatemonReqTimeout_Post_Unblock_Yes,
0105   RtemsRatemonReqTimeout_Post_Unblock_No,
0106   RtemsRatemonReqTimeout_Post_Unblock_NA
0107 } RtemsRatemonReqTimeout_Post_Unblock;
0108 
0109 typedef enum {
0110   RtemsRatemonReqTimeout_Post_PeriodState_Active,
0111   RtemsRatemonReqTimeout_Post_PeriodState_Expired,
0112   RtemsRatemonReqTimeout_Post_PeriodState_NA
0113 } RtemsRatemonReqTimeout_Post_PeriodState;
0114 
0115 typedef enum {
0116   RtemsRatemonReqTimeout_Post_Timer_Active,
0117   RtemsRatemonReqTimeout_Post_Timer_NA
0118 } RtemsRatemonReqTimeout_Post_Timer;
0119 
0120 typedef enum {
0121   RtemsRatemonReqTimeout_Post_Uptime_Nop,
0122   RtemsRatemonReqTimeout_Post_Uptime_Set,
0123   RtemsRatemonReqTimeout_Post_Uptime_NA
0124 } RtemsRatemonReqTimeout_Post_Uptime;
0125 
0126 typedef enum {
0127   RtemsRatemonReqTimeout_Post_CPUUsage_Nop,
0128   RtemsRatemonReqTimeout_Post_CPUUsage_Set,
0129   RtemsRatemonReqTimeout_Post_CPUUsage_NA
0130 } RtemsRatemonReqTimeout_Post_CPUUsage;
0131 
0132 typedef struct {
0133   uint32_t Skip : 1;
0134   uint32_t Pre_WaitFor_NA : 1;
0135   uint32_t Pre_WaitState_NA : 1;
0136   uint32_t Pre_PostponedJobs_NA : 1;
0137   uint32_t Post_PostponedJobs : 2;
0138   uint32_t Post_ReleaseJob : 2;
0139   uint32_t Post_Unblock : 2;
0140   uint32_t Post_PeriodState : 2;
0141   uint32_t Post_Timer : 1;
0142   uint32_t Post_Uptime : 2;
0143   uint32_t Post_CPUUsage : 2;
0144 } RtemsRatemonReqTimeout_Entry;
0145 
0146 /**
0147  * @brief Test context for spec:/rtems/ratemon/req/timeout test case.
0148  */
0149 typedef struct {
0150   /**
0151    * @brief This member contains the period identifier.
0152    */
0153   rtems_id period_id;
0154 
0155   /**
0156    * @brief This member references the period control block.
0157    */
0158   Rate_monotonic_Control *period;
0159 
0160   /**
0161    * @brief This member contains another period identifier.
0162    */
0163   rtems_id other_period_id;
0164 
0165   /**
0166    * @brief This member contains the worker task identifier.
0167    */
0168   rtems_id worker_id;
0169 
0170   /**
0171    * @brief This member contains the call within ISR request.
0172    */
0173   CallWithinISRRequest request;
0174 
0175   /**
0176    * @brief If this member is true, then the worker shall wait for a period.
0177    */
0178   bool wait_for_period;
0179 
0180   /**
0181    * @brief If this member is true, then the worker shall wait for another
0182    *   period.
0183    */
0184   bool period_is_other;
0185 
0186   /**
0187    * @brief If this member is true, then the worker shall intend to block for a
0188    *   period.
0189    */
0190   bool intend_to_block;
0191 
0192   /**
0193    * @brief This member contains the postponed jobs count before the timeout.
0194    */
0195   uint32_t postponed_jobs;
0196 
0197   /**
0198    * @brief This member contains the uptime of the period before the timeout.
0199    */
0200   Timestamp_Control uptime_before;
0201 
0202   /**
0203    * @brief This member contains the CPU usage of the period before the
0204    *   timeout.
0205    */
0206   Timestamp_Control cpu_usage_before;
0207 
0208   /**
0209    * @brief This member contains the release job counter.
0210    */
0211   uint32_t release_job_counter;
0212 
0213   /**
0214    * @brief This member contains the unblock counter.
0215    */
0216   uint32_t unblock_counter;
0217 
0218   struct {
0219     /**
0220      * @brief This member defines the pre-condition indices for the next
0221      *   action.
0222      */
0223     size_t pci[ 3 ];
0224 
0225     /**
0226      * @brief This member defines the pre-condition states for the next action.
0227      */
0228     size_t pcs[ 3 ];
0229 
0230     /**
0231      * @brief If this member is true, then the test action loop is executed.
0232      */
0233     bool in_action_loop;
0234 
0235     /**
0236      * @brief This member contains the next transition map index.
0237      */
0238     size_t index;
0239 
0240     /**
0241      * @brief This member contains the current transition map entry.
0242      */
0243     RtemsRatemonReqTimeout_Entry entry;
0244 
0245     /**
0246      * @brief If this member is true, then the current transition variant
0247      *   should be skipped.
0248      */
0249     bool skip;
0250   } Map;
0251 } RtemsRatemonReqTimeout_Context;
0252 
0253 static RtemsRatemonReqTimeout_Context
0254   RtemsRatemonReqTimeout_Instance;
0255 
0256 static const char * const RtemsRatemonReqTimeout_PreDesc_WaitFor[] = {
0257   "PeriodSelf",
0258   "PeriodOther",
0259   "Other",
0260   "NA"
0261 };
0262 
0263 static const char * const RtemsRatemonReqTimeout_PreDesc_WaitState[] = {
0264   "Blocked",
0265   "IntendToBlock",
0266   "NA"
0267 };
0268 
0269 static const char * const RtemsRatemonReqTimeout_PreDesc_PostponedJobs[] = {
0270   "Zero",
0271   "NotZeroOrMax",
0272   "Max",
0273   "NA"
0274 };
0275 
0276 static const char * const * const RtemsRatemonReqTimeout_PreDesc[] = {
0277   RtemsRatemonReqTimeout_PreDesc_WaitFor,
0278   RtemsRatemonReqTimeout_PreDesc_WaitState,
0279   RtemsRatemonReqTimeout_PreDesc_PostponedJobs,
0280   NULL
0281 };
0282 
0283 #define EVENT_RESET RTEMS_EVENT_0
0284 
0285 #define EVENT_PERIOD_WAIT RTEMS_EVENT_1
0286 
0287 #define EVENT_PERIOD_OTHER RTEMS_EVENT_2
0288 
0289 typedef RtemsRatemonReqTimeout_Context Context;
0290 
0291 static void Tick( void *arg )
0292 {
0293   Context               *ctx;
0294   T_scheduler_log_10     scheduler_log_10;
0295   const T_scheduler_log *scheduler_log;
0296   size_t                 index;
0297 
0298   ctx = arg;
0299   ctx->release_job_counter = 0;
0300   ctx->unblock_counter = 0;
0301   ctx->uptime_before = ctx->period->time_period_initiated;
0302   ctx->cpu_usage_before = ctx->period->cpu_usage_period_initiated;
0303   scheduler_log = T_scheduler_record_10( &scheduler_log_10 );
0304   T_null( scheduler_log );
0305   ClockTick();
0306   scheduler_log = T_scheduler_record( NULL );
0307   T_eq_ptr( &scheduler_log->header, &scheduler_log_10.header );
0308 
0309   index = 0;
0310 
0311   while ( true ) {
0312     const T_scheduler_event *event;
0313 
0314     event = T_scheduler_next_any( &scheduler_log_10.header, &index );
0315 
0316     if ( event == &T_scheduler_event_null ) {
0317       break;
0318     }
0319 
0320     T_eq_u32( event->thread->Object.id, ctx->worker_id );
0321 
0322     switch ( event->operation ) {
0323       case T_SCHEDULER_RELEASE_JOB:
0324         ++ctx->release_job_counter;
0325         T_eq_u64(
0326           event->release_job.deadline,
0327           rtems_clock_get_ticks_since_boot() + 1
0328         );
0329         break;
0330       case T_SCHEDULER_UNBLOCK:
0331         ++ctx->unblock_counter;
0332         break;
0333       default:
0334         break;
0335     }
0336   }
0337 }
0338 
0339 static void SchedulerBlock(
0340   void                    *arg,
0341   const T_scheduler_event *event,
0342   T_scheduler_when         when
0343 )
0344 {
0345   Context *ctx;
0346 
0347   ctx = arg;
0348 
0349   if (
0350     when == T_SCHEDULER_BEFORE &&
0351     event->operation == T_SCHEDULER_BLOCK
0352   ) {
0353     T_scheduler_set_event_handler( NULL, NULL );
0354     ctx->request.handler = Tick;
0355     CallWithinISRSubmit( &ctx->request );
0356   }
0357 }
0358 
0359 static Rate_monotonic_Control *GetControl( rtems_id id )
0360 {
0361   Rate_monotonic_Control *period;
0362   ISR_lock_Context        lock_context;
0363 
0364   period = _Rate_monotonic_Get( id, &lock_context );
0365   T_assert_not_null( period );
0366   _ISR_lock_ISR_enable( &lock_context );
0367 
0368   return period;
0369 }
0370 
0371 static void Worker( rtems_task_argument arg )
0372 {
0373   Context          *ctx;
0374   rtems_status_code sc;
0375 
0376   ctx = (Context *) arg;
0377 
0378   sc = rtems_rate_monotonic_create( OBJECT_NAME, &ctx->period_id );
0379   T_rsc_success( sc );
0380 
0381   sc = rtems_rate_monotonic_create( OBJECT_NAME, &ctx->other_period_id );
0382   T_rsc_success( sc );
0383 
0384   while ( true ) {
0385     rtems_event_set events;
0386 
0387     events = ReceiveAnyEvents();
0388 
0389     if ( ( events & EVENT_RESET ) != 0 ) {
0390       sc = rtems_rate_monotonic_cancel( ctx->period_id );
0391       T_rsc_success( sc );
0392 
0393       sc = rtems_rate_monotonic_cancel( ctx->other_period_id );
0394       T_rsc_success( sc );
0395 
0396       sc = rtems_rate_monotonic_period( ctx->period_id, 1 );
0397       T_rsc_success( sc );
0398 
0399       ctx->period->postponed_jobs = ctx->postponed_jobs;
0400     }
0401 
0402     if ( ( events & EVENT_PERIOD_WAIT ) != 0 ) {
0403       if ( ctx->intend_to_block ) {
0404         T_scheduler_set_event_handler( SchedulerBlock, ctx );
0405       }
0406 
0407       sc = rtems_rate_monotonic_period( ctx->period_id, 1 );
0408       T_rsc_success( sc );
0409     }
0410 
0411     if ( ( events & EVENT_PERIOD_OTHER ) != 0 ) {
0412       sc = rtems_rate_monotonic_period( ctx->other_period_id, 2 );
0413       T_rsc_success( sc );
0414 
0415       sc = rtems_rate_monotonic_period( ctx->other_period_id, 2 );
0416       T_rsc_success( sc );
0417     }
0418   }
0419 }
0420 
0421 static void RtemsRatemonReqTimeout_Pre_WaitFor_Prepare(
0422   RtemsRatemonReqTimeout_Context    *ctx,
0423   RtemsRatemonReqTimeout_Pre_WaitFor state
0424 )
0425 {
0426   switch ( state ) {
0427     case RtemsRatemonReqTimeout_Pre_WaitFor_PeriodSelf: {
0428       /*
0429        * While the owner task of the period waits for the period.
0430        */
0431       ctx->wait_for_period = true;
0432       ctx->period_is_other = false;
0433       break;
0434     }
0435 
0436     case RtemsRatemonReqTimeout_Pre_WaitFor_PeriodOther: {
0437       /*
0438        * While the owner task of the period waits for another period.
0439        */
0440       ctx->wait_for_period = true;
0441       ctx->period_is_other = true;
0442       break;
0443     }
0444 
0445     case RtemsRatemonReqTimeout_Pre_WaitFor_Other: {
0446       /*
0447        * While the owner task of the period does not wait for a period.
0448        */
0449       ctx->wait_for_period = false;
0450       break;
0451     }
0452 
0453     case RtemsRatemonReqTimeout_Pre_WaitFor_NA:
0454       break;
0455   }
0456 }
0457 
0458 static void RtemsRatemonReqTimeout_Pre_WaitState_Prepare(
0459   RtemsRatemonReqTimeout_Context      *ctx,
0460   RtemsRatemonReqTimeout_Pre_WaitState state
0461 )
0462 {
0463   switch ( state ) {
0464     case RtemsRatemonReqTimeout_Pre_WaitState_Blocked: {
0465       /*
0466        * While the owner task is in the blocked wait state.
0467        */
0468       ctx->intend_to_block = false;
0469       break;
0470     }
0471 
0472     case RtemsRatemonReqTimeout_Pre_WaitState_IntendToBlock: {
0473       /*
0474        * While the owner task is in the intend to block wait state.
0475        */
0476       ctx->intend_to_block = true;
0477       break;
0478     }
0479 
0480     case RtemsRatemonReqTimeout_Pre_WaitState_NA:
0481       break;
0482   }
0483 }
0484 
0485 static void RtemsRatemonReqTimeout_Pre_PostponedJobs_Prepare(
0486   RtemsRatemonReqTimeout_Context          *ctx,
0487   RtemsRatemonReqTimeout_Pre_PostponedJobs state
0488 )
0489 {
0490   switch ( state ) {
0491     case RtemsRatemonReqTimeout_Pre_PostponedJobs_Zero: {
0492       /*
0493        * While the count of postponed jobs is equal to zero.
0494        */
0495       ctx->postponed_jobs = 0;
0496       break;
0497     }
0498 
0499     case RtemsRatemonReqTimeout_Pre_PostponedJobs_NotZeroOrMax: {
0500       /*
0501        * While the count of postponed jobs is not equal to zero or UINT32_MAX.
0502        */
0503       ctx->postponed_jobs = 123;
0504       break;
0505     }
0506 
0507     case RtemsRatemonReqTimeout_Pre_PostponedJobs_Max: {
0508       /*
0509        * While the count of postponed jobs is equal to UINT32_MAX.
0510        */
0511       ctx->postponed_jobs = UINT32_MAX;
0512       break;
0513     }
0514 
0515     case RtemsRatemonReqTimeout_Pre_PostponedJobs_NA:
0516       break;
0517   }
0518 }
0519 
0520 static void RtemsRatemonReqTimeout_Post_PostponedJobs_Check(
0521   RtemsRatemonReqTimeout_Context           *ctx,
0522   RtemsRatemonReqTimeout_Post_PostponedJobs state
0523 )
0524 {
0525   switch ( state ) {
0526     case RtemsRatemonReqTimeout_Post_PostponedJobs_Nop: {
0527       /*
0528        * The count of postponed jobs of the period shall not be modified.
0529        */
0530       T_eq_u32( ctx->period->postponed_jobs, ctx->postponed_jobs );
0531       break;
0532     }
0533 
0534     case RtemsRatemonReqTimeout_Post_PostponedJobs_PlusOne: {
0535       /*
0536        * The count of postponed jobs of the period shall be incremented by one.
0537        */
0538       T_eq_u32( ctx->period->postponed_jobs, ctx->postponed_jobs + 1 );
0539       break;
0540     }
0541 
0542     case RtemsRatemonReqTimeout_Post_PostponedJobs_NA:
0543       break;
0544   }
0545 }
0546 
0547 static void RtemsRatemonReqTimeout_Post_ReleaseJob_Check(
0548   RtemsRatemonReqTimeout_Context        *ctx,
0549   RtemsRatemonReqTimeout_Post_ReleaseJob state
0550 )
0551 {
0552   switch ( state ) {
0553     case RtemsRatemonReqTimeout_Post_ReleaseJob_Yes: {
0554       /*
0555        * The owner task of the period shall release a job with a deadline equal
0556        * to the clock tick plus the next period length by the timeout
0557        * operation.
0558        */
0559       T_eq_u32( ctx->release_job_counter, 1 );
0560       break;
0561     }
0562 
0563     case RtemsRatemonReqTimeout_Post_ReleaseJob_No: {
0564       /*
0565        * The owner task of the period shall not release a job by the timeout
0566        * operation.
0567        */
0568       T_eq_u32( ctx->release_job_counter, 0 );
0569       break;
0570     }
0571 
0572     case RtemsRatemonReqTimeout_Post_ReleaseJob_NA:
0573       break;
0574   }
0575 }
0576 
0577 static void RtemsRatemonReqTimeout_Post_Unblock_Check(
0578   RtemsRatemonReqTimeout_Context     *ctx,
0579   RtemsRatemonReqTimeout_Post_Unblock state
0580 )
0581 {
0582   switch ( state ) {
0583     case RtemsRatemonReqTimeout_Post_Unblock_Yes: {
0584       /*
0585        * The owner task of the period shall be unblocked by the timeout
0586        * operation.
0587        */
0588       T_eq_u32( ctx->unblock_counter, 1 );
0589       break;
0590     }
0591 
0592     case RtemsRatemonReqTimeout_Post_Unblock_No: {
0593       /*
0594        * The owner task of the period shall not be unblocked by the timeout
0595        * operation.
0596        */
0597       T_eq_u32( ctx->unblock_counter, 0 );
0598       break;
0599     }
0600 
0601     case RtemsRatemonReqTimeout_Post_Unblock_NA:
0602       break;
0603   }
0604 }
0605 
0606 static void RtemsRatemonReqTimeout_Post_PeriodState_Check(
0607   RtemsRatemonReqTimeout_Context         *ctx,
0608   RtemsRatemonReqTimeout_Post_PeriodState state
0609 )
0610 {
0611   switch ( state ) {
0612     case RtemsRatemonReqTimeout_Post_PeriodState_Active: {
0613       /*
0614        * The period state shall be active.
0615        */
0616       T_eq_int( ctx->period->state, RATE_MONOTONIC_ACTIVE );
0617       break;
0618     }
0619 
0620     case RtemsRatemonReqTimeout_Post_PeriodState_Expired: {
0621       /*
0622        * The period state shall be expired.
0623        */
0624       T_eq_int( ctx->period->state, RATE_MONOTONIC_EXPIRED );
0625       break;
0626     }
0627 
0628     case RtemsRatemonReqTimeout_Post_PeriodState_NA:
0629       break;
0630   }
0631 }
0632 
0633 static void RtemsRatemonReqTimeout_Post_Timer_Check(
0634   RtemsRatemonReqTimeout_Context   *ctx,
0635   RtemsRatemonReqTimeout_Post_Timer state
0636 )
0637 {
0638   switch ( state ) {
0639     case RtemsRatemonReqTimeout_Post_Timer_Active: {
0640       /*
0641        * The timeout timer of the period shall expired at the current clock
0642        * tick plus the next period length.
0643        */
0644       T_true( _Watchdog_Is_scheduled( &ctx->period->Timer ) );
0645       T_eq_u64(
0646         ctx->period->Timer.expire,
0647         rtems_clock_get_ticks_since_boot() + 1
0648       );
0649       break;
0650     }
0651 
0652     case RtemsRatemonReqTimeout_Post_Timer_NA:
0653       break;
0654   }
0655 }
0656 
0657 static void RtemsRatemonReqTimeout_Post_Uptime_Check(
0658   RtemsRatemonReqTimeout_Context    *ctx,
0659   RtemsRatemonReqTimeout_Post_Uptime state
0660 )
0661 {
0662   switch ( state ) {
0663     case RtemsRatemonReqTimeout_Post_Uptime_Nop: {
0664       /*
0665        * The period initiated CLOCK_MONOTONIC value shall not be modified.
0666        */
0667       T_eq_i64( ctx->uptime_before, ctx->period->time_period_initiated );
0668       break;
0669     }
0670 
0671     case RtemsRatemonReqTimeout_Post_Uptime_Set: {
0672       /*
0673        * The period initiated CLOCK_MONOTONIC value shall be set to the
0674        * CLOCK_MONOTONIC at some time point during the timeout operation.
0675        */
0676       T_ne_i64( ctx->uptime_before, ctx->period->time_period_initiated );
0677       break;
0678     }
0679 
0680     case RtemsRatemonReqTimeout_Post_Uptime_NA:
0681       break;
0682   }
0683 }
0684 
0685 static void RtemsRatemonReqTimeout_Post_CPUUsage_Check(
0686   RtemsRatemonReqTimeout_Context      *ctx,
0687   RtemsRatemonReqTimeout_Post_CPUUsage state
0688 )
0689 {
0690   switch ( state ) {
0691     case RtemsRatemonReqTimeout_Post_CPUUsage_Nop: {
0692       /*
0693        * The period initiated CPU usage of the owner task value shall not be
0694        * modified.
0695        */
0696       T_eq_i64(
0697         ctx->cpu_usage_before,
0698         ctx->period->cpu_usage_period_initiated
0699       );
0700       break;
0701     }
0702 
0703     case RtemsRatemonReqTimeout_Post_CPUUsage_Set: {
0704       /*
0705        * The period initiated CPU usage of the owner task value shall be set to
0706        * the CPU usage of the owner task at some time point during the timeout
0707        * operation.
0708        */
0709       T_ne_i64(
0710         ctx->cpu_usage_before,
0711         ctx->period->cpu_usage_period_initiated
0712       );
0713       break;
0714     }
0715 
0716     case RtemsRatemonReqTimeout_Post_CPUUsage_NA:
0717       break;
0718   }
0719 }
0720 
0721 static void RtemsRatemonReqTimeout_Setup( RtemsRatemonReqTimeout_Context *ctx )
0722 {
0723   ctx->request.arg = ctx;
0724   ctx->worker_id = CreateTask( "WORK", GetSelfPriority() );
0725   StartTask( ctx->worker_id, Worker, ctx );
0726   Yield();
0727   ctx->period = GetControl( ctx->period_id );
0728 }
0729 
0730 static void RtemsRatemonReqTimeout_Setup_Wrap( void *arg )
0731 {
0732   RtemsRatemonReqTimeout_Context *ctx;
0733 
0734   ctx = arg;
0735   ctx->Map.in_action_loop = false;
0736   RtemsRatemonReqTimeout_Setup( ctx );
0737 }
0738 
0739 static void RtemsRatemonReqTimeout_Teardown(
0740   RtemsRatemonReqTimeout_Context *ctx
0741 )
0742 {
0743   rtems_status_code sc;
0744 
0745   DeleteTask( ctx->worker_id );
0746 
0747   sc = rtems_rate_monotonic_delete( ctx->period_id );
0748   T_rsc_success( sc );
0749 
0750   sc = rtems_rate_monotonic_delete( ctx->other_period_id );
0751   T_rsc_success( sc );
0752 }
0753 
0754 static void RtemsRatemonReqTimeout_Teardown_Wrap( void *arg )
0755 {
0756   RtemsRatemonReqTimeout_Context *ctx;
0757 
0758   ctx = arg;
0759   ctx->Map.in_action_loop = false;
0760   RtemsRatemonReqTimeout_Teardown( ctx );
0761 }
0762 
0763 static void RtemsRatemonReqTimeout_Action(
0764   RtemsRatemonReqTimeout_Context *ctx
0765 )
0766 {
0767   SendEvents( ctx->worker_id, EVENT_RESET );
0768   Yield();
0769 
0770   if ( ctx->wait_for_period ) {
0771     if ( ctx->period_is_other ) {
0772       SendEvents( ctx->worker_id, EVENT_PERIOD_OTHER );
0773       Yield();
0774       Tick( ctx );
0775     } else {
0776       SendEvents( ctx->worker_id, EVENT_PERIOD_WAIT );
0777       Yield();
0778 
0779       if ( !ctx->intend_to_block ) {
0780         Tick( ctx );
0781       }
0782     }
0783   } else {
0784     Tick( ctx );
0785   }
0786 }
0787 
0788 static void RtemsRatemonReqTimeout_Cleanup(
0789   RtemsRatemonReqTimeout_Context *ctx
0790 )
0791 {
0792   ClockTick();
0793   Yield();
0794 }
0795 
0796 static const RtemsRatemonReqTimeout_Entry
0797 RtemsRatemonReqTimeout_Entries[] = {
0798   { 0, 0, 1, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_PlusOne,
0799     RtemsRatemonReqTimeout_Post_ReleaseJob_No,
0800     RtemsRatemonReqTimeout_Post_Unblock_No,
0801     RtemsRatemonReqTimeout_Post_PeriodState_Expired,
0802     RtemsRatemonReqTimeout_Post_Timer_Active,
0803     RtemsRatemonReqTimeout_Post_Uptime_Nop,
0804     RtemsRatemonReqTimeout_Post_CPUUsage_Nop },
0805   { 1, 0, 0, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_NA,
0806     RtemsRatemonReqTimeout_Post_ReleaseJob_NA,
0807     RtemsRatemonReqTimeout_Post_Unblock_NA,
0808     RtemsRatemonReqTimeout_Post_PeriodState_NA,
0809     RtemsRatemonReqTimeout_Post_Timer_NA,
0810     RtemsRatemonReqTimeout_Post_Uptime_NA,
0811     RtemsRatemonReqTimeout_Post_CPUUsage_NA },
0812   { 0, 0, 1, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
0813     RtemsRatemonReqTimeout_Post_ReleaseJob_No,
0814     RtemsRatemonReqTimeout_Post_Unblock_No,
0815     RtemsRatemonReqTimeout_Post_PeriodState_Expired,
0816     RtemsRatemonReqTimeout_Post_Timer_Active,
0817     RtemsRatemonReqTimeout_Post_Uptime_Nop,
0818     RtemsRatemonReqTimeout_Post_CPUUsage_Nop },
0819   { 0, 0, 0, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
0820     RtemsRatemonReqTimeout_Post_ReleaseJob_Yes,
0821     RtemsRatemonReqTimeout_Post_Unblock_Yes,
0822     RtemsRatemonReqTimeout_Post_PeriodState_Active,
0823     RtemsRatemonReqTimeout_Post_Timer_Active,
0824     RtemsRatemonReqTimeout_Post_Uptime_Set,
0825     RtemsRatemonReqTimeout_Post_CPUUsage_Set },
0826   { 0, 0, 0, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
0827     RtemsRatemonReqTimeout_Post_ReleaseJob_Yes,
0828     RtemsRatemonReqTimeout_Post_Unblock_No,
0829     RtemsRatemonReqTimeout_Post_PeriodState_Active,
0830     RtemsRatemonReqTimeout_Post_Timer_Active,
0831     RtemsRatemonReqTimeout_Post_Uptime_Set,
0832     RtemsRatemonReqTimeout_Post_CPUUsage_Set }
0833 };
0834 
0835 static const uint8_t
0836 RtemsRatemonReqTimeout_Map[] = {
0837   3, 1, 1, 4, 1, 1, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2
0838 };
0839 
0840 static size_t RtemsRatemonReqTimeout_Scope( void *arg, char *buf, size_t n )
0841 {
0842   RtemsRatemonReqTimeout_Context *ctx;
0843 
0844   ctx = arg;
0845 
0846   if ( ctx->Map.in_action_loop ) {
0847     return T_get_scope( RtemsRatemonReqTimeout_PreDesc, buf, n, ctx->Map.pcs );
0848   }
0849 
0850   return 0;
0851 }
0852 
0853 static T_fixture RtemsRatemonReqTimeout_Fixture = {
0854   .setup = RtemsRatemonReqTimeout_Setup_Wrap,
0855   .stop = NULL,
0856   .teardown = RtemsRatemonReqTimeout_Teardown_Wrap,
0857   .scope = RtemsRatemonReqTimeout_Scope,
0858   .initial_context = &RtemsRatemonReqTimeout_Instance
0859 };
0860 
0861 static inline RtemsRatemonReqTimeout_Entry RtemsRatemonReqTimeout_PopEntry(
0862   RtemsRatemonReqTimeout_Context *ctx
0863 )
0864 {
0865   size_t index;
0866 
0867   index = ctx->Map.index;
0868   ctx->Map.index = index + 1;
0869   return RtemsRatemonReqTimeout_Entries[
0870     RtemsRatemonReqTimeout_Map[ index ]
0871   ];
0872 }
0873 
0874 static void RtemsRatemonReqTimeout_SetPreConditionStates(
0875   RtemsRatemonReqTimeout_Context *ctx
0876 )
0877 {
0878   ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0879 
0880   if ( ctx->Map.entry.Pre_WaitState_NA ) {
0881     ctx->Map.pcs[ 1 ] = RtemsRatemonReqTimeout_Pre_WaitState_NA;
0882   } else {
0883     ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0884   }
0885 
0886   ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0887 }
0888 
0889 static void RtemsRatemonReqTimeout_TestVariant(
0890   RtemsRatemonReqTimeout_Context *ctx
0891 )
0892 {
0893   RtemsRatemonReqTimeout_Pre_WaitFor_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0894   RtemsRatemonReqTimeout_Pre_WaitState_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0895   RtemsRatemonReqTimeout_Pre_PostponedJobs_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0896   RtemsRatemonReqTimeout_Action( ctx );
0897   RtemsRatemonReqTimeout_Post_PostponedJobs_Check(
0898     ctx,
0899     ctx->Map.entry.Post_PostponedJobs
0900   );
0901   RtemsRatemonReqTimeout_Post_ReleaseJob_Check(
0902     ctx,
0903     ctx->Map.entry.Post_ReleaseJob
0904   );
0905   RtemsRatemonReqTimeout_Post_Unblock_Check(
0906     ctx,
0907     ctx->Map.entry.Post_Unblock
0908   );
0909   RtemsRatemonReqTimeout_Post_PeriodState_Check(
0910     ctx,
0911     ctx->Map.entry.Post_PeriodState
0912   );
0913   RtemsRatemonReqTimeout_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
0914   RtemsRatemonReqTimeout_Post_Uptime_Check( ctx, ctx->Map.entry.Post_Uptime );
0915   RtemsRatemonReqTimeout_Post_CPUUsage_Check(
0916     ctx,
0917     ctx->Map.entry.Post_CPUUsage
0918   );
0919 }
0920 
0921 /**
0922  * @fn void T_case_body_RtemsRatemonReqTimeout( void )
0923  */
0924 T_TEST_CASE_FIXTURE( RtemsRatemonReqTimeout, &RtemsRatemonReqTimeout_Fixture )
0925 {
0926   RtemsRatemonReqTimeout_Context *ctx;
0927 
0928   ctx = T_fixture_context();
0929   ctx->Map.in_action_loop = true;
0930   ctx->Map.index = 0;
0931 
0932   for (
0933     ctx->Map.pci[ 0 ] = RtemsRatemonReqTimeout_Pre_WaitFor_PeriodSelf;
0934     ctx->Map.pci[ 0 ] < RtemsRatemonReqTimeout_Pre_WaitFor_NA;
0935     ++ctx->Map.pci[ 0 ]
0936   ) {
0937     for (
0938       ctx->Map.pci[ 1 ] = RtemsRatemonReqTimeout_Pre_WaitState_Blocked;
0939       ctx->Map.pci[ 1 ] < RtemsRatemonReqTimeout_Pre_WaitState_NA;
0940       ++ctx->Map.pci[ 1 ]
0941     ) {
0942       for (
0943         ctx->Map.pci[ 2 ] = RtemsRatemonReqTimeout_Pre_PostponedJobs_Zero;
0944         ctx->Map.pci[ 2 ] < RtemsRatemonReqTimeout_Pre_PostponedJobs_NA;
0945         ++ctx->Map.pci[ 2 ]
0946       ) {
0947         ctx->Map.entry = RtemsRatemonReqTimeout_PopEntry( ctx );
0948 
0949         if ( ctx->Map.entry.Skip ) {
0950           continue;
0951         }
0952 
0953         RtemsRatemonReqTimeout_SetPreConditionStates( ctx );
0954         RtemsRatemonReqTimeout_TestVariant( ctx );
0955         RtemsRatemonReqTimeout_Cleanup( ctx );
0956       }
0957     }
0958   }
0959 }
0960 
0961 /** @} */