source: rtems/testsuites/sptests/spintrcritical10/init.c @ 57f125d

4.115
Last change on this file since 57f125d was 57f125d, checked in by Sebastian Huber <sebastian.huber@…>, on 01/02/13 at 17:56:35

rtems: Critical fix for events

Commit 4b45c1393ce4ee3e1c2762ef3145d2bd6b5b38da marked a test in
_Event_Timeout() as debug only. This test is required also in non-debug
configurations since otherwise state corruption can happen. A revised
test sptests/spintrcritical10 checks the relevant sequences.

  • Property mode set to 100644
File size: 8.8 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2012.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  Copyright (c) 2013 embedded brains GmbH.
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 */
11
12#ifdef HAVE_CONFIG_H
13  #include "config.h"
14#endif
15
16#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
17#include <tmacros.h>
18#include <intrcritical.h>
19
20#define GREEN RTEMS_EVENT_0
21
22#define RED RTEMS_EVENT_1
23
24#define EVENTS (GREEN | RED)
25
26#define DEADBEEF 0xdeadbeef
27
28typedef struct {
29  rtems_id timer;
30  Thread_Control *thread;
31  bool hit;
32} test_context;
33
34static void any_satisfy_before_timeout(rtems_id timer, void *arg)
35{
36  rtems_status_code sc;
37  test_context *ctx = arg;
38  const Thread_Control *thread = ctx->thread;
39
40  if (thread->Wait.count != 0) {
41    ctx->hit = _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
42
43    rtems_test_assert(thread->Wait.count == EVENTS);
44    rtems_test_assert(
45      *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
46    );
47    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
48
49    sc = rtems_event_send(thread->Object.id, GREEN);
50    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
51
52    rtems_test_assert(thread->Wait.count == 0);
53    rtems_test_assert(
54      *(rtems_event_set *) thread->Wait.return_argument == GREEN
55    );
56    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
57
58    sc = rtems_event_send(thread->Object.id, RED);
59    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
60
61    rtems_test_assert(thread->Wait.count == 0);
62    rtems_test_assert(
63      *(rtems_event_set *) thread->Wait.return_argument == GREEN
64    );
65    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
66
67    _Event_Timeout(thread->Object.id, &_Event_Sync_state);
68
69    rtems_test_assert(thread->Wait.count == 0);
70    rtems_test_assert(
71      *(rtems_event_set *) thread->Wait.return_argument == GREEN
72    );
73    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
74
75    if (ctx->hit) {
76      rtems_test_assert(
77        _Event_Sync_state == THREAD_BLOCKING_OPERATION_SATISFIED
78      );
79    }
80  }
81
82  sc = rtems_timer_reset(timer);
83  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
84}
85
86static void test_any_satisfy_before_timeout(test_context *ctx)
87{
88  rtems_status_code sc;
89  int resets = 0;
90
91  puts(
92    "Init - Trying to generate any satisfied before timeout "
93    "while blocking on event"
94  );
95
96  ctx->hit = false;
97
98  interrupt_critical_section_test_support_initialize(NULL);
99
100  sc = rtems_timer_fire_after(ctx->timer, 1, any_satisfy_before_timeout, ctx);
101  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
102
103  while (!ctx->hit && resets < 2) {
104    rtems_event_set out;
105
106    if (interrupt_critical_section_test_support_delay())
107      resets++;
108
109    out = DEADBEEF;
110    sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ANY | RTEMS_WAIT, 1, &out);
111    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
112    rtems_test_assert(out == GREEN);
113
114    out = DEADBEEF;
115    sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, 0, &out);
116    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
117    rtems_test_assert(out == RED);
118  }
119
120  sc = rtems_timer_cancel(ctx->timer);
121  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
122
123  rtems_test_assert(ctx->hit);
124}
125
126static void all_satisfy_before_timeout(rtems_id timer, void *arg)
127{
128  rtems_status_code sc;
129  test_context *ctx = arg;
130  const Thread_Control *thread = ctx->thread;
131
132  if (thread->Wait.count != 0) {
133    ctx->hit = _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
134
135    rtems_test_assert(thread->Wait.count == EVENTS);
136    rtems_test_assert(
137      *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
138    );
139    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
140
141    sc = rtems_event_send(thread->Object.id, GREEN);
142    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
143
144    rtems_test_assert(thread->Wait.count == EVENTS);
145    rtems_test_assert(
146      *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
147    );
148    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
149
150    sc = rtems_event_send(thread->Object.id, RED);
151    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
152
153    rtems_test_assert(thread->Wait.count == 0);
154    rtems_test_assert(
155      *(rtems_event_set *) thread->Wait.return_argument == EVENTS
156    );
157    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
158
159    _Event_Timeout(thread->Object.id, &_Event_Sync_state);
160
161    rtems_test_assert(thread->Wait.count == 0);
162    rtems_test_assert(
163      *(rtems_event_set *) thread->Wait.return_argument == EVENTS
164    );
165    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
166
167    if (ctx->hit) {
168      rtems_test_assert(
169        _Event_Sync_state == THREAD_BLOCKING_OPERATION_SATISFIED
170      );
171    }
172  }
173
174  sc = rtems_timer_reset(timer);
175  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
176}
177
178static void test_all_satisfy_before_timeout(test_context *ctx)
179{
180  rtems_status_code sc;
181  int resets = 0;
182
183  puts(
184    "Init - Trying to generate all satisfied before timeout "
185    "while blocking on event"
186  );
187
188  ctx->hit = false;
189
190  interrupt_critical_section_test_support_initialize(NULL);
191
192  sc = rtems_timer_fire_after(ctx->timer, 1, all_satisfy_before_timeout, ctx);
193  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
194
195  while (!ctx->hit && resets < 2) {
196    rtems_event_set out;
197
198    if (interrupt_critical_section_test_support_delay())
199      resets++;
200
201    out = DEADBEEF;
202    sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_WAIT, 1, &out);
203    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
204    rtems_test_assert(out == EVENTS);
205  }
206
207  sc = rtems_timer_cancel(ctx->timer);
208  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
209
210  rtems_test_assert(ctx->hit);
211}
212
213static void timeout_before_satisfied(rtems_id timer, void *arg)
214{
215  rtems_status_code sc;
216  test_context *ctx = arg;
217  const Thread_Control *thread = ctx->thread;
218
219  if (thread->Wait.count != 0) {
220    ctx->hit =
221      _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
222
223    rtems_test_assert(thread->Wait.count == EVENTS);
224    rtems_test_assert(
225      *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
226    );
227    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
228
229    _Event_Timeout(thread->Object.id, &_Event_Sync_state);
230
231    rtems_test_assert(thread->Wait.count == 0);
232    rtems_test_assert(
233      *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
234    );
235    rtems_test_assert(thread->Wait.return_code == RTEMS_TIMEOUT);
236
237    sc = rtems_event_send(thread->Object.id, EVENTS);
238    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
239
240    rtems_test_assert(thread->Wait.count == 0);
241    rtems_test_assert(
242      *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
243    );
244    rtems_test_assert(thread->Wait.return_code == RTEMS_TIMEOUT);
245
246    if (ctx->hit) {
247      rtems_test_assert(
248        _Event_Sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT
249      );
250    }
251  }
252
253  sc = rtems_timer_reset(timer);
254  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
255}
256
257static void test_timeout_before_all_satisfy(test_context *ctx)
258{
259  rtems_status_code sc;
260  int resets = 0;
261
262  puts(
263    "Init - Trying to generate timeout before all satisfied "
264    "while blocking on event"
265  );
266
267  ctx->hit = false;
268
269  interrupt_critical_section_test_support_initialize(NULL);
270
271  sc = rtems_timer_fire_after(ctx->timer, 1, timeout_before_satisfied, ctx);
272  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
273
274  while (!ctx->hit && resets < 2) {
275    rtems_event_set out;
276
277    if (interrupt_critical_section_test_support_delay())
278      resets++;
279
280    out = DEADBEEF;
281    sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_WAIT, 1, &out);
282    rtems_test_assert(sc == RTEMS_TIMEOUT);
283    rtems_test_assert(out == DEADBEEF);
284
285    out = DEADBEEF;
286    sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_NO_WAIT, 0, &out);
287    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
288    rtems_test_assert(out == EVENTS);
289  }
290
291  sc = rtems_timer_cancel(ctx->timer);
292  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
293
294  rtems_test_assert(ctx->hit);
295}
296
297static rtems_task Init(
298  rtems_task_argument ignored
299)
300{
301  rtems_status_code sc;
302  test_context ctx = {
303    .thread = _Thread_Executing
304  };
305
306  puts( "\n\n*** TEST INTERRUPT CRITICAL SECTION 10 ***" );
307
308  sc = rtems_timer_create(rtems_build_name('T', 'I', 'M', 'R'), &ctx.timer);
309  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
310
311  test_any_satisfy_before_timeout(&ctx);
312  test_all_satisfy_before_timeout(&ctx);
313  test_timeout_before_all_satisfy(&ctx);
314
315  puts( "*** END OF TEST INTERRUPT CRITICAL SECTION 10 ***" );
316  rtems_test_exit(0);
317}
318
319/* configuration information */
320
321#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
322#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
323
324#define CONFIGURE_MAXIMUM_TASKS       1
325#define CONFIGURE_MAXIMUM_TIMERS      1
326#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
327#define CONFIGURE_MICROSECONDS_PER_TICK  1000
328
329#define CONFIGURE_INIT
330#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.