source: rtems/testsuites/libtests/ttest02/init.c @ cc3fd8fc

Last change on this file since cc3fd8fc was cc3fd8fc, checked in by Sebastian Huber <sebastian.huber@…>, on 07/17/20 at 17:42:32

libtest: Add T_interrupt_test()

Update #3199.

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <rtems/test.h>
33#include <rtems/test-info.h>
34
35#include <rtems.h>
36
37static void
38prepare(void *arg)
39{
40        Atomic_Uint *state;
41
42        state = arg;
43        _Atomic_Store_uint(state, 0, ATOMIC_ORDER_RELAXED);
44}
45
46static void
47action(void *arg)
48{
49        Atomic_Uint *state;
50        unsigned int expected;
51        bool success_0;
52        bool success_1;
53
54        state = arg;
55
56        /*
57         * This code models a critical section in the operating system.  The
58         * interrupt should happen between the two atomic operations.
59         */
60        expected = 0;
61        success_0 = _Atomic_Compare_exchange_uint(state, &expected, 1,
62            ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED);
63        expected = 1;
64        success_1 = _Atomic_Compare_exchange_uint(state, &expected, 2,
65            ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED);
66        T_quiet_true(success_0);
67        T_quiet_true(success_1);
68
69        T_interrupt_test_busy_wait_for_interrupt();
70}
71
72static T_interrupt_test_state
73interrupt(void *arg)
74{
75        Atomic_Uint *state;
76        unsigned int expected;
77
78        if (T_interrupt_test_get_state() != T_INTERRUPT_TEST_ACTION) {
79                return T_INTERRUPT_TEST_CONTINUE;
80        }
81
82        state = arg;
83        expected = 1;
84
85        if (_Atomic_Compare_exchange_uint(state, &expected, expected,
86            ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED)) {
87                return T_INTERRUPT_TEST_DONE;
88        } else if (expected == 0) {
89                return T_INTERRUPT_TEST_EARLY;
90        } else {
91                T_quiet_eq_uint(expected, 2);
92                return T_INTERRUPT_TEST_LATE;
93        }
94}
95
96static const T_interrupt_test_config done_config = {
97        .prepare = prepare,
98        .action = action,
99        .interrupt = interrupt,
100        .max_iteration_count = 10000
101};
102
103T_TEST_CASE(TestInterruptDone)
104{
105        int i;
106
107        for (i = 0; i < 10; ++i) {
108                Atomic_Uint action_state;
109                T_interrupt_test_state state;
110
111                state = T_interrupt_test(&done_config, &action_state);
112                T_eq_int(state, T_INTERRUPT_TEST_DONE);
113        }
114}
115
116static const T_interrupt_test_config timeout_config = {
117        .interrupt = interrupt,
118        .action = action
119};
120
121T_TEST_CASE(TestInterruptTimeout)
122{
123        Atomic_Uint action_state;
124        T_interrupt_test_state state;
125
126        T_plan(1);
127        state = T_interrupt_test(&timeout_config, &action_state);
128        T_step_eq_int(0, state, T_INTERRUPT_TEST_TIMEOUT);
129}
130
131static void
132fatal(void *arg)
133{
134        (void)arg;
135        T_step(0);
136        T_stop();
137}
138
139static const T_interrupt_test_config fatal_config = {
140        .prepare = fatal,
141        .action = action,
142        .interrupt = interrupt,
143        .max_iteration_count = 10000
144};
145
146T_TEST_CASE(TestInterruptFatal)
147{
148        Atomic_Uint action_state;
149
150        T_plan(1);
151        T_interrupt_test(&fatal_config, &action_state);
152        T_unreachable();
153}
154
155const char rtems_test_name[] = "TTEST 2";
156
157static void
158Init(rtems_task_argument argument)
159{
160        rtems_test_run(argument, TEST_STATE);
161}
162
163#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
164#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
165
166#define CONFIGURE_MICROSECONDS_PER_TICK 1000
167
168#define CONFIGURE_MAXIMUM_TASKS 1
169
170#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
171
172#define CONFIGURE_INIT
173
174#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.