source: rtems/testsuites/sptests/spextensions01/init.c @ 6a9282d

5
Last change on this file since 6a9282d was 6a9282d, checked in by Sebastian Huber <sebastian.huber@…>, on 12/09/16 at 09:49:49

Rename is_internal to always_set_to_false

Update #2825.

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/*
2 * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.com/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#define TESTS_USE_PRINTK
20#include "tmacros.h"
21
22#include <assert.h>
23#include <limits.h>
24#include <stdlib.h>
25
26#include <bsp.h>
27
28#include <rtems/score/apimutex.h>
29#include <rtems/score/sysstate.h>
30#include <rtems/score/threaddispatch.h>
31
32const char rtems_test_name[] = "SPEXTENSIONS 1";
33
34static int counter;
35
36static int active_extensions = 2;
37
38static rtems_id master_task;
39
40static bool before_multitasking(void)
41{
42  return _System_state_Is_before_multitasking(_System_state_Get());
43}
44
45static bool life_protected(void)
46{
47  Thread_Control *executing;
48
49  executing = _Thread_Get_executing();
50
51  return executing == NULL
52    || (executing->Life.state & THREAD_LIFE_PROTECTED) != 0;
53}
54
55static void assert_normal_thread_context(void)
56{
57  assert(_Thread_Dispatch_is_enabled());
58  assert(!_RTEMS_Allocator_is_owner());
59  assert(!life_protected());
60}
61
62static void assert_life_protected_thread_context(void)
63{
64  assert(_Thread_Dispatch_is_enabled() || before_multitasking());
65  assert(!_RTEMS_Allocator_is_owner());
66  assert(life_protected() || before_multitasking());
67}
68
69static void assert_allocator_protected_thread_context(void)
70{
71  assert(_Thread_Dispatch_is_enabled() || before_multitasking());
72  assert(_RTEMS_Allocator_is_owner());
73  assert(life_protected() || before_multitasking());
74}
75
76static void assert_thread_dispatch_disabled_context(void)
77{
78  assert(!_Thread_Dispatch_is_enabled());
79  assert(!_RTEMS_Allocator_is_owner());
80  assert(!life_protected());
81}
82
83static void assert_static_order(int index)
84{
85  assert((counter % active_extensions) == index);
86  ++counter;
87}
88
89static void assert_forward_order(int index)
90{
91  assert((counter % active_extensions) == index);
92  ++counter;
93}
94
95static void assert_reverse_order(int index)
96{
97  assert((counter % active_extensions) == (5 - index));
98  ++counter;
99}
100
101static bool zero_thread_create(rtems_tcb *a, rtems_tcb *b)
102{
103  assert_static_order(0);
104  assert_allocator_protected_thread_context();
105  return true;
106}
107
108static void zero_thread_start(rtems_tcb *a, rtems_tcb *b)
109{
110  assert_static_order(0);
111  assert_thread_dispatch_disabled_context();
112}
113
114static void zero_thread_restart(rtems_tcb *a, rtems_tcb *b)
115{
116  assert_static_order(0);
117  assert_life_protected_thread_context();
118}
119
120static void zero_thread_delete(rtems_tcb *a, rtems_tcb *b)
121{
122  assert_static_order(0);
123  assert_allocator_protected_thread_context();
124}
125
126static void zero_thread_switch(rtems_tcb *a, rtems_tcb *b)
127{
128  assert_static_order(0);
129}
130
131static void zero_thread_begin(rtems_tcb *a)
132{
133  assert_static_order(0);
134  assert_normal_thread_context();
135}
136
137static void zero_thread_exitted(rtems_tcb *a)
138{
139  assert_static_order(0);
140  assert_normal_thread_context();
141}
142
143static void zero_fatal(
144  rtems_fatal_source source,
145  bool always_set_to_false,
146  rtems_fatal_code code
147)
148{
149  if (source == RTEMS_FATAL_SOURCE_EXIT) {
150    assert_static_order(0);
151  }
152}
153
154static void zero_thread_terminate(rtems_tcb *a)
155{
156  assert_static_order(0);
157  assert_life_protected_thread_context();
158}
159
160static bool one_thread_create(rtems_tcb *a, rtems_tcb *b)
161{
162  assert_static_order(1);
163  assert_allocator_protected_thread_context();
164  return true;
165}
166
167static void one_thread_start(rtems_tcb *a, rtems_tcb *b)
168{
169  assert_static_order(1);
170  assert_thread_dispatch_disabled_context();
171}
172
173static void one_thread_restart(rtems_tcb *a, rtems_tcb *b)
174{
175  assert_static_order(1);
176  assert_life_protected_thread_context();
177}
178
179static void one_thread_delete(rtems_tcb *a, rtems_tcb *b)
180{
181  assert_static_order(1);
182  assert_allocator_protected_thread_context();
183}
184
185static void one_thread_switch(rtems_tcb *a, rtems_tcb *b)
186{
187  assert_static_order(1);
188}
189
190static void one_thread_begin(rtems_tcb *a)
191{
192  assert_static_order(1);
193  assert_normal_thread_context();
194}
195
196static void one_thread_exitted(rtems_tcb *a)
197{
198  assert_static_order(1);
199  assert_normal_thread_context();
200}
201
202static void one_fatal(
203  rtems_fatal_source source,
204  bool always_set_to_false,
205  rtems_fatal_code code
206)
207{
208  if (source == RTEMS_FATAL_SOURCE_EXIT) {
209    assert_static_order(1);
210  }
211}
212
213static void one_thread_terminate(rtems_tcb *a)
214{
215  assert_static_order(1);
216  assert_life_protected_thread_context();
217}
218
219static bool two_thread_create(rtems_tcb *a, rtems_tcb *b)
220{
221  assert_forward_order(2);
222  assert_allocator_protected_thread_context();
223  return true;
224}
225
226static void two_thread_start(rtems_tcb *a, rtems_tcb *b)
227{
228  assert_forward_order(2);
229  assert_thread_dispatch_disabled_context();
230}
231
232static void two_thread_restart(rtems_tcb *a, rtems_tcb *b)
233{
234  assert_static_order(2);
235  assert_life_protected_thread_context();
236}
237
238static void two_thread_delete(rtems_tcb *a, rtems_tcb *b)
239{
240  assert_reverse_order(2);
241  assert_allocator_protected_thread_context();
242}
243
244static void two_thread_switch(rtems_tcb *a, rtems_tcb *b)
245{
246  assert_forward_order(2);
247}
248
249static void two_thread_begin(rtems_tcb *a)
250{
251  assert_forward_order(2);
252  assert_normal_thread_context();
253}
254
255static void two_thread_exitted(rtems_tcb *a)
256{
257  assert_forward_order(2);
258  assert_normal_thread_context();
259}
260
261static void two_fatal(
262  rtems_fatal_source source,
263  bool always_set_to_false,
264  rtems_fatal_code code
265)
266{
267  if (source == RTEMS_FATAL_SOURCE_EXIT) {
268    assert_reverse_order(2);
269    assert(counter == 72);
270    TEST_END();
271  }
272}
273
274static void two_thread_terminate(rtems_tcb *a)
275{
276  assert_forward_order(2);
277  assert_life_protected_thread_context();
278}
279
280static bool three_thread_create(rtems_tcb *a, rtems_tcb *b)
281{
282  assert_forward_order(3);
283  assert_allocator_protected_thread_context();
284  return true;
285}
286
287static void three_thread_start(rtems_tcb *a, rtems_tcb *b)
288{
289  assert_forward_order(3);
290  assert_thread_dispatch_disabled_context();
291}
292
293static void three_thread_restart(rtems_tcb *a, rtems_tcb *b)
294{
295  assert_static_order(3);
296  assert_life_protected_thread_context();
297}
298
299static void three_thread_delete(rtems_tcb *a, rtems_tcb *b)
300{
301  assert_reverse_order(3);
302  assert_allocator_protected_thread_context();
303}
304
305static void three_thread_switch(rtems_tcb *a, rtems_tcb *b)
306{
307  assert_forward_order(3);
308}
309
310static void three_thread_begin(rtems_tcb *a)
311{
312  assert_forward_order(3);
313  assert_normal_thread_context();
314}
315
316static void three_thread_exitted(rtems_tcb *a)
317{
318  assert_forward_order(3);
319  assert_normal_thread_context();
320}
321
322static void three_fatal(
323  rtems_fatal_source source,
324  bool always_set_to_false,
325  rtems_fatal_code code
326)
327{
328  if (source == RTEMS_FATAL_SOURCE_EXIT) {
329    assert_reverse_order(3);
330  }
331}
332
333static void three_thread_terminate(rtems_tcb *a)
334{
335  assert_forward_order(3);
336  assert_life_protected_thread_context();
337}
338
339#define ZERO \
340  { \
341    .thread_create = zero_thread_create, \
342    .thread_start = zero_thread_start, \
343    .thread_restart = zero_thread_restart, \
344    .thread_delete = zero_thread_delete, \
345    .thread_switch = zero_thread_switch, \
346    .thread_begin = zero_thread_begin, \
347    .thread_exitted = zero_thread_exitted, \
348    .fatal = zero_fatal, \
349    .thread_terminate = zero_thread_terminate \
350  }
351
352#define ONE \
353  { \
354    .thread_create = one_thread_create, \
355    .thread_start = one_thread_start, \
356    .thread_restart = one_thread_restart, \
357    .thread_delete = one_thread_delete, \
358    .thread_switch = one_thread_switch, \
359    .thread_begin = one_thread_begin, \
360    .thread_exitted = one_thread_exitted, \
361    .fatal = one_fatal, \
362    .thread_terminate = one_thread_terminate \
363  }
364
365static const rtems_extensions_table two = {
366  .thread_create = two_thread_create,
367  .thread_start = two_thread_start,
368  .thread_restart = two_thread_restart,
369  .thread_delete = two_thread_delete,
370  .thread_switch = two_thread_switch,
371  .thread_begin = two_thread_begin,
372  .thread_exitted = two_thread_exitted,
373  .fatal = two_fatal,
374  .thread_terminate = two_thread_terminate
375};
376
377static const rtems_extensions_table three = {
378  .thread_create = three_thread_create,
379  .thread_start = three_thread_start,
380  .thread_restart = three_thread_restart,
381  .thread_delete = three_thread_delete,
382  .thread_switch = three_thread_switch,
383  .thread_begin = three_thread_begin,
384  .thread_exitted = three_thread_exitted,
385  .fatal = three_fatal,
386  .thread_terminate = three_thread_terminate
387};
388
389static const rtems_extensions_table initial_test =
390  RTEMS_TEST_INITIAL_EXTENSION;
391
392#ifdef BSP_INITIAL_EXTENSION
393static const rtems_extensions_table initial_bsp =
394  BSP_INITIAL_EXTENSION;
395#endif
396
397static void wake_up_master(void)
398{
399  rtems_status_code sc;
400
401  sc = rtems_event_transient_send(master_task);
402  assert(sc == RTEMS_SUCCESSFUL);
403}
404
405static void wait_for_worker(void)
406{
407  rtems_status_code sc;
408
409  sc = rtems_event_transient_receive(
410    RTEMS_WAIT,
411    RTEMS_NO_TIMEOUT
412  );
413  assert(sc == RTEMS_SUCCESSFUL);
414}
415
416static void worker(rtems_task_argument arg)
417{
418  wake_up_master();
419
420  (void) rtems_task_suspend(RTEMS_SELF);
421  assert(false);
422}
423
424static void test(void)
425{
426  rtems_status_code sc;
427  rtems_id id;
428
429  master_task = rtems_task_self();
430
431#ifdef BSP_INITIAL_EXTENSION
432  sc = rtems_extension_create(
433    rtems_build_name(' ', 'B', 'S', 'P'),
434    &initial_bsp,
435    &id
436  );
437  assert(sc == RTEMS_SUCCESSFUL);
438#undef BSP_INITIAL_EXTENSION
439#endif
440
441  sc = rtems_extension_create(
442    rtems_build_name('T', 'E', 'S', 'T'),
443    &initial_test,
444    &id
445  );
446  assert(sc == RTEMS_SUCCESSFUL);
447
448  sc = rtems_extension_create(
449    rtems_build_name('2', ' ', ' ', ' '),
450    &two,
451    &id
452  );
453  assert(sc == RTEMS_SUCCESSFUL);
454
455  sc = rtems_extension_create(
456    rtems_build_name('3', ' ', ' ', ' '),
457    &three,
458    &id
459  );
460  assert(sc == RTEMS_SUCCESSFUL);
461
462  active_extensions = 4;
463  assert(counter == 14);
464  counter = 16;
465
466  sc = rtems_task_create(
467    rtems_build_name('W', 'O', 'R', 'K'),
468    2,
469    RTEMS_MINIMUM_STACK_SIZE,
470    RTEMS_DEFAULT_MODES,
471    RTEMS_DEFAULT_ATTRIBUTES,
472    &id
473  );
474  assert(sc == RTEMS_SUCCESSFUL);
475
476  sc = rtems_task_start(id, worker, 0);
477  assert(sc == RTEMS_SUCCESSFUL);
478
479  wait_for_worker();
480
481  sc = rtems_task_restart(id, 0);
482  assert(sc == RTEMS_SUCCESSFUL);
483
484  wait_for_worker();
485
486  sc = rtems_task_delete(id);
487  assert(sc == RTEMS_SUCCESSFUL);
488
489  /* Process zombies to trigger delete extensions */
490  sc = rtems_task_create(
491    rtems_build_name('N', 'U', 'L', 'L'),
492    2,
493    SIZE_MAX,
494    RTEMS_DEFAULT_MODES,
495    RTEMS_DEFAULT_ATTRIBUTES,
496    &id
497  );
498  assert(sc == RTEMS_UNSATISFIED);
499}
500
501static void Init(rtems_task_argument arg)
502{
503  TEST_BEGIN();
504
505  test();
506
507  exit(0);
508}
509
510#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
511#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
512
513#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 4
514
515#define CONFIGURE_MAXIMUM_TASKS 2
516
517#define CONFIGURE_INITIAL_EXTENSIONS ZERO, ONE
518
519#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
520
521#define CONFIGURE_INIT
522
523#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.