source: rtems/testsuites/validation/tc-barrier-release.c @ 1ce127e

Last change on this file since 1ce127e was 1ce127e, checked in by Sebastian Huber <sebastian.huber@…>, on 03/05/21 at 20:18:55

validation: Use common wording

  • Property mode set to 100644
File size: 15.7 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSTestCaseRtemsBarrierReqRelease
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.h>
56#include <string.h>
57
58#include <rtems/test.h>
59
60/**
61 * @defgroup RTEMSTestCaseRtemsBarrierReqRelease \
62 *   spec:/rtems/barrier/req/release
63 *
64 * @ingroup RTEMSTestSuiteTestsuitesValidation0
65 *
66 * @{
67 */
68
69typedef enum {
70  RtemsBarrierReqRelease_Pre_Barrier_NoObj,
71  RtemsBarrierReqRelease_Pre_Barrier_Manual,
72  RtemsBarrierReqRelease_Pre_Barrier_Auto,
73  RtemsBarrierReqRelease_Pre_Barrier_NA
74} RtemsBarrierReqRelease_Pre_Barrier;
75
76typedef enum {
77  RtemsBarrierReqRelease_Pre_Released_Valid,
78  RtemsBarrierReqRelease_Pre_Released_Null,
79  RtemsBarrierReqRelease_Pre_Released_NA
80} RtemsBarrierReqRelease_Pre_Released;
81
82typedef enum {
83  RtemsBarrierReqRelease_Pre_Waiting_Zero,
84  RtemsBarrierReqRelease_Pre_Waiting_Positive,
85  RtemsBarrierReqRelease_Pre_Waiting_NA
86} RtemsBarrierReqRelease_Pre_Waiting;
87
88typedef enum {
89  RtemsBarrierReqRelease_Post_Status_Ok,
90  RtemsBarrierReqRelease_Post_Status_InvId,
91  RtemsBarrierReqRelease_Post_Status_InvAddr,
92  RtemsBarrierReqRelease_Post_Status_NA
93} RtemsBarrierReqRelease_Post_Status;
94
95typedef enum {
96  RtemsBarrierReqRelease_Post_Released_Valid,
97  RtemsBarrierReqRelease_Post_Released_Unchanged,
98  RtemsBarrierReqRelease_Post_Released_NA
99} RtemsBarrierReqRelease_Post_Released;
100
101/**
102 * @brief Test context for spec:/rtems/barrier/req/release test case.
103 */
104typedef struct {
105  rtems_id worker_id;
106
107  rtems_id manual_release_id;
108
109  rtems_id auto_release_id;
110
111  uint32_t waiting_tasks;
112
113  uint32_t released_value;
114
115  rtems_id id;
116
117  uint32_t *released;
118
119  rtems_status_code status;
120
121  /**
122   * @brief This member defines the pre-condition states for the next action.
123   */
124  size_t pcs[ 3 ];
125
126  /**
127   * @brief This member indicates if the test action loop is currently
128   *   executed.
129   */
130  bool in_action_loop;
131} RtemsBarrierReqRelease_Context;
132
133static RtemsBarrierReqRelease_Context
134  RtemsBarrierReqRelease_Instance;
135
136static const char * const RtemsBarrierReqRelease_PreDesc_Barrier[] = {
137  "NoObj",
138  "Manual",
139  "Auto",
140  "NA"
141};
142
143static const char * const RtemsBarrierReqRelease_PreDesc_Released[] = {
144  "Valid",
145  "Null",
146  "NA"
147};
148
149static const char * const RtemsBarrierReqRelease_PreDesc_Waiting[] = {
150  "Zero",
151  "Positive",
152  "NA"
153};
154
155static const char * const * const RtemsBarrierReqRelease_PreDesc[] = {
156  RtemsBarrierReqRelease_PreDesc_Barrier,
157  RtemsBarrierReqRelease_PreDesc_Released,
158  RtemsBarrierReqRelease_PreDesc_Waiting,
159  NULL
160};
161
162#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
163
164#define EVENT_WAIT RTEMS_EVENT_0
165
166#define RELEASED_INVALID_VALUE 0xffffffff
167
168typedef RtemsBarrierReqRelease_Context Context;
169
170typedef enum {
171  PRIO_HIGH = 1,
172  PRIO_NORMAL
173} Priorities;
174
175static void SendEvents( rtems_id id, rtems_event_set events )
176{
177  rtems_status_code sc;
178
179  sc = rtems_event_send( id, events );
180  T_rsc_success( sc );
181}
182
183static void Worker( rtems_task_argument arg )
184{
185  Context *ctx;
186
187  ctx = (Context *) arg;
188
189  while ( true ) {
190    rtems_status_code sc;
191    rtems_event_set   events;
192
193    events = 0;
194    sc = rtems_event_receive(
195      RTEMS_ALL_EVENTS,
196      RTEMS_EVENT_ANY | RTEMS_WAIT,
197      RTEMS_NO_TIMEOUT,
198      &events
199    );
200    T_rsc_success( sc );
201
202    if ( ( events & EVENT_WAIT ) != 0 ) {
203      sc = rtems_barrier_wait( ctx->id, RTEMS_NO_TIMEOUT );
204      T_rsc_success( sc );
205    }
206  }
207}
208
209static void RtemsBarrierReqRelease_Pre_Barrier_Prepare(
210  RtemsBarrierReqRelease_Context    *ctx,
211  RtemsBarrierReqRelease_Pre_Barrier state
212)
213{
214  switch ( state ) {
215    case RtemsBarrierReqRelease_Pre_Barrier_NoObj: {
216      /*
217       * The ``id`` parameter shall be invalid.
218       */
219      ctx->id = 0xffffffff;
220      break;
221    }
222
223    case RtemsBarrierReqRelease_Pre_Barrier_Manual: {
224      /*
225       * The ``id`` parameter shall be associated with a manual release
226       * barrier.
227       */
228      ctx->id = ctx->manual_release_id;
229      break;
230    }
231
232    case RtemsBarrierReqRelease_Pre_Barrier_Auto: {
233      /*
234       * The ``id`` parameter shall be associated with an automatic release
235       * barrier.
236       */
237      ctx->id = ctx->auto_release_id;
238      break;
239    }
240
241    case RtemsBarrierReqRelease_Pre_Barrier_NA:
242      break;
243  }
244}
245
246static void RtemsBarrierReqRelease_Pre_Released_Prepare(
247  RtemsBarrierReqRelease_Context     *ctx,
248  RtemsBarrierReqRelease_Pre_Released state
249)
250{
251  ctx->released_value = RELEASED_INVALID_VALUE;
252
253  switch ( state ) {
254    case RtemsBarrierReqRelease_Pre_Released_Valid: {
255      /*
256       * The ``released`` parameter shall reference an object of type uint32_t.
257       */
258      ctx->released = &ctx->released_value;
259      break;
260    }
261
262    case RtemsBarrierReqRelease_Pre_Released_Null: {
263      /*
264       * The ``released`` parameter shall be NULL.
265       */
266      ctx->released = NULL;
267      break;
268    }
269
270    case RtemsBarrierReqRelease_Pre_Released_NA:
271      break;
272  }
273}
274
275static void RtemsBarrierReqRelease_Pre_Waiting_Prepare(
276  RtemsBarrierReqRelease_Context    *ctx,
277  RtemsBarrierReqRelease_Pre_Waiting state
278)
279{
280  switch ( state ) {
281    case RtemsBarrierReqRelease_Pre_Waiting_Zero: {
282      /*
283       * The number of tasks waiting at the barrier shall be zero.
284       */
285      ctx->waiting_tasks = 0;
286      break;
287    }
288
289    case RtemsBarrierReqRelease_Pre_Waiting_Positive: {
290      /*
291       * The number of tasks waiting at the barrier shall be positive.
292       */
293      ctx->waiting_tasks = 1;
294      SendEvents( ctx->worker_id, EVENT_WAIT );
295      break;
296    }
297
298    case RtemsBarrierReqRelease_Pre_Waiting_NA:
299      break;
300  }
301}
302
303static void RtemsBarrierReqRelease_Post_Status_Check(
304  RtemsBarrierReqRelease_Context    *ctx,
305  RtemsBarrierReqRelease_Post_Status state
306)
307{
308  switch ( state ) {
309    case RtemsBarrierReqRelease_Post_Status_Ok: {
310      /*
311       * The return status of rtems_barrier_release() shall be
312       * RTEMS_SUCCESSFUL.
313       */
314      T_rsc_success( ctx->status );
315      break;
316    }
317
318    case RtemsBarrierReqRelease_Post_Status_InvId: {
319      /*
320       * The return status of rtems_barrier_release() shall be
321       * RTEMS_INVALID_ID.
322       */
323      T_rsc( ctx->status, RTEMS_INVALID_ID );
324      break;
325    }
326
327    case RtemsBarrierReqRelease_Post_Status_InvAddr: {
328      /*
329       * The return status of rtems_barrier_release() shall be
330       * RTEMS_INVALID_ADDRESS.
331       */
332      T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
333      break;
334    }
335
336    case RtemsBarrierReqRelease_Post_Status_NA:
337      break;
338  }
339}
340
341static void RtemsBarrierReqRelease_Post_Released_Check(
342  RtemsBarrierReqRelease_Context      *ctx,
343  RtemsBarrierReqRelease_Post_Released state
344)
345{
346  switch ( state ) {
347    case RtemsBarrierReqRelease_Post_Released_Valid: {
348      /*
349       * The value of the variable for the number of released tasks shall equal
350       * the number of tasks released by the rtems_barrier_release() call.
351       */
352      T_eq_u32( ctx->released_value, ctx->waiting_tasks );
353      break;
354    }
355
356    case RtemsBarrierReqRelease_Post_Released_Unchanged: {
357      /*
358       * The value of variable for the number of released tasks shall be
359       * unchanged by the rtems_barrier_release() call.
360       */
361      T_eq_u32( ctx->released_value, RELEASED_INVALID_VALUE );
362      break;
363    }
364
365    case RtemsBarrierReqRelease_Post_Released_NA:
366      break;
367  }
368}
369
370static void RtemsBarrierReqRelease_Setup( RtemsBarrierReqRelease_Context *ctx )
371{
372  rtems_status_code   sc;
373  rtems_task_priority prio;
374
375  memset( ctx, 0, sizeof( *ctx ) );
376
377  prio = 0;
378  sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio );
379  T_rsc_success( sc );
380  T_eq_u32( prio, PRIO_HIGH );
381
382  sc = rtems_task_create(
383    rtems_build_name( 'W', 'O', 'R', 'K' ),
384    PRIO_HIGH,
385    RTEMS_MINIMUM_STACK_SIZE,
386    RTEMS_DEFAULT_MODES,
387    RTEMS_DEFAULT_ATTRIBUTES,
388    &ctx->worker_id
389  );
390  T_assert_rsc_success( sc );
391
392  sc = rtems_task_start(
393    ctx->worker_id,
394    Worker,
395    (rtems_task_argument) ctx
396  );
397  T_assert_rsc_success( sc );
398
399  sc = rtems_barrier_create(
400    NAME,
401    RTEMS_BARRIER_MANUAL_RELEASE,
402    0,
403    &ctx->manual_release_id
404  );
405  T_assert_rsc_success( sc );
406
407  sc = rtems_barrier_create(
408    NAME,
409    RTEMS_BARRIER_AUTOMATIC_RELEASE,
410    2,
411    &ctx->auto_release_id
412  );
413  T_assert_rsc_success( sc );
414}
415
416static void RtemsBarrierReqRelease_Setup_Wrap( void *arg )
417{
418  RtemsBarrierReqRelease_Context *ctx;
419
420  ctx = arg;
421  ctx->in_action_loop = false;
422  RtemsBarrierReqRelease_Setup( ctx );
423}
424
425static void RtemsBarrierReqRelease_Teardown(
426  RtemsBarrierReqRelease_Context *ctx
427)
428{
429  rtems_status_code   sc;
430  rtems_task_priority prio;
431
432  prio = 0;
433  sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio );
434  T_rsc_success( sc );
435  T_eq_u32( prio, PRIO_NORMAL );
436
437  if ( ctx->worker_id != 0 ) {
438    sc = rtems_task_delete( ctx->worker_id );
439    T_rsc_success( sc );
440  }
441
442  if ( ctx->manual_release_id != 0 ) {
443    sc = rtems_barrier_delete( ctx->manual_release_id );
444    T_rsc_success( sc );
445  }
446
447  if ( ctx->auto_release_id != 0 ) {
448    sc = rtems_barrier_delete( ctx->auto_release_id );
449    T_rsc_success( sc );
450  }
451}
452
453static void RtemsBarrierReqRelease_Teardown_Wrap( void *arg )
454{
455  RtemsBarrierReqRelease_Context *ctx;
456
457  ctx = arg;
458  ctx->in_action_loop = false;
459  RtemsBarrierReqRelease_Teardown( ctx );
460}
461
462static size_t RtemsBarrierReqRelease_Scope( void *arg, char *buf, size_t n )
463{
464  RtemsBarrierReqRelease_Context *ctx;
465
466  ctx = arg;
467
468  if ( ctx->in_action_loop ) {
469    return T_get_scope( RtemsBarrierReqRelease_PreDesc, buf, n, ctx->pcs );
470  }
471
472  return 0;
473}
474
475static T_fixture RtemsBarrierReqRelease_Fixture = {
476  .setup = RtemsBarrierReqRelease_Setup_Wrap,
477  .stop = NULL,
478  .teardown = RtemsBarrierReqRelease_Teardown_Wrap,
479  .scope = RtemsBarrierReqRelease_Scope,
480  .initial_context = &RtemsBarrierReqRelease_Instance
481};
482
483static const uint8_t RtemsBarrierReqRelease_TransitionMap[][ 2 ] = {
484  {
485    RtemsBarrierReqRelease_Post_Status_InvId,
486    RtemsBarrierReqRelease_Post_Released_Unchanged
487  }, {
488    RtemsBarrierReqRelease_Post_Status_InvId,
489    RtemsBarrierReqRelease_Post_Released_Unchanged
490  }, {
491    RtemsBarrierReqRelease_Post_Status_InvAddr,
492    RtemsBarrierReqRelease_Post_Released_Unchanged
493  }, {
494    RtemsBarrierReqRelease_Post_Status_InvAddr,
495    RtemsBarrierReqRelease_Post_Released_Unchanged
496  }, {
497    RtemsBarrierReqRelease_Post_Status_Ok,
498    RtemsBarrierReqRelease_Post_Released_Valid
499  }, {
500    RtemsBarrierReqRelease_Post_Status_Ok,
501    RtemsBarrierReqRelease_Post_Released_Valid
502  }, {
503    RtemsBarrierReqRelease_Post_Status_InvAddr,
504    RtemsBarrierReqRelease_Post_Released_Unchanged
505  }, {
506    RtemsBarrierReqRelease_Post_Status_InvAddr,
507    RtemsBarrierReqRelease_Post_Released_Unchanged
508  }, {
509    RtemsBarrierReqRelease_Post_Status_Ok,
510    RtemsBarrierReqRelease_Post_Released_Valid
511  }, {
512    RtemsBarrierReqRelease_Post_Status_Ok,
513    RtemsBarrierReqRelease_Post_Released_Valid
514  }, {
515    RtemsBarrierReqRelease_Post_Status_InvAddr,
516    RtemsBarrierReqRelease_Post_Released_Unchanged
517  }, {
518    RtemsBarrierReqRelease_Post_Status_InvAddr,
519    RtemsBarrierReqRelease_Post_Released_Unchanged
520  }
521};
522
523static const struct {
524  uint8_t Skip : 1;
525  uint8_t Pre_Barrier_NA : 1;
526  uint8_t Pre_Released_NA : 1;
527  uint8_t Pre_Waiting_NA : 1;
528} RtemsBarrierReqRelease_TransitionInfo[] = {
529  {
530    0, 0, 0, 1
531  }, {
532    0, 0, 0, 1
533  }, {
534    0, 0, 0, 1
535  }, {
536    0, 0, 0, 1
537  }, {
538    0, 0, 0, 0
539  }, {
540    0, 0, 0, 0
541  }, {
542    0, 0, 0, 1
543  }, {
544    0, 0, 0, 1
545  }, {
546    0, 0, 0, 0
547  }, {
548    0, 0, 0, 0
549  }, {
550    0, 0, 0, 1
551  }, {
552    0, 0, 0, 1
553  }
554};
555
556static void RtemsBarrierReqRelease_Action(
557  RtemsBarrierReqRelease_Context *ctx
558)
559{
560  ctx->status = rtems_barrier_release( ctx->id, ctx->released );
561}
562
563/**
564 * @fn void T_case_body_RtemsBarrierReqRelease( void )
565 */
566T_TEST_CASE_FIXTURE( RtemsBarrierReqRelease, &RtemsBarrierReqRelease_Fixture )
567{
568  RtemsBarrierReqRelease_Context *ctx;
569  size_t index;
570
571  ctx = T_fixture_context();
572  ctx->in_action_loop = true;
573  index = 0;
574
575  for (
576    ctx->pcs[ 0 ] = RtemsBarrierReqRelease_Pre_Barrier_NoObj;
577    ctx->pcs[ 0 ] < RtemsBarrierReqRelease_Pre_Barrier_NA;
578    ++ctx->pcs[ 0 ]
579  ) {
580    if ( RtemsBarrierReqRelease_TransitionInfo[ index ].Pre_Barrier_NA ) {
581      ctx->pcs[ 0 ] = RtemsBarrierReqRelease_Pre_Barrier_NA;
582      index += ( RtemsBarrierReqRelease_Pre_Barrier_NA - 1 )
583        * RtemsBarrierReqRelease_Pre_Released_NA
584        * RtemsBarrierReqRelease_Pre_Waiting_NA;
585    }
586
587    for (
588      ctx->pcs[ 1 ] = RtemsBarrierReqRelease_Pre_Released_Valid;
589      ctx->pcs[ 1 ] < RtemsBarrierReqRelease_Pre_Released_NA;
590      ++ctx->pcs[ 1 ]
591    ) {
592      if ( RtemsBarrierReqRelease_TransitionInfo[ index ].Pre_Released_NA ) {
593        ctx->pcs[ 1 ] = RtemsBarrierReqRelease_Pre_Released_NA;
594        index += ( RtemsBarrierReqRelease_Pre_Released_NA - 1 )
595          * RtemsBarrierReqRelease_Pre_Waiting_NA;
596      }
597
598      for (
599        ctx->pcs[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_Zero;
600        ctx->pcs[ 2 ] < RtemsBarrierReqRelease_Pre_Waiting_NA;
601        ++ctx->pcs[ 2 ]
602      ) {
603        if ( RtemsBarrierReqRelease_TransitionInfo[ index ].Pre_Waiting_NA ) {
604          ctx->pcs[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_NA;
605          index += ( RtemsBarrierReqRelease_Pre_Waiting_NA - 1 );
606        }
607
608        if ( RtemsBarrierReqRelease_TransitionInfo[ index ].Skip ) {
609          ++index;
610          continue;
611        }
612
613        RtemsBarrierReqRelease_Pre_Barrier_Prepare( ctx, ctx->pcs[ 0 ] );
614        RtemsBarrierReqRelease_Pre_Released_Prepare( ctx, ctx->pcs[ 1 ] );
615        RtemsBarrierReqRelease_Pre_Waiting_Prepare( ctx, ctx->pcs[ 2 ] );
616        RtemsBarrierReqRelease_Action( ctx );
617        RtemsBarrierReqRelease_Post_Status_Check(
618          ctx,
619          RtemsBarrierReqRelease_TransitionMap[ index ][ 0 ]
620        );
621        RtemsBarrierReqRelease_Post_Released_Check(
622          ctx,
623          RtemsBarrierReqRelease_TransitionMap[ index ][ 1 ]
624        );
625        ++index;
626      }
627    }
628  }
629}
630
631/** @} */
Note: See TracBrowser for help on using the repository browser.