source: rtems/testsuites/sptests/sp68/init.c @ 6c0301d

4.115
Last change on this file since 6c0301d was 6c0301d, checked in by Sebastian Huber <sebastian.huber@…>, on 03/25/14 at 07:06:21

tests/sptests: Use <rtems/test.h>

  • Property mode set to 100644
File size: 10.3 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup sptests
5 *
6 * @brief Test for timer server with blocking calls.
7 */
8
9/*
10 * Copyright (c) 2009
11 * embedded brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * <rtems@embedded-brains.de>
16 *
17 * The license and distribution terms for this file may be
18 * found in the file LICENSE in this distribution or at
19 * http://www.rtems.org/license/LICENSE.
20 */
21
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
25
26#include <tmacros.h>
27
28#include <rtems/rtems/timerimpl.h>
29
30const char rtems_test_name[] = "SP 68";
31
32/* forward declarations to avoid warnings */
33rtems_task Init(rtems_task_argument argument);
34
35#define TIMER_COUNT 6
36
37#define OBTAIN 0
38#define RELEASE 1
39#define INTERRUPT 2
40#define DELAYED 3
41#define SERVER_TRIGGERED 4
42#define INTERRUPT_TRIGGERED 5
43
44#define T0 0
45#define T1 1
46#define T2 2
47#define T3 3
48#define T4 4
49#define T5 5
50#define T6 6
51
52static volatile bool obtain_try;
53static volatile bool obtain_done;
54static volatile bool release_happened;
55static volatile bool interrupt_happened;
56static volatile bool delayed_happened;
57static volatile bool server_triggered_happened;
58static volatile bool interrupt_triggered_happened;
59
60static rtems_id timer [TIMER_COUNT];
61
62static rtems_id semaphore;
63static rtems_id mutex;
64static rtems_id message_queue;
65static rtems_id region;
66static rtems_id barrier;
67
68static void *region_item;
69
70static rtems_interval start;
71
72static volatile enum resource_type {
73  SEMAPHORE = 0,
74  MUTEX,
75  MESSAGE_QUEUE,
76  REGION,
77  EVENT,
78  BARRIER,
79  TASK_WAKE_AFTER
80} resource_type;
81
82static const char *resource_type_desc [] = {
83  "SEMAPHORE",
84  "MUTEX",
85  "MESSAGE QUEUE",
86  "REGION",
87  "EVENT",
88  "BARRIER",
89  "TASK WAKE AFTER"
90};
91
92static void assert_time(rtems_interval expected)
93{
94  rtems_test_assert((rtems_clock_get_ticks_since_boot() - start) == expected);
95}
96
97static void obtain_callback(rtems_id timer_id, void *arg)
98{
99  rtems_status_code sc = RTEMS_SUCCESSFUL;
100  char buf [1];
101  size_t size = sizeof(buf);
102  void *new_region_item = NULL;
103  rtems_event_set events = 0;
104
105  assert_time(T1);
106
107  rtems_test_assert(
108    !release_happened
109      && !interrupt_happened
110      && !delayed_happened
111      && !interrupt_triggered_happened
112      && !server_triggered_happened
113  );
114
115  obtain_try = true;
116
117  switch (resource_type) {
118    case SEMAPHORE:
119      sc = rtems_semaphore_obtain(semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
120      break;
121    case MUTEX:
122      sc = rtems_semaphore_obtain(mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
123      break;
124    case MESSAGE_QUEUE:
125      sc = rtems_message_queue_receive(
126        message_queue, buf, &size, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
127      break;
128    case REGION:
129      sc = rtems_region_get_segment(
130        region, 1, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &new_region_item);
131      break;
132    case EVENT:
133      sc = rtems_event_receive(
134        RTEMS_EVENT_0, RTEMS_EVENT_ALL | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
135      break;
136    case BARRIER:
137      sc = rtems_barrier_wait(barrier, RTEMS_NO_TIMEOUT);
138      break;
139    case TASK_WAKE_AFTER:
140      sc = rtems_task_wake_after(T4 - T1);
141      break;
142    default:
143      rtems_test_assert(false);
144      break;
145  }
146  directive_failed(sc, "obtain");
147
148  obtain_done = true;
149}
150
151static void release_callback(rtems_id timer_id, void *arg)
152{
153  rtems_status_code sc = RTEMS_SUCCESSFUL;
154  char buf [1];
155  size_t size = sizeof(buf);
156  uint32_t released = 0;
157
158  assert_time(T4);
159
160  rtems_test_assert(
161    obtain_try
162      && interrupt_happened
163      && !delayed_happened
164      && !interrupt_triggered_happened
165      && !server_triggered_happened
166  );
167
168  switch (resource_type) {
169    case SEMAPHORE:
170      sc = rtems_semaphore_release(semaphore);
171      break;
172    case MUTEX:
173      sc = rtems_semaphore_release(mutex);
174      break;
175    case MESSAGE_QUEUE:
176      sc = rtems_message_queue_send(message_queue, buf, size);
177      break;
178    case EVENT:
179      sc = rtems_event_send(_Timer_server->thread->Object.id, RTEMS_EVENT_0);
180      break;
181    case BARRIER:
182      sc = rtems_barrier_release(barrier, &released);
183      break;
184    case TASK_WAKE_AFTER:
185      sc = RTEMS_SUCCESSFUL;
186      break;
187    default:
188      rtems_test_assert(false);
189      break;
190  }
191  directive_failed_with_level(sc, "release", 1);
192
193  release_happened = true;
194}
195
196static void interrupt_triggered_callback(rtems_id timer_id, void *arg)
197{
198  /*
199   * This callback is scheduled to fire at T3, but is delayed due to the
200   * blocked obtain callback.
201   */
202  assert_time(T4);
203
204  rtems_test_assert(
205    obtain_done
206      && release_happened
207      && interrupt_happened
208      && !server_triggered_happened
209  );
210
211  interrupt_triggered_happened = true;
212}
213
214static void interrupt_callback(rtems_id timer_id, void *arg)
215{
216  rtems_status_code sc = RTEMS_SUCCESSFUL;
217
218  assert_time(T2);
219
220  rtems_test_assert(
221    obtain_try
222      && !obtain_done
223      && !release_happened
224      && !delayed_happened
225      && !interrupt_triggered_happened
226      && !server_triggered_happened
227  );
228
229  sc = rtems_timer_server_fire_after(
230    timer [INTERRUPT_TRIGGERED],
231    T3 - T2,
232    interrupt_triggered_callback,
233    NULL
234  );
235  directive_failed_with_level(sc, "rtems_timer_server_fire_after", -1);
236
237  interrupt_happened = true;
238}
239
240static void server_triggered_callback(rtems_id timer_id, void *arg)
241{
242  assert_time(T5);
243
244  rtems_test_assert(
245    obtain_done
246      && release_happened
247      && interrupt_happened
248      && delayed_happened
249      && interrupt_triggered_happened
250  );
251
252  server_triggered_happened = true;
253}
254
255static void delayed_callback(rtems_id timer_id, void *arg)
256{
257  rtems_status_code sc = RTEMS_SUCCESSFUL;
258
259  assert_time(T4);
260
261  rtems_test_assert(
262    obtain_done
263      && release_happened
264      && interrupt_happened
265      && !server_triggered_happened
266  );
267
268  sc = rtems_timer_server_fire_after(
269    timer [SERVER_TRIGGERED],
270    T5 - T4,
271    server_triggered_callback,
272    NULL
273  );
274  directive_failed(sc, "rtems_timer_server_fire_after");
275
276  delayed_happened = true;
277}
278
279static void test_reset(void)
280{
281  rtems_status_code sc = RTEMS_SUCCESSFUL;
282
283  obtain_try = false;
284  obtain_done = false;
285  release_happened = false;
286  interrupt_happened = false;
287  delayed_happened = false;
288  interrupt_triggered_happened = false;
289  server_triggered_happened = false;
290
291  /* Synchronize with tick */
292  sc = rtems_task_wake_after(1);
293  directive_failed(sc, "rtems_task_wake_after");
294
295  start = rtems_clock_get_ticks_since_boot();
296}
297
298static void test_case(enum resource_type rt)
299{
300  rtems_status_code sc = RTEMS_SUCCESSFUL;
301
302  printf("test case: %s\n", resource_type_desc [rt]);
303
304  resource_type = rt;
305
306  test_reset();
307
308  sc = rtems_timer_server_fire_after(
309    timer [OBTAIN],
310    T1 - T0,
311    obtain_callback,
312    NULL
313  );
314  directive_failed(sc, "rtems_timer_server_fire_after");
315
316  sc = rtems_timer_fire_after(
317    timer [INTERRUPT],
318    T2 - T0,
319    interrupt_callback,
320    NULL
321  );
322  directive_failed(sc, "rtems_timer_fire_after");
323
324  sc = rtems_timer_server_fire_after(
325    timer [DELAYED],
326    T3 - T0,
327    delayed_callback,
328    NULL
329  );
330  directive_failed(sc, "rtems_timer_server_fire_after");
331
332  if (resource_type != REGION) {
333    sc = rtems_timer_fire_after(
334      timer [RELEASE],
335      T4 - T0,
336      release_callback,
337      NULL
338    );
339    directive_failed(sc, "rtems_timer_fire_after");
340
341    assert_time(T0);
342
343    sc = rtems_task_wake_after(T6 - T0);
344    directive_failed(sc, "task_wake_after");
345  } else {
346    sc = rtems_task_wake_after(T4 - T0);
347    directive_failed(sc, "task_wake_after");
348
349    assert_time(T4);
350
351    rtems_test_assert(
352      obtain_try
353        && interrupt_happened
354        && !delayed_happened
355        && !interrupt_triggered_happened
356        && !server_triggered_happened
357    );
358
359    sc = rtems_region_return_segment(region, region_item);
360    directive_failed(sc, "rtems_region_return_segment");
361
362    release_happened = true;
363
364    sc = rtems_task_wake_after(T6 - T4);
365    directive_failed(sc, "task_wake_after");
366  }
367
368  assert_time(T6);
369
370  rtems_test_assert(
371    obtain_done
372      && interrupt_happened
373      && release_happened
374      && delayed_happened
375      && interrupt_triggered_happened
376      && server_triggered_happened
377  );
378}
379
380rtems_task Init(rtems_task_argument argument)
381{
382  rtems_status_code sc = RTEMS_SUCCESSFUL;
383  char region_area [256];
384  enum resource_type rt = SEMAPHORE;
385  void *new_region_item = NULL;
386  size_t i = 0;
387
388  TEST_BEGIN();
389
390  for (i = 0; i < TIMER_COUNT; ++i) {
391    sc = rtems_timer_create(
392      rtems_build_name('T', 'I', 'M', '0' + i),
393      &timer [i]
394    );
395    directive_failed(sc, "rtems_timer_create");
396  }
397
398  sc = rtems_timer_initiate_server(
399    RTEMS_MINIMUM_PRIORITY,
400    RTEMS_MINIMUM_STACK_SIZE,
401    RTEMS_DEFAULT_ATTRIBUTES
402  );
403  directive_failed(sc, "rtems_timer_initiate_server");
404
405  sc = rtems_semaphore_create(
406    rtems_build_name('S', 'E', 'M', 'A'),
407    0,
408    RTEMS_LOCAL | RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE,
409    0,
410    &semaphore
411  );
412  directive_failed(sc, "rtems_semaphore_create");
413
414  sc = rtems_semaphore_create(
415    rtems_build_name('M', 'U', 'T', 'X'),
416    0,
417    RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE,
418    0,
419    &mutex
420  );
421  directive_failed(sc, "rtems_semaphore_create");
422
423  sc = rtems_message_queue_create(
424    rtems_build_name('M', 'S', 'G', 'Q'),
425    1,
426    1,
427    RTEMS_LOCAL | RTEMS_FIFO,
428    &message_queue
429  );
430  directive_failed(sc, "rtems_message_queue_create");
431
432  sc = rtems_region_create(
433    rtems_build_name('R', 'E', 'G', 'I'),
434    region_area,
435    sizeof(region_area),
436    1,
437    RTEMS_LOCAL | RTEMS_FIFO,
438    &region
439  );
440  directive_failed(sc, "rtems_region_create");
441
442  do {
443    region_item = new_region_item;
444    sc = rtems_region_get_segment(
445        region, 1, RTEMS_NO_WAIT, 0, &new_region_item);
446  } while (sc == RTEMS_SUCCESSFUL);
447
448  sc = rtems_barrier_create(
449    rtems_build_name('B', 'A', 'R', 'R'),
450    RTEMS_LOCAL | RTEMS_FIFO,
451    2,
452    &barrier
453  );
454  directive_failed(sc, "rtems_barrier_create");
455
456  while (rt <= TASK_WAKE_AFTER) {
457    test_case(rt);
458    ++rt;
459  }
460
461  TEST_END();
462
463  rtems_test_exit(0);
464}
465
466#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
467#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
468
469#define CONFIGURE_MAXIMUM_TASKS 2
470#define CONFIGURE_MAXIMUM_TIMERS TIMER_COUNT
471#define CONFIGURE_MAXIMUM_SEMAPHORES 2
472#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 1
473#define CONFIGURE_MAXIMUM_REGIONS 1
474#define CONFIGURE_MAXIMUM_BARRIERS 1
475
476#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
477
478#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
479
480#define CONFIGURE_INIT
481
482#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.