source: rtems/testsuites/validation/tc-clock-nanosleep.c

Last change on this file was 610b54d8, checked in by Sebastian Huber <sebastian.huber@…>, on 07/21/23 at 07:30:07

testsuites: Remove stray ';'

  • Property mode set to 100644
File size: 28.4 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup CReqClockNanosleep
7 */
8
9/*
10 * Copyright (C) 2021 embedded brains GmbH & Co. KG
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 <errno.h>
56#include <limits.h>
57#include <rtems.h>
58#include <time.h>
59#include <rtems/test-scheduler.h>
60#include <rtems/score/timecounter.h>
61
62#include "tx-support.h"
63
64#include <rtems/test.h>
65
66/**
67 * @defgroup CReqClockNanosleep spec:/c/req/clock-nanosleep
68 *
69 * @ingroup TestsuitesValidationNoClock0
70 *
71 * @{
72 */
73
74typedef enum {
75  CReqClockNanosleep_Pre_ClockId_Monotonic,
76  CReqClockNanosleep_Pre_ClockId_Realtime,
77  CReqClockNanosleep_Pre_ClockId_Invalid,
78  CReqClockNanosleep_Pre_ClockId_NA
79} CReqClockNanosleep_Pre_ClockId;
80
81typedef enum {
82  CReqClockNanosleep_Pre_Abstime_Yes,
83  CReqClockNanosleep_Pre_Abstime_No,
84  CReqClockNanosleep_Pre_Abstime_NA
85} CReqClockNanosleep_Pre_Abstime;
86
87typedef enum {
88  CReqClockNanosleep_Pre_RQTp_Valid,
89  CReqClockNanosleep_Pre_RQTp_Null,
90  CReqClockNanosleep_Pre_RQTp_NA
91} CReqClockNanosleep_Pre_RQTp;
92
93typedef enum {
94  CReqClockNanosleep_Pre_RQTpNSec_Valid,
95  CReqClockNanosleep_Pre_RQTpNSec_Invalid,
96  CReqClockNanosleep_Pre_RQTpNSec_NA
97} CReqClockNanosleep_Pre_RQTpNSec;
98
99typedef enum {
100  CReqClockNanosleep_Pre_RQTpSec_Negative,
101  CReqClockNanosleep_Pre_RQTpSec_FarFuture,
102  CReqClockNanosleep_Pre_RQTpSec_Future,
103  CReqClockNanosleep_Pre_RQTpSec_PastOrNow,
104  CReqClockNanosleep_Pre_RQTpSec_NA
105} CReqClockNanosleep_Pre_RQTpSec;
106
107typedef enum {
108  CReqClockNanosleep_Pre_RMTp_Valid,
109  CReqClockNanosleep_Pre_RMTp_Null,
110  CReqClockNanosleep_Pre_RMTp_NA
111} CReqClockNanosleep_Pre_RMTp;
112
113typedef enum {
114  CReqClockNanosleep_Post_Status_Zero,
115  CReqClockNanosleep_Post_Status_ENOTSUP,
116  CReqClockNanosleep_Post_Status_EINVAL,
117  CReqClockNanosleep_Post_Status_NA
118} CReqClockNanosleep_Post_Status;
119
120typedef enum {
121  CReqClockNanosleep_Post_Timer_Inactive,
122  CReqClockNanosleep_Post_Timer_Monotonic,
123  CReqClockNanosleep_Post_Timer_Realtime,
124  CReqClockNanosleep_Post_Timer_NA
125} CReqClockNanosleep_Post_Timer;
126
127typedef enum {
128  CReqClockNanosleep_Post_Expire_Last,
129  CReqClockNanosleep_Post_Expire_Absolute,
130  CReqClockNanosleep_Post_Expire_Relative,
131  CReqClockNanosleep_Post_Expire_NA
132} CReqClockNanosleep_Post_Expire;
133
134typedef enum {
135  CReqClockNanosleep_Post_Scheduler_Block,
136  CReqClockNanosleep_Post_Scheduler_BlockUnblock,
137  CReqClockNanosleep_Post_Scheduler_Nop,
138  CReqClockNanosleep_Post_Scheduler_NA
139} CReqClockNanosleep_Post_Scheduler;
140
141typedef enum {
142  CReqClockNanosleep_Post_RMTp_Zero,
143  CReqClockNanosleep_Post_RMTp_Nop,
144  CReqClockNanosleep_Post_RMTp_NA
145} CReqClockNanosleep_Post_RMTp;
146
147typedef struct {
148  uint32_t Skip : 1;
149  uint32_t Pre_ClockId_NA : 1;
150  uint32_t Pre_Abstime_NA : 1;
151  uint32_t Pre_RQTp_NA : 1;
152  uint32_t Pre_RQTpNSec_NA : 1;
153  uint32_t Pre_RQTpSec_NA : 1;
154  uint32_t Pre_RMTp_NA : 1;
155  uint32_t Post_Status : 2;
156  uint32_t Post_Timer : 2;
157  uint32_t Post_Expire : 2;
158  uint32_t Post_Scheduler : 2;
159  uint32_t Post_RMTp : 2;
160} CReqClockNanosleep_Entry;
161
162/**
163 * @brief Test context for spec:/c/req/clock-nanosleep test case.
164 */
165typedef struct {
166  /**
167   * @brief This member provides the scheduler operation records.
168   */
169  T_scheduler_log_4 scheduler_log;
170
171  /**
172   * @brief This member contains the CLOCK_REALTIME value before the
173   *   clock_nanosleep() call.
174   */
175  struct timespec now_realtime;
176
177  /**
178   * @brief This member contains the CLOCK_MONOTONIC value before the
179   *   clock_nanosleep() call.
180   */
181  struct timespec now_monotonic;
182
183  /**
184   * @brief This member contains the worker task identifier.
185   */
186  rtems_id worker_id;
187
188  /**
189   * @brief This member contains the timer information of the worker task.
190   */
191  TaskTimerInfo timer_info;
192
193  /**
194   * @brief This member provides the object referenced by the ``rqtp``
195   *   parameter.
196   */
197  struct timespec rqtp_obj;
198
199  /**
200   * @brief This member provides the object referenced by the ``rmtp``
201   *   parameter.
202   */
203  struct timespec rmtp_obj;
204
205  /**
206   * @brief This member contains the return value of the clock_nanosleep()
207   *   call.
208   */
209  int status;
210
211  /**
212   * @brief This member specifies the ``clock_id`` parameter value.
213   */
214  clockid_t clock_id;
215
216  /**
217   * @brief This member specifies the ``flags`` parameter value.
218   */
219  int flags;
220
221  /**
222   * @brief This member specifies the ``rqtp`` parameter value.
223   */
224  const struct timespec *rqtp;
225
226  /**
227   * @brief This member specifies the ``rmtp`` parameter value.
228   */
229  struct timespec *rmtp;
230
231  struct {
232    /**
233     * @brief This member defines the pre-condition indices for the next
234     *   action.
235     */
236    size_t pci[ 6 ];
237
238    /**
239     * @brief This member defines the pre-condition states for the next action.
240     */
241    size_t pcs[ 6 ];
242
243    /**
244     * @brief If this member is true, then the test action loop is executed.
245     */
246    bool in_action_loop;
247
248    /**
249     * @brief This member contains the next transition map index.
250     */
251    size_t index;
252
253    /**
254     * @brief This member contains the current transition map entry.
255     */
256    CReqClockNanosleep_Entry entry;
257
258    /**
259     * @brief If this member is true, then the current transition variant
260     *   should be skipped.
261     */
262    bool skip;
263  } Map;
264} CReqClockNanosleep_Context;
265
266static CReqClockNanosleep_Context
267  CReqClockNanosleep_Instance;
268
269static const char * const CReqClockNanosleep_PreDesc_ClockId[] = {
270  "Monotonic",
271  "Realtime",
272  "Invalid",
273  "NA"
274};
275
276static const char * const CReqClockNanosleep_PreDesc_Abstime[] = {
277  "Yes",
278  "No",
279  "NA"
280};
281
282static const char * const CReqClockNanosleep_PreDesc_RQTp[] = {
283  "Valid",
284  "Null",
285  "NA"
286};
287
288static const char * const CReqClockNanosleep_PreDesc_RQTpNSec[] = {
289  "Valid",
290  "Invalid",
291  "NA"
292};
293
294static const char * const CReqClockNanosleep_PreDesc_RQTpSec[] = {
295  "Negative",
296  "FarFuture",
297  "Future",
298  "PastOrNow",
299  "NA"
300};
301
302static const char * const CReqClockNanosleep_PreDesc_RMTp[] = {
303  "Valid",
304  "Null",
305  "NA"
306};
307
308static const char * const * const CReqClockNanosleep_PreDesc[] = {
309  CReqClockNanosleep_PreDesc_ClockId,
310  CReqClockNanosleep_PreDesc_Abstime,
311  CReqClockNanosleep_PreDesc_RQTp,
312  CReqClockNanosleep_PreDesc_RQTpNSec,
313  CReqClockNanosleep_PreDesc_RQTpSec,
314  CReqClockNanosleep_PreDesc_RMTp,
315  NULL
316};
317
318typedef CReqClockNanosleep_Context Context;
319
320static void Worker( rtems_task_argument arg )
321{
322  Context *ctx;
323
324  ctx = (Context *) arg;
325
326  while ( true ) {
327    T_scheduler_log *log;
328    uint32_t         counter;
329
330    SuspendSelf();
331
332    log = T_scheduler_record_4( &ctx->scheduler_log );
333    T_null( log );
334
335    counter = GetTimecountCounter();
336    _Timecounter_Nanotime( &ctx->now_realtime );
337    SetTimecountCounter( counter );
338
339    counter = GetTimecountCounter();
340    _Timecounter_Nanouptime( &ctx->now_monotonic );
341    SetTimecountCounter( counter );
342
343    ctx->status = clock_nanosleep(
344      ctx->clock_id,
345      ctx->flags,
346      ctx->rqtp,
347      ctx->rmtp
348    );
349
350    (void) T_scheduler_record( NULL );
351  }
352}
353
354static void CReqClockNanosleep_Pre_ClockId_Prepare(
355  CReqClockNanosleep_Context    *ctx,
356  CReqClockNanosleep_Pre_ClockId state
357)
358{
359  switch ( state ) {
360    case CReqClockNanosleep_Pre_ClockId_Monotonic: {
361      /*
362       * While the ``clock_id`` parameter is equal to CLOCK_MONOTONIC.
363       */
364      ctx->clock_id = CLOCK_MONOTONIC;
365      break;
366    }
367
368    case CReqClockNanosleep_Pre_ClockId_Realtime: {
369      /*
370       * While the ``clock_id`` parameter is equal to CLOCK_REALTIME.
371       */
372      ctx->clock_id = CLOCK_REALTIME;
373      break;
374    }
375
376    case CReqClockNanosleep_Pre_ClockId_Invalid: {
377      /*
378       * While the ``clock_id`` parameter is an invalid clock identifier.
379       */
380      ctx->clock_id = INT_MAX;
381      break;
382    }
383
384    case CReqClockNanosleep_Pre_ClockId_NA:
385      break;
386  }
387}
388
389static void CReqClockNanosleep_Pre_Abstime_Prepare(
390  CReqClockNanosleep_Context    *ctx,
391  CReqClockNanosleep_Pre_Abstime state
392)
393{
394  switch ( state ) {
395    case CReqClockNanosleep_Pre_Abstime_Yes: {
396      /*
397       * While the ``flags`` parameter indicates an absolute time.
398       */
399      ctx->flags |= TIMER_ABSTIME;
400      break;
401    }
402
403    case CReqClockNanosleep_Pre_Abstime_No: {
404      /*
405       * While the ``flags`` parameter does not indicate an absolute time.
406       */
407      /* This is the default */
408      break;
409    }
410
411    case CReqClockNanosleep_Pre_Abstime_NA:
412      break;
413  }
414}
415
416static void CReqClockNanosleep_Pre_RQTp_Prepare(
417  CReqClockNanosleep_Context *ctx,
418  CReqClockNanosleep_Pre_RQTp state
419)
420{
421  switch ( state ) {
422    case CReqClockNanosleep_Pre_RQTp_Valid: {
423      /*
424       * While the ``rqtp`` parameter references an object of type struct
425       * timespec.
426       */
427      ctx->rqtp = &ctx->rqtp_obj;
428      break;
429    }
430
431    case CReqClockNanosleep_Pre_RQTp_Null: {
432      /*
433       * While the ``rqtp`` parameter is equal to NULL.
434       */
435      ctx->rqtp = NULL;
436      break;
437    }
438
439    case CReqClockNanosleep_Pre_RQTp_NA:
440      break;
441  }
442}
443
444static void CReqClockNanosleep_Pre_RQTpNSec_Prepare(
445  CReqClockNanosleep_Context     *ctx,
446  CReqClockNanosleep_Pre_RQTpNSec state
447)
448{
449  switch ( state ) {
450    case CReqClockNanosleep_Pre_RQTpNSec_Valid: {
451      /*
452       * While the ``tv_nsec`` member of the object referenced by the ``rqtp``
453       * parameter is a valid nanoseconds value.
454       */
455      ctx->rqtp_obj.tv_nsec = 999999999;
456      break;
457    }
458
459    case CReqClockNanosleep_Pre_RQTpNSec_Invalid: {
460      /*
461       * While the ``tv_nsec`` member of the object referenced by the ``rqtp``
462       * parameter is an invalid nanoseconds value.
463       */
464      ctx->rqtp_obj.tv_nsec = -1;
465      break;
466    }
467
468    case CReqClockNanosleep_Pre_RQTpNSec_NA:
469      break;
470  }
471}
472
473static void CReqClockNanosleep_Pre_RQTpSec_Prepare(
474  CReqClockNanosleep_Context    *ctx,
475  CReqClockNanosleep_Pre_RQTpSec state
476)
477{
478  switch ( state ) {
479    case CReqClockNanosleep_Pre_RQTpSec_Negative: {
480      /*
481       * While the ``tv_sec`` member of the object referenced by the ``rqtp``
482       * parameter is negative.
483       */
484      ctx->rqtp_obj.tv_sec = -238479;
485      break;
486    }
487
488    case CReqClockNanosleep_Pre_RQTpSec_FarFuture: {
489      /*
490       * While the ``tv_sec`` member of the object referenced by the ``rqtp``
491       * parameter specifies a time point which is past the implementation
492       * limit.
493       */
494      ctx->rqtp_obj.tv_sec = INT64_MAX;
495      break;
496    }
497
498    case CReqClockNanosleep_Pre_RQTpSec_Future: {
499      /*
500       * While the ``tv_sec`` member of the object referenced by the ``rqtp``
501       * parameter specifies a time point which is after the current time of
502       * the clock specified by the ``clock_id`` parameter and is within the
503       * implementation limits.
504       */
505      ctx->rqtp_obj.tv_sec = 1621322302;
506      break;
507    }
508
509    case CReqClockNanosleep_Pre_RQTpSec_PastOrNow: {
510      /*
511       * While the ``tv_sec`` member of the object referenced by the ``rqtp``
512       * parameter is non-negative and specifies a time point which is before
513       * or at the current time of the clock specified by the ``clock_id``
514       * parameter.
515       */
516      ctx->rqtp_obj.tv_sec = 0;
517
518      if ( ctx->rqtp_obj.tv_nsec == 999999999 ) {
519        ctx->rqtp_obj.tv_nsec = 0;
520      }
521      break;
522    }
523
524    case CReqClockNanosleep_Pre_RQTpSec_NA:
525      break;
526  }
527}
528
529static void CReqClockNanosleep_Pre_RMTp_Prepare(
530  CReqClockNanosleep_Context *ctx,
531  CReqClockNanosleep_Pre_RMTp state
532)
533{
534  switch ( state ) {
535    case CReqClockNanosleep_Pre_RMTp_Valid: {
536      /*
537       * While the ``rmtp`` parameter references an object of type struct
538       * timespec.
539       */
540      ctx->rmtp = &ctx->rmtp_obj;
541      break;
542    }
543
544    case CReqClockNanosleep_Pre_RMTp_Null: {
545      /*
546       * While the ``rmtp`` parameter is equal to NULL.
547       */
548      ctx->rmtp = NULL;
549      break;
550    }
551
552    case CReqClockNanosleep_Pre_RMTp_NA:
553      break;
554  }
555}
556
557static void CReqClockNanosleep_Post_Status_Check(
558  CReqClockNanosleep_Context    *ctx,
559  CReqClockNanosleep_Post_Status state
560)
561{
562  switch ( state ) {
563    case CReqClockNanosleep_Post_Status_Zero: {
564      /*
565       * The return value of clock_nanosleep() shall be equal to zero.
566       */
567      T_eq_int( ctx->status, 0 );
568      break;
569    }
570
571    case CReqClockNanosleep_Post_Status_ENOTSUP: {
572      /*
573       * The return value of clock_nanosleep() shall be equal to ENOTSUP.
574       */
575      T_eq_int( ctx->status, ENOTSUP );
576      break;
577    }
578
579    case CReqClockNanosleep_Post_Status_EINVAL: {
580      /*
581       * The return value of clock_nanosleep() shall be equal to EINVAL.
582       */
583      T_eq_int( ctx->status, EINVAL );
584      break;
585    }
586
587    case CReqClockNanosleep_Post_Status_NA:
588      break;
589  }
590}
591
592static void CReqClockNanosleep_Post_Timer_Check(
593  CReqClockNanosleep_Context   *ctx,
594  CReqClockNanosleep_Post_Timer state
595)
596{
597  switch ( state ) {
598    case CReqClockNanosleep_Post_Timer_Inactive: {
599      /*
600       * The timer of the calling task shall be inactive.
601       */
602      T_eq_int( ctx->timer_info.state, TASK_TIMER_INACTIVE );
603      break;
604    }
605
606    case CReqClockNanosleep_Post_Timer_Monotonic: {
607      /*
608       * The timer of the calling task shall be active using the
609       * CLOCK_MONOTONIC.
610       */
611      T_eq_int( ctx->timer_info.state, TASK_TIMER_MONOTONIC );
612      break;
613    }
614
615    case CReqClockNanosleep_Post_Timer_Realtime: {
616      /*
617       * The timer of the calling task shall be active using the
618       * CLOCK_REALTIME.
619       */
620      T_eq_int( ctx->timer_info.state, TASK_TIMER_REALTIME );
621      break;
622    }
623
624    case CReqClockNanosleep_Post_Timer_NA:
625      break;
626  }
627}
628
629static void CReqClockNanosleep_Post_Expire_Check(
630  CReqClockNanosleep_Context    *ctx,
631  CReqClockNanosleep_Post_Expire state
632)
633{
634  struct timespec expire;
635
636  switch ( state ) {
637    case CReqClockNanosleep_Post_Expire_Last: {
638      /*
639       * The timer of the calling task shall expire at the last valid time
640       * point of the clock specified by the ``clock_id`` parameter.
641       */
642      T_eq_u64( ctx->timer_info.expire_ticks, 0xffffffffffffffff );
643      break;
644    }
645
646    case CReqClockNanosleep_Post_Expire_Absolute: {
647      /*
648       * The timer of the calling task shall expire at the time point specified
649       * by the ``rqtp`` parameter.
650       */
651      T_eq_i64( ctx->timer_info.expire_timespec.tv_sec, ctx->rqtp_obj.tv_sec );
652      T_eq_long(
653        ctx->timer_info.expire_timespec.tv_nsec,
654        ctx->rqtp_obj.tv_nsec
655      );
656      break;
657    }
658
659    case CReqClockNanosleep_Post_Expire_Relative: {
660      /*
661       * The timer of the calling task shall expire at the time point specified
662       * by the sum of the current time of the clock specified by
663       * CLOCK_MONOTONIC and the interval specified by the ``rqtp`` parameter.
664       */
665      expire = ctx->now_monotonic;
666      expire.tv_sec += ctx->rqtp_obj.tv_sec;
667      expire.tv_nsec += ctx->rqtp_obj.tv_nsec;
668
669      if ( expire.tv_nsec >= 1000000000 ) {
670        ++expire.tv_sec;
671        expire.tv_nsec -= 1000000000;
672      }
673
674      T_eq_i64( ctx->timer_info.expire_timespec.tv_sec, expire.tv_sec );
675      T_eq_long( ctx->timer_info.expire_timespec.tv_nsec, expire.tv_nsec );
676      break;
677    }
678
679    case CReqClockNanosleep_Post_Expire_NA:
680      break;
681  }
682}
683
684static void CReqClockNanosleep_Post_Scheduler_Check(
685  CReqClockNanosleep_Context       *ctx,
686  CReqClockNanosleep_Post_Scheduler state
687)
688{
689  switch ( state ) {
690    case CReqClockNanosleep_Post_Scheduler_Block: {
691      /*
692       * The calling task shall be blocked by the scheduler exactly once by the
693       * clock_nanosleep() call.
694       */
695      T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
696      T_eq_int(
697        ctx->scheduler_log.events[ 0 ].operation,
698        T_SCHEDULER_BLOCK
699      );
700      break;
701    }
702
703    case CReqClockNanosleep_Post_Scheduler_BlockUnblock: {
704      /*
705       * The calling task shall be blocked exactly once by the scheduler and
706       * then unblocked in the same thread dispatch critical section by the
707       * clock_nanosleep() call.
708       */
709      T_eq_sz( ctx->scheduler_log.header.recorded, 2 );
710      T_eq_int(
711        ctx->scheduler_log.events[ 0 ].operation,
712        T_SCHEDULER_BLOCK
713      );
714      T_eq_int(
715        ctx->scheduler_log.events[ 1 ].operation,
716        T_SCHEDULER_UNBLOCK
717      );
718      break;
719    }
720
721    case CReqClockNanosleep_Post_Scheduler_Nop: {
722      /*
723       * The calling task shall not be altered by the scheduler by the
724       * clock_nanosleep() call.
725       */
726      T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
727      break;
728    }
729
730    case CReqClockNanosleep_Post_Scheduler_NA:
731      break;
732  }
733}
734
735static void CReqClockNanosleep_Post_RMTp_Check(
736  CReqClockNanosleep_Context  *ctx,
737  CReqClockNanosleep_Post_RMTp state
738)
739{
740  switch ( state ) {
741    case CReqClockNanosleep_Post_RMTp_Zero: {
742      /*
743       * The object referenced by the ``rmtp`` parameter shall be cleared to
744       * zero after the return of the clock_nanosleep() call.
745       */
746      T_eq_i64( ctx->rmtp_obj.tv_sec, 0 );
747      T_eq_long( ctx->rmtp_obj.tv_nsec, 0 );
748      break;
749    }
750
751    case CReqClockNanosleep_Post_RMTp_Nop: {
752      /*
753       * Objects referenced by the ``rmtp`` parameter in past calls to
754       * clock_nanosleep() shall not be accessed by the clock_nanosleep() call.
755       */
756      T_eq_i64( ctx->rmtp_obj.tv_sec, -1 );
757      T_eq_long( ctx->rmtp_obj.tv_nsec, -1 );
758      break;
759    }
760
761    case CReqClockNanosleep_Post_RMTp_NA:
762      break;
763  }
764}
765
766static void CReqClockNanosleep_Setup( CReqClockNanosleep_Context *ctx )
767{
768  rtems_time_of_day now = { 1988, 1, 1, 0, 0, 0, 0 };
769  T_rsc_success( rtems_clock_set( &now ) );
770  SetSelfPriority( PRIO_NORMAL );
771  ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
772  StartTask( ctx->worker_id, Worker, ctx );
773}
774
775static void CReqClockNanosleep_Setup_Wrap( void *arg )
776{
777  CReqClockNanosleep_Context *ctx;
778
779  ctx = arg;
780  ctx->Map.in_action_loop = false;
781  CReqClockNanosleep_Setup( ctx );
782}
783
784static void CReqClockNanosleep_Teardown( CReqClockNanosleep_Context *ctx )
785{
786  DeleteTask( ctx->worker_id );
787  RestoreRunnerPriority();
788}
789
790static void CReqClockNanosleep_Teardown_Wrap( void *arg )
791{
792  CReqClockNanosleep_Context *ctx;
793
794  ctx = arg;
795  ctx->Map.in_action_loop = false;
796  CReqClockNanosleep_Teardown( ctx );
797}
798
799static void CReqClockNanosleep_Prepare( CReqClockNanosleep_Context *ctx )
800{
801  ctx->status = -1;
802  ctx->flags = 0;
803  ctx->rmtp_obj.tv_sec = -1;
804  ctx->rmtp_obj.tv_nsec = -1;
805}
806
807static void CReqClockNanosleep_Action( CReqClockNanosleep_Context *ctx )
808{
809  ResumeTask( ctx->worker_id );
810  (void) T_scheduler_record( NULL );
811  GetTaskTimerInfo( ctx->worker_id, &ctx->timer_info );
812  ClockTick();
813  FinalClockTick();
814}
815
816static const CReqClockNanosleep_Entry
817CReqClockNanosleep_Entries[] = {
818  { 0, 0, 0, 0, 1, 1, 0, CReqClockNanosleep_Post_Status_EINVAL,
819    CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
820    CReqClockNanosleep_Post_Scheduler_BlockUnblock,
821    CReqClockNanosleep_Post_RMTp_Nop },
822  { 0, 0, 0, 0, 1, 1, 0, CReqClockNanosleep_Post_Status_ENOTSUP,
823    CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
824    CReqClockNanosleep_Post_Scheduler_Nop, CReqClockNanosleep_Post_RMTp_Nop },
825  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_EINVAL,
826    CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
827    CReqClockNanosleep_Post_Scheduler_BlockUnblock,
828    CReqClockNanosleep_Post_RMTp_Nop },
829  { 0, 0, 0, 0, 1, 1, 0, CReqClockNanosleep_Post_Status_EINVAL,
830    CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
831    CReqClockNanosleep_Post_Scheduler_BlockUnblock,
832    CReqClockNanosleep_Post_RMTp_Zero },
833  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_ENOTSUP,
834    CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
835    CReqClockNanosleep_Post_Scheduler_Nop, CReqClockNanosleep_Post_RMTp_Nop },
836  { 1, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_NA,
837    CReqClockNanosleep_Post_Timer_NA, CReqClockNanosleep_Post_Expire_NA,
838    CReqClockNanosleep_Post_Scheduler_NA, CReqClockNanosleep_Post_RMTp_NA },
839  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
840    CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
841    CReqClockNanosleep_Post_Scheduler_BlockUnblock,
842    CReqClockNanosleep_Post_RMTp_Nop },
843  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_EINVAL,
844    CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
845    CReqClockNanosleep_Post_Scheduler_BlockUnblock,
846    CReqClockNanosleep_Post_RMTp_Zero },
847  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
848    CReqClockNanosleep_Post_Timer_Monotonic,
849    CReqClockNanosleep_Post_Expire_Last,
850    CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Nop },
851  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
852    CReqClockNanosleep_Post_Timer_Monotonic,
853    CReqClockNanosleep_Post_Expire_Absolute,
854    CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Nop },
855  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
856    CReqClockNanosleep_Post_Timer_Monotonic,
857    CReqClockNanosleep_Post_Expire_Last,
858    CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Zero },
859  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
860    CReqClockNanosleep_Post_Timer_Monotonic,
861    CReqClockNanosleep_Post_Expire_Relative,
862    CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Zero },
863  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
864    CReqClockNanosleep_Post_Timer_Monotonic,
865    CReqClockNanosleep_Post_Expire_Relative,
866    CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Nop },
867  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
868    CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
869    CReqClockNanosleep_Post_Scheduler_BlockUnblock,
870    CReqClockNanosleep_Post_RMTp_Zero },
871  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
872    CReqClockNanosleep_Post_Timer_Realtime,
873    CReqClockNanosleep_Post_Expire_Last,
874    CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Nop },
875  { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
876    CReqClockNanosleep_Post_Timer_Realtime,
877    CReqClockNanosleep_Post_Expire_Absolute,
878    CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Nop }
879};
880
881static const uint8_t
882CReqClockNanosleep_Map[] = {
883  6, 6, 8, 8, 9, 9, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
884  0, 0, 0, 0, 0, 0, 7, 2, 10, 8, 11, 12, 13, 6, 7, 2, 7, 2, 7, 2, 7, 2, 3, 0,
885  3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 6, 6, 14, 14, 15, 15, 6, 6, 2, 2,
886  2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 10,
887  8, 11, 12, 13, 6, 7, 2, 7, 2, 7, 2, 7, 2, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
888  3, 0, 3, 0, 4, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 4, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1,
889  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 4, 5, 5, 5, 5,
890  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
891};
892
893static size_t CReqClockNanosleep_Scope( void *arg, char *buf, size_t n )
894{
895  CReqClockNanosleep_Context *ctx;
896
897  ctx = arg;
898
899  if ( ctx->Map.in_action_loop ) {
900    return T_get_scope( CReqClockNanosleep_PreDesc, buf, n, ctx->Map.pcs );
901  }
902
903  return 0;
904}
905
906static T_fixture CReqClockNanosleep_Fixture = {
907  .setup = CReqClockNanosleep_Setup_Wrap,
908  .stop = NULL,
909  .teardown = CReqClockNanosleep_Teardown_Wrap,
910  .scope = CReqClockNanosleep_Scope,
911  .initial_context = &CReqClockNanosleep_Instance
912};
913
914static inline CReqClockNanosleep_Entry CReqClockNanosleep_PopEntry(
915  CReqClockNanosleep_Context *ctx
916)
917{
918  size_t index;
919
920  index = ctx->Map.index;
921  ctx->Map.index = index + 1;
922  return CReqClockNanosleep_Entries[
923    CReqClockNanosleep_Map[ index ]
924  ];
925}
926
927static void CReqClockNanosleep_SetPreConditionStates(
928  CReqClockNanosleep_Context *ctx
929)
930{
931  ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
932  ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
933  ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
934
935  if ( ctx->Map.entry.Pre_RQTpNSec_NA ) {
936    ctx->Map.pcs[ 3 ] = CReqClockNanosleep_Pre_RQTpNSec_NA;
937  } else {
938    ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
939  }
940
941  if ( ctx->Map.entry.Pre_RQTpSec_NA ) {
942    ctx->Map.pcs[ 4 ] = CReqClockNanosleep_Pre_RQTpSec_NA;
943  } else {
944    ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
945  }
946
947  ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
948}
949
950static void CReqClockNanosleep_TestVariant( CReqClockNanosleep_Context *ctx )
951{
952  CReqClockNanosleep_Pre_ClockId_Prepare( ctx, ctx->Map.pcs[ 0 ] );
953  CReqClockNanosleep_Pre_Abstime_Prepare( ctx, ctx->Map.pcs[ 1 ] );
954  CReqClockNanosleep_Pre_RQTp_Prepare( ctx, ctx->Map.pcs[ 2 ] );
955  CReqClockNanosleep_Pre_RQTpNSec_Prepare( ctx, ctx->Map.pcs[ 3 ] );
956  CReqClockNanosleep_Pre_RQTpSec_Prepare( ctx, ctx->Map.pcs[ 4 ] );
957  CReqClockNanosleep_Pre_RMTp_Prepare( ctx, ctx->Map.pcs[ 5 ] );
958  CReqClockNanosleep_Action( ctx );
959  CReqClockNanosleep_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
960  CReqClockNanosleep_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
961  CReqClockNanosleep_Post_Expire_Check( ctx, ctx->Map.entry.Post_Expire );
962  CReqClockNanosleep_Post_Scheduler_Check(
963    ctx,
964    ctx->Map.entry.Post_Scheduler
965  );
966  CReqClockNanosleep_Post_RMTp_Check( ctx, ctx->Map.entry.Post_RMTp );
967}
968
969/**
970 * @fn void T_case_body_CReqClockNanosleep( void )
971 */
972T_TEST_CASE_FIXTURE( CReqClockNanosleep, &CReqClockNanosleep_Fixture )
973{
974  CReqClockNanosleep_Context *ctx;
975
976  ctx = T_fixture_context();
977  ctx->Map.in_action_loop = true;
978  ctx->Map.index = 0;
979
980  for (
981    ctx->Map.pci[ 0 ] = CReqClockNanosleep_Pre_ClockId_Monotonic;
982    ctx->Map.pci[ 0 ] < CReqClockNanosleep_Pre_ClockId_NA;
983    ++ctx->Map.pci[ 0 ]
984  ) {
985    for (
986      ctx->Map.pci[ 1 ] = CReqClockNanosleep_Pre_Abstime_Yes;
987      ctx->Map.pci[ 1 ] < CReqClockNanosleep_Pre_Abstime_NA;
988      ++ctx->Map.pci[ 1 ]
989    ) {
990      for (
991        ctx->Map.pci[ 2 ] = CReqClockNanosleep_Pre_RQTp_Valid;
992        ctx->Map.pci[ 2 ] < CReqClockNanosleep_Pre_RQTp_NA;
993        ++ctx->Map.pci[ 2 ]
994      ) {
995        for (
996          ctx->Map.pci[ 3 ] = CReqClockNanosleep_Pre_RQTpNSec_Valid;
997          ctx->Map.pci[ 3 ] < CReqClockNanosleep_Pre_RQTpNSec_NA;
998          ++ctx->Map.pci[ 3 ]
999        ) {
1000          for (
1001            ctx->Map.pci[ 4 ] = CReqClockNanosleep_Pre_RQTpSec_Negative;
1002            ctx->Map.pci[ 4 ] < CReqClockNanosleep_Pre_RQTpSec_NA;
1003            ++ctx->Map.pci[ 4 ]
1004          ) {
1005            for (
1006              ctx->Map.pci[ 5 ] = CReqClockNanosleep_Pre_RMTp_Valid;
1007              ctx->Map.pci[ 5 ] < CReqClockNanosleep_Pre_RMTp_NA;
1008              ++ctx->Map.pci[ 5 ]
1009            ) {
1010              ctx->Map.entry = CReqClockNanosleep_PopEntry( ctx );
1011
1012              if ( ctx->Map.entry.Skip ) {
1013                continue;
1014              }
1015
1016              CReqClockNanosleep_SetPreConditionStates( ctx );
1017              CReqClockNanosleep_Prepare( ctx );
1018              CReqClockNanosleep_TestVariant( ctx );
1019            }
1020          }
1021        }
1022      }
1023    }
1024  }
1025}
1026
1027/** @} */
Note: See TracBrowser for help on using the repository browser.