source: rtems/testsuites/sptests/sp68/init.c @ cfcdb5b2

4.115
Last change on this file since cfcdb5b2 was 6e51c4c, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 11/30/09 at 09:08:35

Added timer server control block
Removed _Timer_Server thread pointer
Added _Timer_server pointer to the default timer server control block
Rework of the timer server implementation.

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