source: rtems/testsuites/validation/tc-barrier-release.c @ 34f279aa

Last change on this file since 34f279aa was 34f279aa, checked in by Sebastian Huber <sebastian.huber@…>, on 02/24/21 at 16:59:32

validation: Add comments to barrier tests

Unify code sections across tests.

  • 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
226       * manual release 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
235       * automatic release 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 integer variable.
257       */
258      ctx->released = &ctx->released_value;
259      break;
260    }
261
262    case RtemsBarrierReqRelease_Pre_Released_Null: {
263      /*
264       * The ``released`` parameter shall be
265       * NULL.
266       */
267      ctx->released = NULL;
268      break;
269    }
270
271    case RtemsBarrierReqRelease_Pre_Released_NA:
272      break;
273  }
274}
275
276static void RtemsBarrierReqRelease_Pre_Waiting_Prepare(
277  RtemsBarrierReqRelease_Context    *ctx,
278  RtemsBarrierReqRelease_Pre_Waiting state
279)
280{
281  switch ( state ) {
282    case RtemsBarrierReqRelease_Pre_Waiting_Zero: {
283      /*
284       * The number of tasks waiting at the barrier shall be zero.
285       */
286      ctx->waiting_tasks = 0;
287      break;
288    }
289
290    case RtemsBarrierReqRelease_Pre_Waiting_Positive: {
291      /*
292       * The number of tasks waiting at the barrier shall be positive.
293       */
294      ctx->waiting_tasks = 1;
295      SendEvents( ctx->worker_id, EVENT_WAIT );
296      break;
297    }
298
299    case RtemsBarrierReqRelease_Pre_Waiting_NA:
300      break;
301  }
302}
303
304static void RtemsBarrierReqRelease_Post_Status_Check(
305  RtemsBarrierReqRelease_Context    *ctx,
306  RtemsBarrierReqRelease_Post_Status state
307)
308{
309  switch ( state ) {
310    case RtemsBarrierReqRelease_Post_Status_Ok: {
311      /*
312       * The return status of rtems_barrier_release() shall be
313       * RTEMS_SUCCESSFUL.
314       */
315      T_rsc_success( ctx->status );
316      break;
317    }
318
319    case RtemsBarrierReqRelease_Post_Status_InvId: {
320      /*
321       * The return status of rtems_barrier_release() shall be
322       * RTEMS_INVALID_ID.
323       */
324      T_rsc( ctx->status, RTEMS_INVALID_ID );
325      break;
326    }
327
328    case RtemsBarrierReqRelease_Post_Status_InvAddr: {
329      /*
330       * The return status of rtems_barrier_release() shall be
331       * RTEMS_INVALID_ADDRESS.
332       */
333      T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
334      break;
335    }
336
337    case RtemsBarrierReqRelease_Post_Status_NA:
338      break;
339  }
340}
341
342static void RtemsBarrierReqRelease_Post_Released_Check(
343  RtemsBarrierReqRelease_Context      *ctx,
344  RtemsBarrierReqRelease_Post_Released state
345)
346{
347  switch ( state ) {
348    case RtemsBarrierReqRelease_Post_Released_Valid: {
349      /*
350       * The value of the variable for the number of released tasks shall equal
351       * the number of tasks released by the rtems_barrier_release() call.
352       */
353      T_eq_u32( ctx->released_value, ctx->waiting_tasks );
354      break;
355    }
356
357    case RtemsBarrierReqRelease_Post_Released_Unchanged: {
358      /*
359       * The value of variable for the number of released tasks shall be unchanged
360       * by the rtems_barrier_release() call.
361       */
362      T_eq_u32( ctx->released_value, RELEASED_INVALID_VALUE );
363      break;
364    }
365
366    case RtemsBarrierReqRelease_Post_Released_NA:
367      break;
368  }
369}
370
371static void RtemsBarrierReqRelease_Setup( RtemsBarrierReqRelease_Context *ctx )
372{
373  rtems_status_code   sc;
374  rtems_task_priority prio;
375
376  memset( ctx, 0, sizeof( *ctx ) );
377
378  prio = 0;
379  sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio );
380  T_rsc_success( sc );
381  T_eq_u32( prio, PRIO_HIGH );
382
383  sc = rtems_task_create(
384    rtems_build_name( 'W', 'O', 'R', 'K' ),
385    PRIO_HIGH,
386    RTEMS_MINIMUM_STACK_SIZE,
387    RTEMS_DEFAULT_MODES,
388    RTEMS_DEFAULT_ATTRIBUTES,
389    &ctx->worker_id
390  );
391  T_assert_rsc_success( sc );
392
393  sc = rtems_task_start(
394    ctx->worker_id,
395    Worker,
396    (rtems_task_argument) ctx
397  );
398  T_assert_rsc_success( sc );
399
400  sc = rtems_barrier_create(
401    NAME,
402    RTEMS_BARRIER_MANUAL_RELEASE,
403    0,
404    &ctx->manual_release_id
405  );
406  T_assert_rsc_success( sc );
407
408  sc = rtems_barrier_create(
409    NAME,
410    RTEMS_BARRIER_AUTOMATIC_RELEASE,
411    2,
412    &ctx->auto_release_id
413  );
414  T_assert_rsc_success( sc );
415}
416
417static void RtemsBarrierReqRelease_Setup_Wrap( void *arg )
418{
419  RtemsBarrierReqRelease_Context *ctx;
420
421  ctx = arg;
422  ctx->in_action_loop = false;
423  RtemsBarrierReqRelease_Setup( ctx );
424}
425
426static void RtemsBarrierReqRelease_Teardown(
427  RtemsBarrierReqRelease_Context *ctx
428)
429{
430  rtems_status_code   sc;
431  rtems_task_priority prio;
432
433  prio = 0;
434  sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio );
435  T_rsc_success( sc );
436  T_eq_u32( prio, PRIO_NORMAL );
437
438  if ( ctx->worker_id != 0 ) {
439    sc = rtems_task_delete( ctx->worker_id );
440    T_rsc_success( sc );
441  }
442
443  if ( ctx->manual_release_id != 0 ) {
444    sc = rtems_barrier_delete( ctx->manual_release_id );
445    T_rsc_success( sc );
446  }
447
448  if ( ctx->auto_release_id != 0 ) {
449    sc = rtems_barrier_delete( ctx->auto_release_id );
450    T_rsc_success( sc );
451  }
452}
453
454static void RtemsBarrierReqRelease_Teardown_Wrap( void *arg )
455{
456  RtemsBarrierReqRelease_Context *ctx;
457
458  ctx = arg;
459  ctx->in_action_loop = false;
460  RtemsBarrierReqRelease_Teardown( ctx );
461}
462
463static size_t RtemsBarrierReqRelease_Scope( void *arg, char *buf, size_t n )
464{
465  RtemsBarrierReqRelease_Context *ctx;
466
467  ctx = arg;
468
469  if ( ctx->in_action_loop ) {
470    return T_get_scope( RtemsBarrierReqRelease_PreDesc, buf, n, ctx->pcs );
471  }
472
473  return 0;
474}
475
476static T_fixture RtemsBarrierReqRelease_Fixture = {
477  .setup = RtemsBarrierReqRelease_Setup_Wrap,
478  .stop = NULL,
479  .teardown = RtemsBarrierReqRelease_Teardown_Wrap,
480  .scope = RtemsBarrierReqRelease_Scope,
481  .initial_context = &RtemsBarrierReqRelease_Instance
482};
483
484static const uint8_t RtemsBarrierReqRelease_TransitionMap[][ 2 ] = {
485  {
486    RtemsBarrierReqRelease_Post_Status_InvId,
487    RtemsBarrierReqRelease_Post_Released_Unchanged
488  }, {
489    RtemsBarrierReqRelease_Post_Status_InvId,
490    RtemsBarrierReqRelease_Post_Released_Unchanged
491  }, {
492    RtemsBarrierReqRelease_Post_Status_InvAddr,
493    RtemsBarrierReqRelease_Post_Released_Unchanged
494  }, {
495    RtemsBarrierReqRelease_Post_Status_InvAddr,
496    RtemsBarrierReqRelease_Post_Released_Unchanged
497  }, {
498    RtemsBarrierReqRelease_Post_Status_Ok,
499    RtemsBarrierReqRelease_Post_Released_Valid
500  }, {
501    RtemsBarrierReqRelease_Post_Status_Ok,
502    RtemsBarrierReqRelease_Post_Released_Valid
503  }, {
504    RtemsBarrierReqRelease_Post_Status_InvAddr,
505    RtemsBarrierReqRelease_Post_Released_Unchanged
506  }, {
507    RtemsBarrierReqRelease_Post_Status_InvAddr,
508    RtemsBarrierReqRelease_Post_Released_Unchanged
509  }, {
510    RtemsBarrierReqRelease_Post_Status_Ok,
511    RtemsBarrierReqRelease_Post_Released_Valid
512  }, {
513    RtemsBarrierReqRelease_Post_Status_Ok,
514    RtemsBarrierReqRelease_Post_Released_Valid
515  }, {
516    RtemsBarrierReqRelease_Post_Status_InvAddr,
517    RtemsBarrierReqRelease_Post_Released_Unchanged
518  }, {
519    RtemsBarrierReqRelease_Post_Status_InvAddr,
520    RtemsBarrierReqRelease_Post_Released_Unchanged
521  }
522};
523
524static const struct {
525  uint8_t Skip : 1;
526  uint8_t Pre_Barrier_NA : 1;
527  uint8_t Pre_Released_NA : 1;
528  uint8_t Pre_Waiting_NA : 1;
529} RtemsBarrierReqRelease_TransitionInfo[] = {
530  {
531    0, 0, 0, 1
532  }, {
533    0, 0, 0, 1
534  }, {
535    0, 0, 0, 1
536  }, {
537    0, 0, 0, 1
538  }, {
539    0, 0, 0, 0
540  }, {
541    0, 0, 0, 0
542  }, {
543    0, 0, 0, 1
544  }, {
545    0, 0, 0, 1
546  }, {
547    0, 0, 0, 0
548  }, {
549    0, 0, 0, 0
550  }, {
551    0, 0, 0, 1
552  }, {
553    0, 0, 0, 1
554  }
555};
556
557static void RtemsBarrierReqRelease_Action(
558  RtemsBarrierReqRelease_Context *ctx
559)
560{
561  ctx->status = rtems_barrier_release( ctx->id, ctx->released );
562}
563
564/**
565 * @fn void T_case_body_RtemsBarrierReqRelease( void )
566 */
567T_TEST_CASE_FIXTURE( RtemsBarrierReqRelease, &RtemsBarrierReqRelease_Fixture )
568{
569  RtemsBarrierReqRelease_Context *ctx;
570  size_t index;
571
572  ctx = T_fixture_context();
573  ctx->in_action_loop = true;
574  index = 0;
575
576  for (
577    ctx->pcs[ 0 ] = RtemsBarrierReqRelease_Pre_Barrier_NoObj;
578    ctx->pcs[ 0 ] < RtemsBarrierReqRelease_Pre_Barrier_NA;
579    ++ctx->pcs[ 0 ]
580  ) {
581    if ( RtemsBarrierReqRelease_TransitionInfo[ index ].Pre_Barrier_NA ) {
582      ctx->pcs[ 0 ] = RtemsBarrierReqRelease_Pre_Barrier_NA;
583      index += ( RtemsBarrierReqRelease_Pre_Barrier_NA - 1 )
584        * RtemsBarrierReqRelease_Pre_Released_NA
585        * RtemsBarrierReqRelease_Pre_Waiting_NA;
586    }
587
588    for (
589      ctx->pcs[ 1 ] = RtemsBarrierReqRelease_Pre_Released_Valid;
590      ctx->pcs[ 1 ] < RtemsBarrierReqRelease_Pre_Released_NA;
591      ++ctx->pcs[ 1 ]
592    ) {
593      if ( RtemsBarrierReqRelease_TransitionInfo[ index ].Pre_Released_NA ) {
594        ctx->pcs[ 1 ] = RtemsBarrierReqRelease_Pre_Released_NA;
595        index += ( RtemsBarrierReqRelease_Pre_Released_NA - 1 )
596          * RtemsBarrierReqRelease_Pre_Waiting_NA;
597      }
598
599      for (
600        ctx->pcs[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_Zero;
601        ctx->pcs[ 2 ] < RtemsBarrierReqRelease_Pre_Waiting_NA;
602        ++ctx->pcs[ 2 ]
603      ) {
604        if ( RtemsBarrierReqRelease_TransitionInfo[ index ].Pre_Waiting_NA ) {
605          ctx->pcs[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_NA;
606          index += ( RtemsBarrierReqRelease_Pre_Waiting_NA - 1 );
607        }
608
609        if ( RtemsBarrierReqRelease_TransitionInfo[ index ].Skip ) {
610          ++index;
611          continue;
612        }
613
614        RtemsBarrierReqRelease_Pre_Barrier_Prepare( ctx, ctx->pcs[ 0 ] );
615        RtemsBarrierReqRelease_Pre_Released_Prepare( ctx, ctx->pcs[ 1 ] );
616        RtemsBarrierReqRelease_Pre_Waiting_Prepare( ctx, ctx->pcs[ 2 ] );
617        RtemsBarrierReqRelease_Action( ctx );
618        RtemsBarrierReqRelease_Post_Status_Check(
619          ctx,
620          RtemsBarrierReqRelease_TransitionMap[ index ][ 0 ]
621        );
622        RtemsBarrierReqRelease_Post_Released_Check(
623          ctx,
624          RtemsBarrierReqRelease_TransitionMap[ index ][ 1 ]
625        );
626        ++index;
627      }
628    }
629  }
630}
631
632/** @} */
Note: See TracBrowser for help on using the repository browser.