source: rtems/testsuites/validation/tc-ratemon-timeout.c @ 74a6b33f

Last change on this file since 74a6b33f was 74a6b33f, checked in by Sebastian Huber <sebastian.huber@…>, on 03/17/23 at 14:52:33

validation: Replace enum Event with defines

There is a Doxygen limitation that all compound names (enum, struct,
class, union, group) within a project must be unique.

Update #3716.

  • Property mode set to 100644
File size: 24.9 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RtemsRatemonReqTimeout
7 */
8
9/*
10 * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * This file is part of the RTEMS quality process and was automatically
36 * generated.  If you find something that needs to be fixed or
37 * worded better please post a report or patch to an RTEMS mailing list
38 * or raise a bug report:
39 *
40 * https://www.rtems.org/bugs.html
41 *
42 * For information on updating and regenerating please refer to the How-To
43 * section in the Software Requirements Engineering chapter of the
44 * RTEMS Software Engineering manual.  The manual is provided as a part of
45 * a release.  For development sources please refer to the online
46 * documentation at:
47 *
48 * https://docs.rtems.org
49 */
50
51#ifdef HAVE_CONFIG_H
52#include "config.h"
53#endif
54
55#include <rtems/test-scheduler.h>
56#include <rtems/rtems/ratemonimpl.h>
57
58#include "tx-support.h"
59
60#include <rtems/test.h>
61
62/**
63 * @defgroup RtemsRatemonReqTimeout spec:/rtems/ratemon/req/timeout
64 *
65 * @ingroup TestsuitesValidationNoClock0
66 * @ingroup TestsuitesValidationOneCpu0
67 *
68 * @{
69 */
70
71typedef enum {
72  RtemsRatemonReqTimeout_Pre_WaitFor_PeriodSelf,
73  RtemsRatemonReqTimeout_Pre_WaitFor_PeriodOther,
74  RtemsRatemonReqTimeout_Pre_WaitFor_Other,
75  RtemsRatemonReqTimeout_Pre_WaitFor_NA
76} RtemsRatemonReqTimeout_Pre_WaitFor;
77
78typedef enum {
79  RtemsRatemonReqTimeout_Pre_WaitState_Blocked,
80  RtemsRatemonReqTimeout_Pre_WaitState_IntendToBlock,
81  RtemsRatemonReqTimeout_Pre_WaitState_NA
82} RtemsRatemonReqTimeout_Pre_WaitState;
83
84typedef enum {
85  RtemsRatemonReqTimeout_Pre_PostponedJobs_Zero,
86  RtemsRatemonReqTimeout_Pre_PostponedJobs_NotZeroOrMax,
87  RtemsRatemonReqTimeout_Pre_PostponedJobs_Max,
88  RtemsRatemonReqTimeout_Pre_PostponedJobs_NA
89} RtemsRatemonReqTimeout_Pre_PostponedJobs;
90
91typedef enum {
92  RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
93  RtemsRatemonReqTimeout_Post_PostponedJobs_PlusOne,
94  RtemsRatemonReqTimeout_Post_PostponedJobs_NA
95} RtemsRatemonReqTimeout_Post_PostponedJobs;
96
97typedef enum {
98  RtemsRatemonReqTimeout_Post_ReleaseJob_Yes,
99  RtemsRatemonReqTimeout_Post_ReleaseJob_No,
100  RtemsRatemonReqTimeout_Post_ReleaseJob_NA
101} RtemsRatemonReqTimeout_Post_ReleaseJob;
102
103typedef enum {
104  RtemsRatemonReqTimeout_Post_Unblock_Yes,
105  RtemsRatemonReqTimeout_Post_Unblock_No,
106  RtemsRatemonReqTimeout_Post_Unblock_NA
107} RtemsRatemonReqTimeout_Post_Unblock;
108
109typedef enum {
110  RtemsRatemonReqTimeout_Post_PeriodState_Active,
111  RtemsRatemonReqTimeout_Post_PeriodState_Expired,
112  RtemsRatemonReqTimeout_Post_PeriodState_NA
113} RtemsRatemonReqTimeout_Post_PeriodState;
114
115typedef enum {
116  RtemsRatemonReqTimeout_Post_Timer_Active,
117  RtemsRatemonReqTimeout_Post_Timer_NA
118} RtemsRatemonReqTimeout_Post_Timer;
119
120typedef enum {
121  RtemsRatemonReqTimeout_Post_Uptime_Nop,
122  RtemsRatemonReqTimeout_Post_Uptime_Set,
123  RtemsRatemonReqTimeout_Post_Uptime_NA
124} RtemsRatemonReqTimeout_Post_Uptime;
125
126typedef enum {
127  RtemsRatemonReqTimeout_Post_CPUUsage_Nop,
128  RtemsRatemonReqTimeout_Post_CPUUsage_Set,
129  RtemsRatemonReqTimeout_Post_CPUUsage_NA
130} RtemsRatemonReqTimeout_Post_CPUUsage;
131
132typedef struct {
133  uint32_t Skip : 1;
134  uint32_t Pre_WaitFor_NA : 1;
135  uint32_t Pre_WaitState_NA : 1;
136  uint32_t Pre_PostponedJobs_NA : 1;
137  uint32_t Post_PostponedJobs : 2;
138  uint32_t Post_ReleaseJob : 2;
139  uint32_t Post_Unblock : 2;
140  uint32_t Post_PeriodState : 2;
141  uint32_t Post_Timer : 1;
142  uint32_t Post_Uptime : 2;
143  uint32_t Post_CPUUsage : 2;
144} RtemsRatemonReqTimeout_Entry;
145
146/**
147 * @brief Test context for spec:/rtems/ratemon/req/timeout test case.
148 */
149typedef struct {
150  /**
151   * @brief This member contains the period identifier.
152   */
153  rtems_id period_id;
154
155  /**
156   * @brief This member references the period control block.
157   */
158  Rate_monotonic_Control *period;
159
160  /**
161   * @brief This member contains another period identifier.
162   */
163  rtems_id other_period_id;
164
165  /**
166   * @brief This member contains the worker task identifier.
167   */
168  rtems_id worker_id;
169
170  /**
171   * @brief This member contains the call within ISR request.
172   */
173  CallWithinISRRequest request;
174
175  /**
176   * @brief If this member is true, then the worker shall wait for a period.
177   */
178  bool wait_for_period;
179
180  /**
181   * @brief If this member is true, then the worker shall wait for another
182   *   period.
183   */
184  bool period_is_other;
185
186  /**
187   * @brief If this member is true, then the worker shall intend to block for a
188   *   period.
189   */
190  bool intend_to_block;
191
192  /**
193   * @brief This member contains the postponed jobs count before the timeout.
194   */
195  uint32_t postponed_jobs;
196
197  /**
198   * @brief This member contains the uptime of the period before the timeout.
199   */
200  Timestamp_Control uptime_before;
201
202  /**
203   * @brief This member contains the CPU usage of the period before the
204   *   timeout.
205   */
206  Timestamp_Control cpu_usage_before;
207
208  /**
209   * @brief This member contains the release job counter.
210   */
211  uint32_t release_job_counter;
212
213  /**
214   * @brief This member contains the unblock counter.
215   */
216  uint32_t unblock_counter;
217
218  struct {
219    /**
220     * @brief This member defines the pre-condition indices for the next
221     *   action.
222     */
223    size_t pci[ 3 ];
224
225    /**
226     * @brief This member defines the pre-condition states for the next action.
227     */
228    size_t pcs[ 3 ];
229
230    /**
231     * @brief If this member is true, then the test action loop is executed.
232     */
233    bool in_action_loop;
234
235    /**
236     * @brief This member contains the next transition map index.
237     */
238    size_t index;
239
240    /**
241     * @brief This member contains the current transition map entry.
242     */
243    RtemsRatemonReqTimeout_Entry entry;
244
245    /**
246     * @brief If this member is true, then the current transition variant
247     *   should be skipped.
248     */
249    bool skip;
250  } Map;
251} RtemsRatemonReqTimeout_Context;
252
253static RtemsRatemonReqTimeout_Context
254  RtemsRatemonReqTimeout_Instance;
255
256static const char * const RtemsRatemonReqTimeout_PreDesc_WaitFor[] = {
257  "PeriodSelf",
258  "PeriodOther",
259  "Other",
260  "NA"
261};
262
263static const char * const RtemsRatemonReqTimeout_PreDesc_WaitState[] = {
264  "Blocked",
265  "IntendToBlock",
266  "NA"
267};
268
269static const char * const RtemsRatemonReqTimeout_PreDesc_PostponedJobs[] = {
270  "Zero",
271  "NotZeroOrMax",
272  "Max",
273  "NA"
274};
275
276static const char * const * const RtemsRatemonReqTimeout_PreDesc[] = {
277  RtemsRatemonReqTimeout_PreDesc_WaitFor,
278  RtemsRatemonReqTimeout_PreDesc_WaitState,
279  RtemsRatemonReqTimeout_PreDesc_PostponedJobs,
280  NULL
281};
282
283#define EVENT_RESET RTEMS_EVENT_0
284
285#define EVENT_PERIOD_WAIT RTEMS_EVENT_1
286
287#define EVENT_PERIOD_OTHER RTEMS_EVENT_2
288
289typedef RtemsRatemonReqTimeout_Context Context;
290
291static void Tick( void *arg )
292{
293  Context               *ctx;
294  T_scheduler_log_10     scheduler_log_10;
295  const T_scheduler_log *scheduler_log;
296  size_t                 index;
297
298  ctx = arg;
299  ctx->release_job_counter = 0;
300  ctx->unblock_counter = 0;
301  ctx->uptime_before = ctx->period->time_period_initiated;
302  ctx->cpu_usage_before = ctx->period->cpu_usage_period_initiated;
303  scheduler_log = T_scheduler_record_10( &scheduler_log_10 );
304  T_null( scheduler_log );
305  ClockTick();
306  scheduler_log = T_scheduler_record( NULL );
307  T_eq_ptr( &scheduler_log->header, &scheduler_log_10.header );
308
309  index = 0;
310
311  while ( true ) {
312    const T_scheduler_event *event;
313
314    event = T_scheduler_next_any( &scheduler_log_10.header, &index );
315
316    if ( event == &T_scheduler_event_null ) {
317      break;
318    }
319
320    T_eq_u32( event->thread->Object.id, ctx->worker_id );
321
322    switch ( event->operation ) {
323      case T_SCHEDULER_RELEASE_JOB:
324        ++ctx->release_job_counter;
325        T_eq_u64(
326          event->release_job.deadline,
327          rtems_clock_get_ticks_since_boot() + 1
328        );
329        break;
330      case T_SCHEDULER_UNBLOCK:
331        ++ctx->unblock_counter;
332        break;
333      default:
334        break;
335    }
336  }
337}
338
339static void SchedulerBlock(
340  void                    *arg,
341  const T_scheduler_event *event,
342  T_scheduler_when         when
343)
344{
345  Context *ctx;
346
347  ctx = arg;
348
349  if (
350    when == T_SCHEDULER_BEFORE &&
351    event->operation == T_SCHEDULER_BLOCK
352  ) {
353    T_scheduler_set_event_handler( NULL, NULL );
354    ctx->request.handler = Tick;
355    CallWithinISRSubmit( &ctx->request );
356  }
357}
358
359static Rate_monotonic_Control *GetControl( rtems_id id )
360{
361  Rate_monotonic_Control *period;
362  ISR_lock_Context        lock_context;
363
364  period = _Rate_monotonic_Get( id, &lock_context );
365  T_assert_not_null( period );
366  _ISR_lock_ISR_enable( &lock_context );
367
368  return period;
369}
370
371static void Worker( rtems_task_argument arg )
372{
373  Context          *ctx;
374  rtems_status_code sc;
375
376  ctx = (Context *) arg;
377
378  sc = rtems_rate_monotonic_create( OBJECT_NAME, &ctx->period_id );
379  T_rsc_success( sc );
380
381  sc = rtems_rate_monotonic_create( OBJECT_NAME, &ctx->other_period_id );
382  T_rsc_success( sc );
383
384  while ( true ) {
385    rtems_event_set events;
386
387    events = ReceiveAnyEvents();
388
389    if ( ( events & EVENT_RESET ) != 0 ) {
390      sc = rtems_rate_monotonic_cancel( ctx->period_id );
391      T_rsc_success( sc );
392
393      sc = rtems_rate_monotonic_cancel( ctx->other_period_id );
394      T_rsc_success( sc );
395
396      sc = rtems_rate_monotonic_period( ctx->period_id, 1 );
397      T_rsc_success( sc );
398
399      ctx->period->postponed_jobs = ctx->postponed_jobs;
400    }
401
402    if ( ( events & EVENT_PERIOD_WAIT ) != 0 ) {
403      if ( ctx->intend_to_block ) {
404        T_scheduler_set_event_handler( SchedulerBlock, ctx );
405      }
406
407      sc = rtems_rate_monotonic_period( ctx->period_id, 1 );
408      T_rsc_success( sc );
409    }
410
411    if ( ( events & EVENT_PERIOD_OTHER ) != 0 ) {
412      sc = rtems_rate_monotonic_period( ctx->other_period_id, 2 );
413      T_rsc_success( sc );
414
415      sc = rtems_rate_monotonic_period( ctx->other_period_id, 2 );
416      T_rsc_success( sc );
417    }
418  }
419}
420
421static void RtemsRatemonReqTimeout_Pre_WaitFor_Prepare(
422  RtemsRatemonReqTimeout_Context    *ctx,
423  RtemsRatemonReqTimeout_Pre_WaitFor state
424)
425{
426  switch ( state ) {
427    case RtemsRatemonReqTimeout_Pre_WaitFor_PeriodSelf: {
428      /*
429       * While the owner task of the period waits for the period.
430       */
431      ctx->wait_for_period = true;
432      ctx->period_is_other = false;
433      break;
434    }
435
436    case RtemsRatemonReqTimeout_Pre_WaitFor_PeriodOther: {
437      /*
438       * While the owner task of the period waits for another period.
439       */
440      ctx->wait_for_period = true;
441      ctx->period_is_other = true;
442      break;
443    }
444
445    case RtemsRatemonReqTimeout_Pre_WaitFor_Other: {
446      /*
447       * While the owner task of the period does not wait for a period.
448       */
449      ctx->wait_for_period = false;
450      break;
451    }
452
453    case RtemsRatemonReqTimeout_Pre_WaitFor_NA:
454      break;
455  }
456}
457
458static void RtemsRatemonReqTimeout_Pre_WaitState_Prepare(
459  RtemsRatemonReqTimeout_Context      *ctx,
460  RtemsRatemonReqTimeout_Pre_WaitState state
461)
462{
463  switch ( state ) {
464    case RtemsRatemonReqTimeout_Pre_WaitState_Blocked: {
465      /*
466       * While the owner task is in the blocked wait state.
467       */
468      ctx->intend_to_block = false;
469      break;
470    }
471
472    case RtemsRatemonReqTimeout_Pre_WaitState_IntendToBlock: {
473      /*
474       * While the owner task is in the intend to block wait state.
475       */
476      ctx->intend_to_block = true;
477      break;
478    }
479
480    case RtemsRatemonReqTimeout_Pre_WaitState_NA:
481      break;
482  }
483}
484
485static void RtemsRatemonReqTimeout_Pre_PostponedJobs_Prepare(
486  RtemsRatemonReqTimeout_Context          *ctx,
487  RtemsRatemonReqTimeout_Pre_PostponedJobs state
488)
489{
490  switch ( state ) {
491    case RtemsRatemonReqTimeout_Pre_PostponedJobs_Zero: {
492      /*
493       * While the count of postponed jobs is equal to zero.
494       */
495      ctx->postponed_jobs = 0;
496      break;
497    }
498
499    case RtemsRatemonReqTimeout_Pre_PostponedJobs_NotZeroOrMax: {
500      /*
501       * While the count of postponed jobs is not equal to zero or UINT32_MAX.
502       */
503      ctx->postponed_jobs = 123;
504      break;
505    }
506
507    case RtemsRatemonReqTimeout_Pre_PostponedJobs_Max: {
508      /*
509       * While the count of postponed jobs is equal to UINT32_MAX.
510       */
511      ctx->postponed_jobs = UINT32_MAX;
512      break;
513    }
514
515    case RtemsRatemonReqTimeout_Pre_PostponedJobs_NA:
516      break;
517  }
518}
519
520static void RtemsRatemonReqTimeout_Post_PostponedJobs_Check(
521  RtemsRatemonReqTimeout_Context           *ctx,
522  RtemsRatemonReqTimeout_Post_PostponedJobs state
523)
524{
525  switch ( state ) {
526    case RtemsRatemonReqTimeout_Post_PostponedJobs_Nop: {
527      /*
528       * The count of postponed jobs of the period shall not be modified.
529       */
530      T_eq_u32( ctx->period->postponed_jobs, ctx->postponed_jobs );
531      break;
532    }
533
534    case RtemsRatemonReqTimeout_Post_PostponedJobs_PlusOne: {
535      /*
536       * The count of postponed jobs of the period shall be incremented by one.
537       */
538      T_eq_u32( ctx->period->postponed_jobs, ctx->postponed_jobs + 1 );
539      break;
540    }
541
542    case RtemsRatemonReqTimeout_Post_PostponedJobs_NA:
543      break;
544  }
545}
546
547static void RtemsRatemonReqTimeout_Post_ReleaseJob_Check(
548  RtemsRatemonReqTimeout_Context        *ctx,
549  RtemsRatemonReqTimeout_Post_ReleaseJob state
550)
551{
552  switch ( state ) {
553    case RtemsRatemonReqTimeout_Post_ReleaseJob_Yes: {
554      /*
555       * The owner task of the period shall release a job with a deadline equal
556       * to the clock tick plus the next period length by the timeout
557       * operation.
558       */
559      T_eq_u32( ctx->release_job_counter, 1 );
560      break;
561    }
562
563    case RtemsRatemonReqTimeout_Post_ReleaseJob_No: {
564      /*
565       * The owner task of the period shall not release a job by the timeout
566       * operation.
567       */
568      T_eq_u32( ctx->release_job_counter, 0 );
569      break;
570    }
571
572    case RtemsRatemonReqTimeout_Post_ReleaseJob_NA:
573      break;
574  }
575}
576
577static void RtemsRatemonReqTimeout_Post_Unblock_Check(
578  RtemsRatemonReqTimeout_Context     *ctx,
579  RtemsRatemonReqTimeout_Post_Unblock state
580)
581{
582  switch ( state ) {
583    case RtemsRatemonReqTimeout_Post_Unblock_Yes: {
584      /*
585       * The owner task of the period shall be unblocked by the timeout
586       * operation.
587       */
588      T_eq_u32( ctx->unblock_counter, 1 );
589      break;
590    }
591
592    case RtemsRatemonReqTimeout_Post_Unblock_No: {
593      /*
594       * The owner task of the period shall not be unblocked by the timeout
595       * operation.
596       */
597      T_eq_u32( ctx->unblock_counter, 0 );
598      break;
599    }
600
601    case RtemsRatemonReqTimeout_Post_Unblock_NA:
602      break;
603  }
604}
605
606static void RtemsRatemonReqTimeout_Post_PeriodState_Check(
607  RtemsRatemonReqTimeout_Context         *ctx,
608  RtemsRatemonReqTimeout_Post_PeriodState state
609)
610{
611  switch ( state ) {
612    case RtemsRatemonReqTimeout_Post_PeriodState_Active: {
613      /*
614       * The period state shall be active.
615       */
616      T_eq_int( ctx->period->state, RATE_MONOTONIC_ACTIVE );
617      break;
618    }
619
620    case RtemsRatemonReqTimeout_Post_PeriodState_Expired: {
621      /*
622       * The period state shall be expired.
623       */
624      T_eq_int( ctx->period->state, RATE_MONOTONIC_EXPIRED );
625      break;
626    }
627
628    case RtemsRatemonReqTimeout_Post_PeriodState_NA:
629      break;
630  }
631}
632
633static void RtemsRatemonReqTimeout_Post_Timer_Check(
634  RtemsRatemonReqTimeout_Context   *ctx,
635  RtemsRatemonReqTimeout_Post_Timer state
636)
637{
638  switch ( state ) {
639    case RtemsRatemonReqTimeout_Post_Timer_Active: {
640      /*
641       * The timeout timer of the period shall expired at the current clock
642       * tick plus the next period length.
643       */
644      T_true( _Watchdog_Is_scheduled( &ctx->period->Timer ) );
645      T_eq_u64(
646        ctx->period->Timer.expire,
647        rtems_clock_get_ticks_since_boot() + 1
648      );
649      break;
650    }
651
652    case RtemsRatemonReqTimeout_Post_Timer_NA:
653      break;
654  }
655}
656
657static void RtemsRatemonReqTimeout_Post_Uptime_Check(
658  RtemsRatemonReqTimeout_Context    *ctx,
659  RtemsRatemonReqTimeout_Post_Uptime state
660)
661{
662  switch ( state ) {
663    case RtemsRatemonReqTimeout_Post_Uptime_Nop: {
664      /*
665       * The period initiated CLOCK_MONOTONIC value shall not be modified.
666       */
667      T_eq_i64( ctx->uptime_before, ctx->period->time_period_initiated );
668      break;
669    }
670
671    case RtemsRatemonReqTimeout_Post_Uptime_Set: {
672      /*
673       * The period initiated CLOCK_MONOTONIC value shall be set to the
674       * CLOCK_MONOTONIC at some time point during the timeout operation.
675       */
676      T_ne_i64( ctx->uptime_before, ctx->period->time_period_initiated );
677      break;
678    }
679
680    case RtemsRatemonReqTimeout_Post_Uptime_NA:
681      break;
682  }
683}
684
685static void RtemsRatemonReqTimeout_Post_CPUUsage_Check(
686  RtemsRatemonReqTimeout_Context      *ctx,
687  RtemsRatemonReqTimeout_Post_CPUUsage state
688)
689{
690  switch ( state ) {
691    case RtemsRatemonReqTimeout_Post_CPUUsage_Nop: {
692      /*
693       * The period initiated CPU usage of the owner task value shall not be
694       * modified.
695       */
696      T_eq_i64(
697        ctx->cpu_usage_before,
698        ctx->period->cpu_usage_period_initiated
699      );
700      break;
701    }
702
703    case RtemsRatemonReqTimeout_Post_CPUUsage_Set: {
704      /*
705       * The period initiated CPU usage of the owner task value shall be set to
706       * the CPU usage of the owner task at some time point during the timeout
707       * operation.
708       */
709      T_ne_i64(
710        ctx->cpu_usage_before,
711        ctx->period->cpu_usage_period_initiated
712      );
713      break;
714    }
715
716    case RtemsRatemonReqTimeout_Post_CPUUsage_NA:
717      break;
718  }
719}
720
721static void RtemsRatemonReqTimeout_Setup( RtemsRatemonReqTimeout_Context *ctx )
722{
723  ctx->request.arg = ctx;
724  ctx->worker_id = CreateTask( "WORK", GetSelfPriority() );
725  StartTask( ctx->worker_id, Worker, ctx );
726  Yield();
727  ctx->period = GetControl( ctx->period_id );
728}
729
730static void RtemsRatemonReqTimeout_Setup_Wrap( void *arg )
731{
732  RtemsRatemonReqTimeout_Context *ctx;
733
734  ctx = arg;
735  ctx->Map.in_action_loop = false;
736  RtemsRatemonReqTimeout_Setup( ctx );
737}
738
739static void RtemsRatemonReqTimeout_Teardown(
740  RtemsRatemonReqTimeout_Context *ctx
741)
742{
743  rtems_status_code sc;
744
745  DeleteTask( ctx->worker_id );
746
747  sc = rtems_rate_monotonic_delete( ctx->period_id );
748  T_rsc_success( sc );
749
750  sc = rtems_rate_monotonic_delete( ctx->other_period_id );
751  T_rsc_success( sc );
752}
753
754static void RtemsRatemonReqTimeout_Teardown_Wrap( void *arg )
755{
756  RtemsRatemonReqTimeout_Context *ctx;
757
758  ctx = arg;
759  ctx->Map.in_action_loop = false;
760  RtemsRatemonReqTimeout_Teardown( ctx );
761}
762
763static void RtemsRatemonReqTimeout_Action(
764  RtemsRatemonReqTimeout_Context *ctx
765)
766{
767  SendEvents( ctx->worker_id, EVENT_RESET );
768  Yield();
769
770  if ( ctx->wait_for_period ) {
771    if ( ctx->period_is_other ) {
772      SendEvents( ctx->worker_id, EVENT_PERIOD_OTHER );
773      Yield();
774      Tick( ctx );
775    } else {
776      SendEvents( ctx->worker_id, EVENT_PERIOD_WAIT );
777      Yield();
778
779      if ( !ctx->intend_to_block ) {
780        Tick( ctx );
781      }
782    }
783  } else {
784    Tick( ctx );
785  }
786}
787
788static void RtemsRatemonReqTimeout_Cleanup(
789  RtemsRatemonReqTimeout_Context *ctx
790)
791{
792  ClockTick();
793  Yield();
794}
795
796static const RtemsRatemonReqTimeout_Entry
797RtemsRatemonReqTimeout_Entries[] = {
798  { 0, 0, 1, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_PlusOne,
799    RtemsRatemonReqTimeout_Post_ReleaseJob_No,
800    RtemsRatemonReqTimeout_Post_Unblock_No,
801    RtemsRatemonReqTimeout_Post_PeriodState_Expired,
802    RtemsRatemonReqTimeout_Post_Timer_Active,
803    RtemsRatemonReqTimeout_Post_Uptime_Nop,
804    RtemsRatemonReqTimeout_Post_CPUUsage_Nop },
805  { 1, 0, 0, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_NA,
806    RtemsRatemonReqTimeout_Post_ReleaseJob_NA,
807    RtemsRatemonReqTimeout_Post_Unblock_NA,
808    RtemsRatemonReqTimeout_Post_PeriodState_NA,
809    RtemsRatemonReqTimeout_Post_Timer_NA,
810    RtemsRatemonReqTimeout_Post_Uptime_NA,
811    RtemsRatemonReqTimeout_Post_CPUUsage_NA },
812  { 0, 0, 1, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
813    RtemsRatemonReqTimeout_Post_ReleaseJob_No,
814    RtemsRatemonReqTimeout_Post_Unblock_No,
815    RtemsRatemonReqTimeout_Post_PeriodState_Expired,
816    RtemsRatemonReqTimeout_Post_Timer_Active,
817    RtemsRatemonReqTimeout_Post_Uptime_Nop,
818    RtemsRatemonReqTimeout_Post_CPUUsage_Nop },
819  { 0, 0, 0, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
820    RtemsRatemonReqTimeout_Post_ReleaseJob_Yes,
821    RtemsRatemonReqTimeout_Post_Unblock_Yes,
822    RtemsRatemonReqTimeout_Post_PeriodState_Active,
823    RtemsRatemonReqTimeout_Post_Timer_Active,
824    RtemsRatemonReqTimeout_Post_Uptime_Set,
825    RtemsRatemonReqTimeout_Post_CPUUsage_Set },
826  { 0, 0, 0, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
827    RtemsRatemonReqTimeout_Post_ReleaseJob_Yes,
828    RtemsRatemonReqTimeout_Post_Unblock_No,
829    RtemsRatemonReqTimeout_Post_PeriodState_Active,
830    RtemsRatemonReqTimeout_Post_Timer_Active,
831    RtemsRatemonReqTimeout_Post_Uptime_Set,
832    RtemsRatemonReqTimeout_Post_CPUUsage_Set }
833};
834
835static const uint8_t
836RtemsRatemonReqTimeout_Map[] = {
837  3, 1, 1, 4, 1, 1, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2
838};
839
840static size_t RtemsRatemonReqTimeout_Scope( void *arg, char *buf, size_t n )
841{
842  RtemsRatemonReqTimeout_Context *ctx;
843
844  ctx = arg;
845
846  if ( ctx->Map.in_action_loop ) {
847    return T_get_scope( RtemsRatemonReqTimeout_PreDesc, buf, n, ctx->Map.pcs );
848  }
849
850  return 0;
851}
852
853static T_fixture RtemsRatemonReqTimeout_Fixture = {
854  .setup = RtemsRatemonReqTimeout_Setup_Wrap,
855  .stop = NULL,
856  .teardown = RtemsRatemonReqTimeout_Teardown_Wrap,
857  .scope = RtemsRatemonReqTimeout_Scope,
858  .initial_context = &RtemsRatemonReqTimeout_Instance
859};
860
861static inline RtemsRatemonReqTimeout_Entry RtemsRatemonReqTimeout_PopEntry(
862  RtemsRatemonReqTimeout_Context *ctx
863)
864{
865  size_t index;
866
867  index = ctx->Map.index;
868  ctx->Map.index = index + 1;
869  return RtemsRatemonReqTimeout_Entries[
870    RtemsRatemonReqTimeout_Map[ index ]
871  ];
872}
873
874static void RtemsRatemonReqTimeout_SetPreConditionStates(
875  RtemsRatemonReqTimeout_Context *ctx
876)
877{
878  ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
879
880  if ( ctx->Map.entry.Pre_WaitState_NA ) {
881    ctx->Map.pcs[ 1 ] = RtemsRatemonReqTimeout_Pre_WaitState_NA;
882  } else {
883    ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
884  }
885
886  ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
887}
888
889static void RtemsRatemonReqTimeout_TestVariant(
890  RtemsRatemonReqTimeout_Context *ctx
891)
892{
893  RtemsRatemonReqTimeout_Pre_WaitFor_Prepare( ctx, ctx->Map.pcs[ 0 ] );
894  RtemsRatemonReqTimeout_Pre_WaitState_Prepare( ctx, ctx->Map.pcs[ 1 ] );
895  RtemsRatemonReqTimeout_Pre_PostponedJobs_Prepare( ctx, ctx->Map.pcs[ 2 ] );
896  RtemsRatemonReqTimeout_Action( ctx );
897  RtemsRatemonReqTimeout_Post_PostponedJobs_Check(
898    ctx,
899    ctx->Map.entry.Post_PostponedJobs
900  );
901  RtemsRatemonReqTimeout_Post_ReleaseJob_Check(
902    ctx,
903    ctx->Map.entry.Post_ReleaseJob
904  );
905  RtemsRatemonReqTimeout_Post_Unblock_Check(
906    ctx,
907    ctx->Map.entry.Post_Unblock
908  );
909  RtemsRatemonReqTimeout_Post_PeriodState_Check(
910    ctx,
911    ctx->Map.entry.Post_PeriodState
912  );
913  RtemsRatemonReqTimeout_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
914  RtemsRatemonReqTimeout_Post_Uptime_Check( ctx, ctx->Map.entry.Post_Uptime );
915  RtemsRatemonReqTimeout_Post_CPUUsage_Check(
916    ctx,
917    ctx->Map.entry.Post_CPUUsage
918  );
919}
920
921/**
922 * @fn void T_case_body_RtemsRatemonReqTimeout( void )
923 */
924T_TEST_CASE_FIXTURE( RtemsRatemonReqTimeout, &RtemsRatemonReqTimeout_Fixture )
925{
926  RtemsRatemonReqTimeout_Context *ctx;
927
928  ctx = T_fixture_context();
929  ctx->Map.in_action_loop = true;
930  ctx->Map.index = 0;
931
932  for (
933    ctx->Map.pci[ 0 ] = RtemsRatemonReqTimeout_Pre_WaitFor_PeriodSelf;
934    ctx->Map.pci[ 0 ] < RtemsRatemonReqTimeout_Pre_WaitFor_NA;
935    ++ctx->Map.pci[ 0 ]
936  ) {
937    for (
938      ctx->Map.pci[ 1 ] = RtemsRatemonReqTimeout_Pre_WaitState_Blocked;
939      ctx->Map.pci[ 1 ] < RtemsRatemonReqTimeout_Pre_WaitState_NA;
940      ++ctx->Map.pci[ 1 ]
941    ) {
942      for (
943        ctx->Map.pci[ 2 ] = RtemsRatemonReqTimeout_Pre_PostponedJobs_Zero;
944        ctx->Map.pci[ 2 ] < RtemsRatemonReqTimeout_Pre_PostponedJobs_NA;
945        ++ctx->Map.pci[ 2 ]
946      ) {
947        ctx->Map.entry = RtemsRatemonReqTimeout_PopEntry( ctx );
948
949        if ( ctx->Map.entry.Skip ) {
950          continue;
951        }
952
953        RtemsRatemonReqTimeout_SetPreConditionStates( ctx );
954        RtemsRatemonReqTimeout_TestVariant( ctx );
955        RtemsRatemonReqTimeout_Cleanup( ctx );
956      }
957    }
958  }
959}
960
961/** @} */
Note: See TracBrowser for help on using the repository browser.