source: rtems/testsuites/validation/tc-signal-send.c @ c0c4b8b

Last change on this file since c0c4b8b was c0c4b8b, checked in by Sebastian Huber <sebastian.huber@…>, on 03/02/21 at 06:54:17

validation: Format comment blocks

  • Property mode set to 100644
File size: 31.2 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSTestCaseRtemsSignalReqSend
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
57#include <rtems/test.h>
58
59/**
60 * @defgroup RTEMSTestCaseRtemsSignalReqSend spec:/rtems/signal/req/send
61 *
62 * @ingroup RTEMSTestSuiteTestsuitesValidation0
63 * @ingroup RTEMSTestSuiteTestsuitesValidation1
64 *
65 * @{
66 */
67
68typedef enum {
69  RtemsSignalReqSend_Pre_Task_NoObj,
70  RtemsSignalReqSend_Pre_Task_Self,
71  RtemsSignalReqSend_Pre_Task_Other,
72  RtemsSignalReqSend_Pre_Task_NA
73} RtemsSignalReqSend_Pre_Task;
74
75typedef enum {
76  RtemsSignalReqSend_Pre_Set_Zero,
77  RtemsSignalReqSend_Pre_Set_NonZero,
78  RtemsSignalReqSend_Pre_Set_NA
79} RtemsSignalReqSend_Pre_Set;
80
81typedef enum {
82  RtemsSignalReqSend_Pre_Handler_Invalid,
83  RtemsSignalReqSend_Pre_Handler_Valid,
84  RtemsSignalReqSend_Pre_Handler_NA
85} RtemsSignalReqSend_Pre_Handler;
86
87typedef enum {
88  RtemsSignalReqSend_Pre_ASR_Enabled,
89  RtemsSignalReqSend_Pre_ASR_Disabled,
90  RtemsSignalReqSend_Pre_ASR_NA
91} RtemsSignalReqSend_Pre_ASR;
92
93typedef enum {
94  RtemsSignalReqSend_Pre_Nested_Yes,
95  RtemsSignalReqSend_Pre_Nested_No,
96  RtemsSignalReqSend_Pre_Nested_NA
97} RtemsSignalReqSend_Pre_Nested;
98
99typedef enum {
100  RtemsSignalReqSend_Post_Status_Ok,
101  RtemsSignalReqSend_Post_Status_InvNum,
102  RtemsSignalReqSend_Post_Status_InvId,
103  RtemsSignalReqSend_Post_Status_NotDef,
104  RtemsSignalReqSend_Post_Status_NA
105} RtemsSignalReqSend_Post_Status;
106
107typedef enum {
108  RtemsSignalReqSend_Post_Handler_NoCall,
109  RtemsSignalReqSend_Post_Handler_DuringSend,
110  RtemsSignalReqSend_Post_Handler_AfterDispatch,
111  RtemsSignalReqSend_Post_Handler_AfterEnable,
112  RtemsSignalReqSend_Post_Handler_NA
113} RtemsSignalReqSend_Post_Handler;
114
115typedef enum {
116  RtemsSignalReqSend_Post_Recursive_Yes,
117  RtemsSignalReqSend_Post_Recursive_No,
118  RtemsSignalReqSend_Post_Recursive_NA
119} RtemsSignalReqSend_Post_Recursive;
120
121/**
122 * @brief Test context for spec:/rtems/signal/req/send test case.
123 */
124typedef struct {
125  rtems_id runner_id;
126
127  rtems_id worker_id;
128
129  rtems_asr_entry handler;
130
131  size_t nested;
132
133  size_t handler_calls;
134
135  size_t calls_after_send;
136
137  size_t calls_after_dispatch;
138
139  size_t calls_after_enable;
140
141  rtems_signal_set processed_signal_sets[ 2 ];
142
143  uintptr_t stack_pointers[ 2 ];;
144
145  rtems_mode mode;;
146
147  rtems_status_code status;
148
149  rtems_id id;
150
151  rtems_signal_set signal_set;
152
153  /**
154   * @brief This member defines the pre-condition states for the next action.
155   */
156  size_t pcs[ 5 ];
157
158  /**
159   * @brief This member indicates if the test action loop is currently
160   *   executed.
161   */
162  bool in_action_loop;
163} RtemsSignalReqSend_Context;
164
165static RtemsSignalReqSend_Context
166  RtemsSignalReqSend_Instance;
167
168static const char * const RtemsSignalReqSend_PreDesc_Task[] = {
169  "NoObj",
170  "Self",
171  "Other",
172  "NA"
173};
174
175static const char * const RtemsSignalReqSend_PreDesc_Set[] = {
176  "Zero",
177  "NonZero",
178  "NA"
179};
180
181static const char * const RtemsSignalReqSend_PreDesc_Handler[] = {
182  "Invalid",
183  "Valid",
184  "NA"
185};
186
187static const char * const RtemsSignalReqSend_PreDesc_ASR[] = {
188  "Enabled",
189  "Disabled",
190  "NA"
191};
192
193static const char * const RtemsSignalReqSend_PreDesc_Nested[] = {
194  "Yes",
195  "No",
196  "NA"
197};
198
199static const char * const * const RtemsSignalReqSend_PreDesc[] = {
200  RtemsSignalReqSend_PreDesc_Task,
201  RtemsSignalReqSend_PreDesc_Set,
202  RtemsSignalReqSend_PreDesc_Handler,
203  RtemsSignalReqSend_PreDesc_ASR,
204  RtemsSignalReqSend_PreDesc_Nested,
205  NULL
206};
207
208#define EVENT_START RTEMS_EVENT_0
209
210#define EVENT_SEND_DONE RTEMS_EVENT_1
211
212#define EVENT_DO_ENABLE RTEMS_EVENT_2
213
214#define EVENT_END RTEMS_EVENT_3
215
216#define EVENT_WORKER_DONE RTEMS_EVENT_4
217
218typedef RtemsSignalReqSend_Context Context;
219
220typedef enum {
221  PRIO_HIGH = 1,
222  PRIO_NORMAL
223} Priorities;
224
225static rtems_event_set Wait( void )
226{
227  rtems_status_code sc;
228  rtems_event_set   events;
229
230  events = 0;
231  sc = rtems_event_receive(
232    RTEMS_ALL_EVENTS,
233    RTEMS_EVENT_ANY | RTEMS_WAIT,
234    RTEMS_NO_TIMEOUT,
235    &events
236  );
237  T_rsc_success( sc );
238
239  return events;
240}
241
242static void SendEvents( rtems_id id, rtems_event_set events )
243{
244  rtems_status_code sc;
245
246  sc = rtems_event_send( id, events );
247  T_rsc_success( sc );
248}
249
250static void WorkerDone( const Context *ctx )
251{
252#if defined(RTEMS_SMP)
253  if ( rtems_scheduler_get_processor_maximum() > 1 ) {
254    SendEvents( ctx->runner_id, EVENT_WORKER_DONE );
255  }
256#endif
257}
258
259static void SendEventsToWorker( const Context *ctx, rtems_event_set events )
260{
261  SendEvents( ctx->worker_id, events );
262
263#if defined(RTEMS_SMP)
264  if ( rtems_scheduler_get_processor_maximum() > 1 ) {
265    events = Wait();
266    T_eq_u32( events, EVENT_WORKER_DONE );
267  }
268#endif
269}
270
271static void SignalHandler( rtems_signal_set signal_set )
272{
273  Context *ctx;
274  size_t   i;
275  size_t   n;
276
277  ctx = T_fixture_context();
278  i = ctx->handler_calls;
279  n = RTEMS_ARRAY_SIZE( ctx->processed_signal_sets );
280  ctx->processed_signal_sets[ i % n ] = signal_set;
281  ctx->stack_pointers[ i % n ] = (uintptr_t) __builtin_frame_address( 0 );
282  T_lt_sz( i, n );
283  ctx->handler_calls = i + 1;
284
285  if ( ctx->nested != 0 && i == 0 ) {
286    rtems_status_code sc;
287
288    if ( ctx->id == ctx->worker_id ) {
289      rtems_event_set events;
290
291      sc = rtems_signal_catch( ctx->handler, RTEMS_NO_ASR );
292      T_rsc_success( sc );
293
294      WorkerDone( ctx );
295
296      events = Wait();
297      T_eq_u32( events, EVENT_SEND_DONE );
298
299      WorkerDone( ctx );
300
301      events = Wait();
302      T_eq_u32( events, EVENT_DO_ENABLE );
303    } else {
304      sc = rtems_signal_catch( ctx->handler, RTEMS_NO_ASR );
305      T_rsc_success( sc );
306
307      ctx->status = rtems_signal_send( ctx->id, ctx->signal_set );
308      ctx->calls_after_send = ctx->handler_calls;
309      ctx->calls_after_dispatch = ctx->handler_calls;
310    }
311  }
312}
313
314static void Worker( rtems_task_argument arg )
315{
316  Context *ctx;
317
318  ctx = (Context *) arg;
319
320  while ( true ) {
321    rtems_status_code sc;
322    rtems_event_set   events;
323
324    events = Wait();
325    T_eq_u32( events, EVENT_START );
326
327    if ( ctx->nested != 0 ) {
328      sc = rtems_signal_catch( SignalHandler, ctx->mode );
329      T_rsc_success( sc );
330
331      sc = rtems_signal_send( RTEMS_SELF, 0x600df00d );
332      T_rsc_success( sc );
333
334      WorkerDone( ctx );
335    } else {
336      rtems_mode mode;
337
338      sc = rtems_task_mode( ctx->mode, RTEMS_ASR_MASK, &mode );
339      T_rsc_success( sc );
340
341      sc = rtems_signal_catch( ctx->handler, RTEMS_NO_ASR );
342      T_rsc_success( sc );
343
344      WorkerDone( ctx );
345
346      events = Wait();
347      T_eq_u32( events, EVENT_SEND_DONE );
348
349      WorkerDone( ctx );
350
351      events = Wait();
352      T_eq_u32( events, EVENT_DO_ENABLE );
353
354      sc = rtems_task_mode( mode, RTEMS_ASR_MASK, &mode );
355      T_rsc_success( sc );
356
357      WorkerDone( ctx );
358    }
359
360    events = Wait();
361    T_eq_u32( events, EVENT_END );
362
363    WorkerDone( ctx );
364  }
365}
366
367static void RtemsSignalReqSend_Pre_Task_Prepare(
368  RtemsSignalReqSend_Context *ctx,
369  RtemsSignalReqSend_Pre_Task state
370)
371{
372  switch ( state ) {
373    case RtemsSignalReqSend_Pre_Task_NoObj: {
374      /*
375       * The ``id`` parameter shall be invalid.
376       */
377      ctx->id = 0xffffffff;
378      break;
379    }
380
381    case RtemsSignalReqSend_Pre_Task_Self: {
382      /*
383       * The ``id`` parameter shall be associated with the calling task.
384       */
385      ctx->id = RTEMS_SELF;
386      break;
387    }
388
389    case RtemsSignalReqSend_Pre_Task_Other: {
390      /*
391       * The ``id`` parameter shall be associated with a task other than the
392       * calling task.
393       */
394      ctx->id = ctx->worker_id;
395      break;
396    }
397
398    case RtemsSignalReqSend_Pre_Task_NA:
399      break;
400  }
401}
402
403static void RtemsSignalReqSend_Pre_Set_Prepare(
404  RtemsSignalReqSend_Context *ctx,
405  RtemsSignalReqSend_Pre_Set  state
406)
407{
408  switch ( state ) {
409    case RtemsSignalReqSend_Pre_Set_Zero: {
410      /*
411       * The ``signal_set`` parameter shall be zero.
412       */
413      ctx->signal_set = 0;
414      break;
415    }
416
417    case RtemsSignalReqSend_Pre_Set_NonZero: {
418      /*
419       * The ``signal_set`` parameter shall be non-zero.
420       */
421      ctx->signal_set = 0xdeadbeef;
422      break;
423    }
424
425    case RtemsSignalReqSend_Pre_Set_NA:
426      break;
427  }
428}
429
430static void RtemsSignalReqSend_Pre_Handler_Prepare(
431  RtemsSignalReqSend_Context    *ctx,
432  RtemsSignalReqSend_Pre_Handler state
433)
434{
435  switch ( state ) {
436    case RtemsSignalReqSend_Pre_Handler_Invalid: {
437      /*
438       * When the target task has no valid ASR handler installed, the
439       * rtems_signal_send() directive shall be called.
440       */
441      ctx->handler = NULL;
442      break;
443    }
444
445    case RtemsSignalReqSend_Pre_Handler_Valid: {
446      /*
447       * When the target task has a valid ASR handler installed, the
448       * rtems_signal_send() directive shall be called.
449       */
450      ctx->handler = SignalHandler;
451      break;
452    }
453
454    case RtemsSignalReqSend_Pre_Handler_NA:
455      break;
456  }
457}
458
459static void RtemsSignalReqSend_Pre_ASR_Prepare(
460  RtemsSignalReqSend_Context *ctx,
461  RtemsSignalReqSend_Pre_ASR  state
462)
463{
464  switch ( state ) {
465    case RtemsSignalReqSend_Pre_ASR_Enabled: {
466      /*
467       * When the target task has ASR processing enabled, the
468       * rtems_signal_send() directive shall be called.
469       */
470      ctx->mode = RTEMS_DEFAULT_MODES;
471      break;
472    }
473
474    case RtemsSignalReqSend_Pre_ASR_Disabled: {
475      /*
476       * When the target task has ASR processing disabled, the
477       * rtems_signal_send() directive shall be called.
478       */
479      ctx->mode = RTEMS_NO_ASR;
480      break;
481    }
482
483    case RtemsSignalReqSend_Pre_ASR_NA:
484      break;
485  }
486}
487
488static void RtemsSignalReqSend_Pre_Nested_Prepare(
489  RtemsSignalReqSend_Context   *ctx,
490  RtemsSignalReqSend_Pre_Nested state
491)
492{
493  switch ( state ) {
494    case RtemsSignalReqSend_Pre_Nested_Yes: {
495      /*
496       * When the target task processes an asynchronous signal set, the
497       * rtems_signal_send() directive shall be called.
498       */
499      ctx->nested = 1;
500      break;
501    }
502
503    case RtemsSignalReqSend_Pre_Nested_No: {
504      /*
505       * When the target task does not process an asynchronous signal set, the
506       * rtems_signal_send() directive shall be called.
507       */
508      ctx->nested = 0;
509      break;
510    }
511
512    case RtemsSignalReqSend_Pre_Nested_NA:
513      break;
514  }
515}
516
517static void RtemsSignalReqSend_Post_Status_Check(
518  RtemsSignalReqSend_Context    *ctx,
519  RtemsSignalReqSend_Post_Status state
520)
521{
522  switch ( state ) {
523    case RtemsSignalReqSend_Post_Status_Ok: {
524      /*
525       * The return status of rtems_signal_send() shall be RTEMS_SUCCESSFUL.
526       */
527      T_rsc_success( ctx->status );
528      break;
529    }
530
531    case RtemsSignalReqSend_Post_Status_InvNum: {
532      /*
533       * The return status of rtems_signal_send() shall be
534       * RTEMS_INVALID_NUMBER.
535       */
536      T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
537      break;
538    }
539
540    case RtemsSignalReqSend_Post_Status_InvId: {
541      /*
542       * The return status of rtems_signal_send() shall be RTEMS_INVALID_ID.
543       */
544      T_rsc( ctx->status, RTEMS_INVALID_ID );
545      break;
546    }
547
548    case RtemsSignalReqSend_Post_Status_NotDef: {
549      /*
550       * The return status of rtems_signal_send() shall be RTEMS_NOT_DEFINED.
551       */
552      T_rsc( ctx->status, RTEMS_NOT_DEFINED );
553      break;
554    }
555
556    case RtemsSignalReqSend_Post_Status_NA:
557      break;
558  }
559}
560
561static void RtemsSignalReqSend_Post_Handler_Check(
562  RtemsSignalReqSend_Context     *ctx,
563  RtemsSignalReqSend_Post_Handler state
564)
565{
566  size_t expected_calls;
567
568  expected_calls = ctx->nested;
569
570  switch ( state ) {
571    case RtemsSignalReqSend_Post_Handler_NoCall: {
572      /*
573       * While the ASR processing is disabled, the ASR handler shall not be
574       * called.
575       */
576      T_eq_sz( ctx->calls_after_send, ctx->nested );
577      T_eq_sz( ctx->calls_after_dispatch, ctx->nested );
578      T_eq_sz( ctx->calls_after_enable, ctx->nested );
579      break;
580    }
581
582    case RtemsSignalReqSend_Post_Handler_DuringSend: {
583      /*
584       * The ASR handler shall be called during the rtems_signal_send() call.
585       */
586      ++expected_calls;
587      T_eq_sz( ctx->calls_after_send, ctx->nested + 1 );
588      T_eq_sz( ctx->calls_after_dispatch, ctx->nested + 1 );
589      T_eq_sz( ctx->calls_after_enable, ctx->nested + 1 );
590      break;
591    }
592
593    case RtemsSignalReqSend_Post_Handler_AfterDispatch: {
594      /*
595       * When the next thread dispatch of the target task of the
596       * rtems_signal_send() call takes place, the ASR handler shall be called.
597       */
598      ++expected_calls;
599      T_eq_sz( ctx->calls_after_send, ctx->nested );
600      T_eq_sz( ctx->calls_after_dispatch, ctx->nested + 1 );
601      T_eq_sz( ctx->calls_after_enable, ctx->nested + 1 );
602      break;
603    }
604
605    case RtemsSignalReqSend_Post_Handler_AfterEnable: {
606      /*
607       * When the target task of the rtems_signal_send() call re-enables ASR
608       * processing, the ASR handler shall be called.
609       */
610      ++expected_calls;
611      T_eq_sz( ctx->calls_after_send, ctx->nested );
612      T_eq_sz( ctx->calls_after_dispatch, ctx->nested );
613      T_eq_sz( ctx->calls_after_enable, ctx->nested + 1 );
614      break;
615    }
616
617    case RtemsSignalReqSend_Post_Handler_NA:
618      break;
619  }
620
621  T_eq_sz( ctx->handler_calls, expected_calls );
622
623  if ( ctx->nested != 0 ) {
624    T_eq_u32( ctx->processed_signal_sets[ 0 ], 0x600df00d );
625  }
626
627  if ( expected_calls > ctx->nested ) {
628    T_eq_u32( ctx->processed_signal_sets[ ctx->nested ], 0xdeadbeef );
629  }
630}
631
632static void RtemsSignalReqSend_Post_Recursive_Check(
633  RtemsSignalReqSend_Context       *ctx,
634  RtemsSignalReqSend_Post_Recursive state
635)
636{
637  switch ( state ) {
638    case RtemsSignalReqSend_Post_Recursive_Yes: {
639      /*
640       * The ASR handler shall be called recursively.
641       */
642      T_eq_sz( ctx->handler_calls, 2 );
643      T_ne_uptr( ctx->stack_pointers[ 0 ], 0 );
644      T_ne_uptr( ctx->stack_pointers[ 1 ], 0 );
645      T_ne_uptr( ctx->stack_pointers[ 0 ], ctx->stack_pointers[ 1 ] );
646      break;
647    }
648
649    case RtemsSignalReqSend_Post_Recursive_No: {
650      /*
651       * The ASR handler shall not be called recursively.
652       */
653      if ( ctx->handler_calls == 2 ) {
654        T_ne_uptr( ctx->stack_pointers[ 0 ], 0 );
655        T_ne_uptr( ctx->stack_pointers[ 1 ], 0 );
656        T_eq_uptr( ctx->stack_pointers[ 0 ], ctx->stack_pointers[ 1 ] );
657      }
658      break;
659    }
660
661    case RtemsSignalReqSend_Post_Recursive_NA:
662      break;
663  }
664}
665
666static void RtemsSignalReqSend_Setup( RtemsSignalReqSend_Context *ctx )
667{
668  rtems_status_code   sc;
669  rtems_task_priority prio;
670
671  memset( ctx, 0, sizeof( *ctx ) );
672  ctx->runner_id = rtems_task_self();
673
674  prio = 0;
675  sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio );
676  T_rsc_success( sc );
677  T_eq_u32( prio, PRIO_HIGH );
678
679  sc = rtems_task_create(
680    rtems_build_name( 'W', 'O', 'R', 'K' ),
681    PRIO_HIGH,
682    RTEMS_MINIMUM_STACK_SIZE,
683    RTEMS_DEFAULT_MODES,
684    RTEMS_DEFAULT_ATTRIBUTES,
685    &ctx->worker_id
686  );
687  T_assert_rsc_success( sc );
688
689  #if defined(RTEMS_SMP)
690  if ( rtems_scheduler_get_processor_maximum() > 1 ) {
691    rtems_id scheduler_id;
692
693    sc = rtems_scheduler_ident_by_processor( 1, &scheduler_id );
694    T_assert_rsc_success( sc );
695
696    sc = rtems_task_set_scheduler( ctx->worker_id, scheduler_id, PRIO_HIGH );
697    T_assert_rsc_success( sc );
698  }
699  #endif
700
701  sc = rtems_task_start( ctx->worker_id, Worker, (rtems_task_argument) ctx );
702  T_assert_rsc_success( sc );
703}
704
705static void RtemsSignalReqSend_Setup_Wrap( void *arg )
706{
707  RtemsSignalReqSend_Context *ctx;
708
709  ctx = arg;
710  ctx->in_action_loop = false;
711  RtemsSignalReqSend_Setup( ctx );
712}
713
714static void RtemsSignalReqSend_Teardown( RtemsSignalReqSend_Context *ctx )
715{
716  rtems_status_code   sc;
717  rtems_task_priority prio;
718
719  prio = 0;
720  sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio );
721  T_rsc_success( sc );
722  T_eq_u32( prio, PRIO_NORMAL );
723
724  if ( ctx->worker_id != 0 ) {
725    sc = rtems_task_delete( ctx->worker_id );
726    T_rsc_success( sc );
727  }
728}
729
730static void RtemsSignalReqSend_Teardown_Wrap( void *arg )
731{
732  RtemsSignalReqSend_Context *ctx;
733
734  ctx = arg;
735  ctx->in_action_loop = false;
736  RtemsSignalReqSend_Teardown( ctx );
737}
738
739static size_t RtemsSignalReqSend_Scope( void *arg, char *buf, size_t n )
740{
741  RtemsSignalReqSend_Context *ctx;
742
743  ctx = arg;
744
745  if ( ctx->in_action_loop ) {
746    return T_get_scope( RtemsSignalReqSend_PreDesc, buf, n, ctx->pcs );
747  }
748
749  return 0;
750}
751
752static T_fixture RtemsSignalReqSend_Fixture = {
753  .setup = RtemsSignalReqSend_Setup_Wrap,
754  .stop = NULL,
755  .teardown = RtemsSignalReqSend_Teardown_Wrap,
756  .scope = RtemsSignalReqSend_Scope,
757  .initial_context = &RtemsSignalReqSend_Instance
758};
759
760static const uint8_t RtemsSignalReqSend_TransitionMap[][ 3 ] = {
761  {
762    RtemsSignalReqSend_Post_Status_InvNum,
763    RtemsSignalReqSend_Post_Handler_NoCall,
764    RtemsSignalReqSend_Post_Recursive_No
765  }, {
766    RtemsSignalReqSend_Post_Status_InvNum,
767    RtemsSignalReqSend_Post_Handler_NoCall,
768    RtemsSignalReqSend_Post_Recursive_No
769  }, {
770    RtemsSignalReqSend_Post_Status_InvNum,
771    RtemsSignalReqSend_Post_Handler_NoCall,
772    RtemsSignalReqSend_Post_Recursive_No
773  }, {
774    RtemsSignalReqSend_Post_Status_InvNum,
775    RtemsSignalReqSend_Post_Handler_NoCall,
776    RtemsSignalReqSend_Post_Recursive_No
777  }, {
778    RtemsSignalReqSend_Post_Status_InvNum,
779    RtemsSignalReqSend_Post_Handler_NoCall,
780    RtemsSignalReqSend_Post_Recursive_No
781  }, {
782    RtemsSignalReqSend_Post_Status_InvNum,
783    RtemsSignalReqSend_Post_Handler_NoCall,
784    RtemsSignalReqSend_Post_Recursive_No
785  }, {
786    RtemsSignalReqSend_Post_Status_InvNum,
787    RtemsSignalReqSend_Post_Handler_NoCall,
788    RtemsSignalReqSend_Post_Recursive_No
789  }, {
790    RtemsSignalReqSend_Post_Status_InvNum,
791    RtemsSignalReqSend_Post_Handler_NoCall,
792    RtemsSignalReqSend_Post_Recursive_No
793  }, {
794    RtemsSignalReqSend_Post_Status_InvId,
795    RtemsSignalReqSend_Post_Handler_NoCall,
796    RtemsSignalReqSend_Post_Recursive_No
797  }, {
798    RtemsSignalReqSend_Post_Status_InvId,
799    RtemsSignalReqSend_Post_Handler_NoCall,
800    RtemsSignalReqSend_Post_Recursive_No
801  }, {
802    RtemsSignalReqSend_Post_Status_InvId,
803    RtemsSignalReqSend_Post_Handler_NoCall,
804    RtemsSignalReqSend_Post_Recursive_No
805  }, {
806    RtemsSignalReqSend_Post_Status_InvId,
807    RtemsSignalReqSend_Post_Handler_NoCall,
808    RtemsSignalReqSend_Post_Recursive_No
809  }, {
810    RtemsSignalReqSend_Post_Status_InvId,
811    RtemsSignalReqSend_Post_Handler_NoCall,
812    RtemsSignalReqSend_Post_Recursive_No
813  }, {
814    RtemsSignalReqSend_Post_Status_InvId,
815    RtemsSignalReqSend_Post_Handler_NoCall,
816    RtemsSignalReqSend_Post_Recursive_No
817  }, {
818    RtemsSignalReqSend_Post_Status_InvId,
819    RtemsSignalReqSend_Post_Handler_NoCall,
820    RtemsSignalReqSend_Post_Recursive_No
821  }, {
822    RtemsSignalReqSend_Post_Status_InvId,
823    RtemsSignalReqSend_Post_Handler_NoCall,
824    RtemsSignalReqSend_Post_Recursive_No
825  }, {
826    RtemsSignalReqSend_Post_Status_InvNum,
827    RtemsSignalReqSend_Post_Handler_NoCall,
828    RtemsSignalReqSend_Post_Recursive_No
829  }, {
830    RtemsSignalReqSend_Post_Status_InvNum,
831    RtemsSignalReqSend_Post_Handler_NoCall,
832    RtemsSignalReqSend_Post_Recursive_No
833  }, {
834    RtemsSignalReqSend_Post_Status_InvNum,
835    RtemsSignalReqSend_Post_Handler_NoCall,
836    RtemsSignalReqSend_Post_Recursive_No
837  }, {
838    RtemsSignalReqSend_Post_Status_InvNum,
839    RtemsSignalReqSend_Post_Handler_NoCall,
840    RtemsSignalReqSend_Post_Recursive_No
841  }, {
842    RtemsSignalReqSend_Post_Status_InvNum,
843    RtemsSignalReqSend_Post_Handler_NoCall,
844    RtemsSignalReqSend_Post_Recursive_No
845  }, {
846    RtemsSignalReqSend_Post_Status_InvNum,
847    RtemsSignalReqSend_Post_Handler_NoCall,
848    RtemsSignalReqSend_Post_Recursive_No
849  }, {
850    RtemsSignalReqSend_Post_Status_InvNum,
851    RtemsSignalReqSend_Post_Handler_NoCall,
852    RtemsSignalReqSend_Post_Recursive_No
853  }, {
854    RtemsSignalReqSend_Post_Status_InvNum,
855    RtemsSignalReqSend_Post_Handler_NoCall,
856    RtemsSignalReqSend_Post_Recursive_No
857  }, {
858    RtemsSignalReqSend_Post_Status_NotDef,
859    RtemsSignalReqSend_Post_Handler_NoCall,
860    RtemsSignalReqSend_Post_Recursive_No
861  }, {
862    RtemsSignalReqSend_Post_Status_NotDef,
863    RtemsSignalReqSend_Post_Handler_NoCall,
864    RtemsSignalReqSend_Post_Recursive_No
865  }, {
866    RtemsSignalReqSend_Post_Status_NotDef,
867    RtemsSignalReqSend_Post_Handler_NoCall,
868    RtemsSignalReqSend_Post_Recursive_No
869  }, {
870    RtemsSignalReqSend_Post_Status_NotDef,
871    RtemsSignalReqSend_Post_Handler_NoCall,
872    RtemsSignalReqSend_Post_Recursive_No
873  }, {
874    RtemsSignalReqSend_Post_Status_Ok,
875    RtemsSignalReqSend_Post_Handler_DuringSend,
876    RtemsSignalReqSend_Post_Recursive_Yes
877  }, {
878    RtemsSignalReqSend_Post_Status_Ok,
879    RtemsSignalReqSend_Post_Handler_DuringSend,
880    RtemsSignalReqSend_Post_Recursive_No
881  }, {
882    RtemsSignalReqSend_Post_Status_Ok,
883    RtemsSignalReqSend_Post_Handler_AfterEnable,
884    RtemsSignalReqSend_Post_Recursive_No
885  }, {
886    RtemsSignalReqSend_Post_Status_Ok,
887    RtemsSignalReqSend_Post_Handler_AfterEnable,
888    RtemsSignalReqSend_Post_Recursive_No
889  }, {
890    RtemsSignalReqSend_Post_Status_InvNum,
891    RtemsSignalReqSend_Post_Handler_NoCall,
892    RtemsSignalReqSend_Post_Recursive_No
893  }, {
894    RtemsSignalReqSend_Post_Status_InvNum,
895    RtemsSignalReqSend_Post_Handler_NoCall,
896    RtemsSignalReqSend_Post_Recursive_No
897  }, {
898    RtemsSignalReqSend_Post_Status_InvNum,
899    RtemsSignalReqSend_Post_Handler_NoCall,
900    RtemsSignalReqSend_Post_Recursive_No
901  }, {
902    RtemsSignalReqSend_Post_Status_InvNum,
903    RtemsSignalReqSend_Post_Handler_NoCall,
904    RtemsSignalReqSend_Post_Recursive_No
905  }, {
906    RtemsSignalReqSend_Post_Status_InvNum,
907    RtemsSignalReqSend_Post_Handler_NoCall,
908    RtemsSignalReqSend_Post_Recursive_No
909  }, {
910    RtemsSignalReqSend_Post_Status_InvNum,
911    RtemsSignalReqSend_Post_Handler_NoCall,
912    RtemsSignalReqSend_Post_Recursive_No
913  }, {
914    RtemsSignalReqSend_Post_Status_InvNum,
915    RtemsSignalReqSend_Post_Handler_NoCall,
916    RtemsSignalReqSend_Post_Recursive_No
917  }, {
918    RtemsSignalReqSend_Post_Status_InvNum,
919    RtemsSignalReqSend_Post_Handler_NoCall,
920    RtemsSignalReqSend_Post_Recursive_No
921  }, {
922    RtemsSignalReqSend_Post_Status_NotDef,
923    RtemsSignalReqSend_Post_Handler_NoCall,
924    RtemsSignalReqSend_Post_Recursive_No
925  }, {
926    RtemsSignalReqSend_Post_Status_NotDef,
927    RtemsSignalReqSend_Post_Handler_NoCall,
928    RtemsSignalReqSend_Post_Recursive_No
929  }, {
930    RtemsSignalReqSend_Post_Status_NotDef,
931    RtemsSignalReqSend_Post_Handler_NoCall,
932    RtemsSignalReqSend_Post_Recursive_No
933  }, {
934    RtemsSignalReqSend_Post_Status_NotDef,
935    RtemsSignalReqSend_Post_Handler_NoCall,
936    RtemsSignalReqSend_Post_Recursive_No
937  }, {
938    RtemsSignalReqSend_Post_Status_Ok,
939    RtemsSignalReqSend_Post_Handler_AfterDispatch,
940    RtemsSignalReqSend_Post_Recursive_Yes
941  }, {
942    RtemsSignalReqSend_Post_Status_Ok,
943    RtemsSignalReqSend_Post_Handler_AfterDispatch,
944    RtemsSignalReqSend_Post_Recursive_No
945  }, {
946    RtemsSignalReqSend_Post_Status_Ok,
947    RtemsSignalReqSend_Post_Handler_AfterEnable,
948    RtemsSignalReqSend_Post_Recursive_No
949  }, {
950    RtemsSignalReqSend_Post_Status_Ok,
951    RtemsSignalReqSend_Post_Handler_AfterEnable,
952    RtemsSignalReqSend_Post_Recursive_No
953  }
954};
955
956static const struct {
957  uint8_t Skip : 1;
958  uint8_t Pre_Task_NA : 1;
959  uint8_t Pre_Set_NA : 1;
960  uint8_t Pre_Handler_NA : 1;
961  uint8_t Pre_ASR_NA : 1;
962  uint8_t Pre_Nested_NA : 1;
963} RtemsSignalReqSend_TransitionInfo[] = {
964  {
965    0, 0, 0, 0, 0, 0
966  }, {
967    0, 0, 0, 0, 0, 0
968  }, {
969    0, 0, 0, 0, 0, 0
970  }, {
971    0, 0, 0, 0, 0, 0
972  }, {
973    0, 0, 0, 0, 0, 0
974  }, {
975    0, 0, 0, 0, 0, 0
976  }, {
977    0, 0, 0, 0, 0, 0
978  }, {
979    0, 0, 0, 0, 0, 0
980  }, {
981    0, 0, 0, 0, 0, 0
982  }, {
983    0, 0, 0, 0, 0, 0
984  }, {
985    0, 0, 0, 0, 0, 0
986  }, {
987    0, 0, 0, 0, 0, 0
988  }, {
989    0, 0, 0, 0, 0, 0
990  }, {
991    0, 0, 0, 0, 0, 0
992  }, {
993    0, 0, 0, 0, 0, 0
994  }, {
995    0, 0, 0, 0, 0, 0
996  }, {
997    0, 0, 0, 0, 0, 0
998  }, {
999    0, 0, 0, 0, 0, 0
1000  }, {
1001    0, 0, 0, 0, 0, 0
1002  }, {
1003    0, 0, 0, 0, 0, 0
1004  }, {
1005    0, 0, 0, 0, 0, 0
1006  }, {
1007    0, 0, 0, 0, 0, 0
1008  }, {
1009    0, 0, 0, 0, 0, 0
1010  }, {
1011    0, 0, 0, 0, 0, 0
1012  }, {
1013    0, 0, 0, 0, 0, 0
1014  }, {
1015    0, 0, 0, 0, 0, 0
1016  }, {
1017    0, 0, 0, 0, 0, 0
1018  }, {
1019    0, 0, 0, 0, 0, 0
1020  }, {
1021    0, 0, 0, 0, 0, 0
1022  }, {
1023    0, 0, 0, 0, 0, 0
1024  }, {
1025    0, 0, 0, 0, 0, 0
1026  }, {
1027    0, 0, 0, 0, 0, 0
1028  }, {
1029    0, 0, 0, 0, 0, 0
1030  }, {
1031    0, 0, 0, 0, 0, 0
1032  }, {
1033    0, 0, 0, 0, 0, 0
1034  }, {
1035    0, 0, 0, 0, 0, 0
1036  }, {
1037    0, 0, 0, 0, 0, 0
1038  }, {
1039    0, 0, 0, 0, 0, 0
1040  }, {
1041    0, 0, 0, 0, 0, 0
1042  }, {
1043    0, 0, 0, 0, 0, 0
1044  }, {
1045    0, 0, 0, 0, 0, 0
1046  }, {
1047    0, 0, 0, 0, 0, 0
1048  }, {
1049    0, 0, 0, 0, 0, 0
1050  }, {
1051    0, 0, 0, 0, 0, 0
1052  }, {
1053    0, 0, 0, 0, 0, 0
1054  }, {
1055    0, 0, 0, 0, 0, 0
1056  }, {
1057    0, 0, 0, 0, 0, 0
1058  }, {
1059    0, 0, 0, 0, 0, 0
1060  }
1061};
1062
1063static void RtemsSignalReqSend_Prepare( RtemsSignalReqSend_Context *ctx )
1064{
1065  ctx->handler_calls = 0;
1066  ctx->calls_after_send = 0;
1067  ctx->calls_after_dispatch = 0;
1068  ctx->calls_after_enable = 0;
1069  memset( &ctx->processed_signal_sets, 0, sizeof( ctx->processed_signal_sets ) );
1070  memset( &ctx->stack_pointers, 0, sizeof( ctx->stack_pointers ) );
1071}
1072
1073static void RtemsSignalReqSend_Action( RtemsSignalReqSend_Context *ctx )
1074{
1075  rtems_status_code sc;
1076
1077  if ( ctx->id == ctx->worker_id ) {
1078    SendEventsToWorker( ctx, EVENT_START );
1079
1080    ctx->status = rtems_signal_send( ctx->id, ctx->signal_set );
1081    ctx->calls_after_send = ctx->handler_calls;
1082
1083    SendEventsToWorker( ctx, EVENT_SEND_DONE );
1084    ctx->calls_after_dispatch = ctx->handler_calls;
1085    SendEventsToWorker( ctx, EVENT_DO_ENABLE );
1086    ctx->calls_after_enable = ctx->handler_calls;
1087    SendEventsToWorker( ctx, EVENT_END );
1088  } else if ( ctx->nested != 0 ) {
1089    sc = rtems_signal_catch( SignalHandler, ctx->mode );
1090    T_rsc_success( sc );
1091
1092    sc = rtems_signal_send( RTEMS_SELF, 0x600df00d );
1093    T_rsc_success( sc );
1094
1095    ctx->calls_after_enable = ctx->handler_calls;
1096  } else {
1097    rtems_mode mode;
1098
1099    sc = rtems_task_mode( ctx->mode, RTEMS_ASR_MASK, &mode );
1100    T_rsc_success( sc );
1101
1102    sc = rtems_signal_catch( ctx->handler, RTEMS_NO_ASR );
1103    T_rsc_success( sc );
1104
1105    ctx->status = rtems_signal_send( ctx->id, ctx->signal_set );
1106    ctx->calls_after_send = ctx->handler_calls;
1107    ctx->calls_after_dispatch = ctx->handler_calls;
1108
1109    sc = rtems_task_mode( mode, RTEMS_ASR_MASK, &mode );
1110    T_rsc_success( sc );
1111
1112    ctx->calls_after_enable = ctx->handler_calls;
1113  }
1114}
1115
1116/**
1117 * @fn void T_case_body_RtemsSignalReqSend( void )
1118 */
1119T_TEST_CASE_FIXTURE( RtemsSignalReqSend, &RtemsSignalReqSend_Fixture )
1120{
1121  RtemsSignalReqSend_Context *ctx;
1122  size_t index;
1123
1124  ctx = T_fixture_context();
1125  ctx->in_action_loop = true;
1126  index = 0;
1127
1128  for (
1129    ctx->pcs[ 0 ] = RtemsSignalReqSend_Pre_Task_NoObj;
1130    ctx->pcs[ 0 ] < RtemsSignalReqSend_Pre_Task_NA;
1131    ++ctx->pcs[ 0 ]
1132  ) {
1133    if ( RtemsSignalReqSend_TransitionInfo[ index ].Pre_Task_NA ) {
1134      ctx->pcs[ 0 ] = RtemsSignalReqSend_Pre_Task_NA;
1135      index += ( RtemsSignalReqSend_Pre_Task_NA - 1 )
1136        * RtemsSignalReqSend_Pre_Set_NA
1137        * RtemsSignalReqSend_Pre_Handler_NA
1138        * RtemsSignalReqSend_Pre_ASR_NA
1139        * RtemsSignalReqSend_Pre_Nested_NA;
1140    }
1141
1142    for (
1143      ctx->pcs[ 1 ] = RtemsSignalReqSend_Pre_Set_Zero;
1144      ctx->pcs[ 1 ] < RtemsSignalReqSend_Pre_Set_NA;
1145      ++ctx->pcs[ 1 ]
1146    ) {
1147      if ( RtemsSignalReqSend_TransitionInfo[ index ].Pre_Set_NA ) {
1148        ctx->pcs[ 1 ] = RtemsSignalReqSend_Pre_Set_NA;
1149        index += ( RtemsSignalReqSend_Pre_Set_NA - 1 )
1150          * RtemsSignalReqSend_Pre_Handler_NA
1151          * RtemsSignalReqSend_Pre_ASR_NA
1152          * RtemsSignalReqSend_Pre_Nested_NA;
1153      }
1154
1155      for (
1156        ctx->pcs[ 2 ] = RtemsSignalReqSend_Pre_Handler_Invalid;
1157        ctx->pcs[ 2 ] < RtemsSignalReqSend_Pre_Handler_NA;
1158        ++ctx->pcs[ 2 ]
1159      ) {
1160        if ( RtemsSignalReqSend_TransitionInfo[ index ].Pre_Handler_NA ) {
1161          ctx->pcs[ 2 ] = RtemsSignalReqSend_Pre_Handler_NA;
1162          index += ( RtemsSignalReqSend_Pre_Handler_NA - 1 )
1163            * RtemsSignalReqSend_Pre_ASR_NA
1164            * RtemsSignalReqSend_Pre_Nested_NA;
1165        }
1166
1167        for (
1168          ctx->pcs[ 3 ] = RtemsSignalReqSend_Pre_ASR_Enabled;
1169          ctx->pcs[ 3 ] < RtemsSignalReqSend_Pre_ASR_NA;
1170          ++ctx->pcs[ 3 ]
1171        ) {
1172          if ( RtemsSignalReqSend_TransitionInfo[ index ].Pre_ASR_NA ) {
1173            ctx->pcs[ 3 ] = RtemsSignalReqSend_Pre_ASR_NA;
1174            index += ( RtemsSignalReqSend_Pre_ASR_NA - 1 )
1175              * RtemsSignalReqSend_Pre_Nested_NA;
1176          }
1177
1178          for (
1179            ctx->pcs[ 4 ] = RtemsSignalReqSend_Pre_Nested_Yes;
1180            ctx->pcs[ 4 ] < RtemsSignalReqSend_Pre_Nested_NA;
1181            ++ctx->pcs[ 4 ]
1182          ) {
1183            if ( RtemsSignalReqSend_TransitionInfo[ index ].Pre_Nested_NA ) {
1184              ctx->pcs[ 4 ] = RtemsSignalReqSend_Pre_Nested_NA;
1185              index += ( RtemsSignalReqSend_Pre_Nested_NA - 1 );
1186            }
1187
1188            if ( RtemsSignalReqSend_TransitionInfo[ index ].Skip ) {
1189              ++index;
1190              continue;
1191            }
1192
1193            RtemsSignalReqSend_Prepare( ctx );
1194            RtemsSignalReqSend_Pre_Task_Prepare( ctx, ctx->pcs[ 0 ] );
1195            RtemsSignalReqSend_Pre_Set_Prepare( ctx, ctx->pcs[ 1 ] );
1196            RtemsSignalReqSend_Pre_Handler_Prepare( ctx, ctx->pcs[ 2 ] );
1197            RtemsSignalReqSend_Pre_ASR_Prepare( ctx, ctx->pcs[ 3 ] );
1198            RtemsSignalReqSend_Pre_Nested_Prepare( ctx, ctx->pcs[ 4 ] );
1199            RtemsSignalReqSend_Action( ctx );
1200            RtemsSignalReqSend_Post_Status_Check(
1201              ctx,
1202              RtemsSignalReqSend_TransitionMap[ index ][ 0 ]
1203            );
1204            RtemsSignalReqSend_Post_Handler_Check(
1205              ctx,
1206              RtemsSignalReqSend_TransitionMap[ index ][ 1 ]
1207            );
1208            RtemsSignalReqSend_Post_Recursive_Check(
1209              ctx,
1210              RtemsSignalReqSend_TransitionMap[ index ][ 2 ]
1211            );
1212            ++index;
1213          }
1214        }
1215      }
1216    }
1217  }
1218}
1219
1220/** @} */
Note: See TracBrowser for help on using the repository browser.