source: rtems/testsuites/smptests/smpthreadlife01/init.c @ 5abe5a8

4.115
Last change on this file since 5abe5a8 was 5abe5a8, checked in by Christian Mauderer <Christian.Mauderer@…>, on 06/02/14 at 14:15:15

smptests/smpthreadlife01: Fix for debug enabled

  • Property mode set to 100644
File size: 8.1 KB
Line 
1/*
2 * Copyright (c) 2014 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.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include "tmacros.h"
20
21#include <rtems.h>
22#include <rtems/counter.h>
23#include <rtems/libcsupport.h>
24#include <rtems/score/profiling.h>
25#include <rtems/score/smpbarrier.h>
26#include <rtems/score/threadimpl.h>
27
28const char rtems_test_name[] = "SMPTHREADLIFE 1";
29
30#define CPU_COUNT 2
31
32typedef struct {
33  volatile rtems_task_argument main_arg;
34  volatile rtems_task_argument worker_arg;
35  volatile bool terminated;
36  SMP_barrier_Control barrier;
37  SMP_barrier_State main_barrier_state;
38  SMP_barrier_State worker_barrier_state;
39  Thread_Control *delay_switch_for_executing;
40} test_context;
41
42static test_context test_instance = {
43  .barrier = SMP_BARRIER_CONTROL_INITIALIZER,
44  .main_barrier_state = SMP_BARRIER_STATE_INITIALIZER,
45  .worker_barrier_state = SMP_BARRIER_STATE_INITIALIZER
46};
47
48static void restart_extension(
49  Thread_Control *executing,
50  Thread_Control *restarted
51)
52{
53  rtems_test_assert(executing == restarted);
54}
55
56static void delete_extension(
57  Thread_Control *executing,
58  Thread_Control *deleted
59)
60{
61  rtems_test_assert(executing != deleted);
62}
63
64static void terminate_extension(Thread_Control *executing)
65{
66  test_context *ctx = &test_instance;
67
68  ctx->terminated = true;
69}
70
71static void switch_extension(Thread_Control *executing, Thread_Control *heir)
72{
73  test_context *ctx = &test_instance;
74
75  if (ctx->delay_switch_for_executing == executing) {
76    ctx->delay_switch_for_executing = NULL;
77    _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT);
78    rtems_counter_delay_nanoseconds(100000000);
79
80    /* Avoid bad profiling statisitics */
81    _Profiling_Thread_dispatch_disable( _Per_CPU_Get(), 0 );
82  }
83}
84
85static void worker_task(rtems_task_argument arg)
86{
87  test_context *ctx = &test_instance;
88
89  rtems_test_assert(arg == ctx->main_arg);
90
91  ctx->worker_arg = arg;
92
93  _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT);
94
95  while (true) {
96    /* Do nothing */
97  }
98}
99
100static void test_restart(void)
101{
102  test_context *ctx = &test_instance;
103  rtems_status_code sc;
104  rtems_id id;
105  rtems_task_argument arg;
106  rtems_resource_snapshot snapshot;
107
108  rtems_resource_snapshot_take(&snapshot);
109
110  sc = rtems_task_create(
111    rtems_build_name('W', 'O', 'R', 'K'),
112    1,
113    RTEMS_MINIMUM_STACK_SIZE,
114    RTEMS_DEFAULT_MODES,
115    RTEMS_DEFAULT_ATTRIBUTES,
116    &id
117  );
118  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
119
120  sc = rtems_task_start(id, worker_task, 0);
121  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
122
123  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
124
125  for (arg = 1; arg < 23; ++arg) {
126    ctx->main_arg = arg;
127    ctx->worker_arg = 0;
128
129    sc = rtems_task_restart(id, arg);
130    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
131
132    _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
133
134    rtems_test_assert(ctx->worker_arg == arg);
135  }
136
137  sc = rtems_task_delete(id);
138  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
139
140  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
141}
142
143static void test_delete(void)
144{
145  test_context *ctx = &test_instance;
146  rtems_status_code sc;
147  rtems_id id;
148  rtems_task_argument arg;
149  rtems_resource_snapshot snapshot;
150
151  rtems_resource_snapshot_take(&snapshot);
152
153  for (arg = 31; arg < 57; ++arg) {
154    ctx->main_arg = arg;
155    ctx->worker_arg = 0;
156    ctx->terminated = false;
157
158    sc = rtems_task_create(
159      rtems_build_name('W', 'O', 'R', 'K'),
160      1,
161      RTEMS_MINIMUM_STACK_SIZE,
162      RTEMS_DEFAULT_MODES,
163      RTEMS_DEFAULT_ATTRIBUTES,
164      &id
165    );
166    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
167
168    sc = rtems_task_start(id, worker_task, arg);
169    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
170
171    _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
172
173    rtems_test_assert(ctx->worker_arg == arg);
174    rtems_test_assert(!ctx->terminated);
175
176    sc = rtems_task_delete(id);
177    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
178
179    rtems_test_assert(ctx->terminated);
180
181    rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
182  }
183}
184
185static void delay_ipi_task(rtems_task_argument variant)
186{
187  test_context *ctx = &test_instance;
188  ISR_Level level;
189
190  _ISR_Disable_without_giant(level);
191  (void) level;
192
193  _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT);
194
195  /*
196   * Interrupts are disabled, so the inter-processor interrupt deleting us will
197   * be delayed a bit.
198   */
199  rtems_counter_delay_nanoseconds(100000000);
200
201  if (variant != 0) {
202    _Thread_Disable_dispatch();
203  }
204
205  /*
206   * We get deleted as a side effect of enabling the thread life protection or
207   * later if we enable the thread dispatching.
208   */
209  _Thread_Set_life_protection(true);
210
211  if (variant != 0) {
212    _Thread_Enable_dispatch();
213  }
214
215  rtems_test_assert(0);
216}
217
218static void test_set_life_protection(rtems_task_argument variant)
219{
220  test_context *ctx = &test_instance;
221  rtems_status_code sc;
222  rtems_id id;
223  rtems_resource_snapshot snapshot;
224
225  rtems_resource_snapshot_take(&snapshot);
226
227  sc = rtems_task_create(
228    rtems_build_name('D', 'E', 'L', 'Y'),
229    1,
230    RTEMS_MINIMUM_STACK_SIZE,
231    RTEMS_DEFAULT_MODES,
232    RTEMS_DEFAULT_ATTRIBUTES,
233    &id
234  );
235  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
236
237  sc = rtems_task_start(id, delay_ipi_task, variant);
238  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
239
240  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
241
242  sc = rtems_task_delete(id);
243  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
244
245  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
246}
247
248static void delay_switch_task(rtems_task_argument arg)
249{
250  test_context *ctx = &test_instance;
251  rtems_status_code sc;
252  ISR_Level level;
253
254  _ISR_Disable_without_giant(level);
255  (void) level;
256
257  ctx->delay_switch_for_executing = _Thread_Get_executing();
258
259  _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT);
260
261  sc = rtems_task_delete(RTEMS_SELF);
262  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
263}
264
265static void test_wait_for_execution_stop(void)
266{
267  test_context *ctx = &test_instance;
268  rtems_status_code sc;
269  rtems_id id;
270  rtems_resource_snapshot snapshot;
271
272  rtems_resource_snapshot_take(&snapshot);
273
274  sc = rtems_task_create(
275    rtems_build_name('S', 'W', 'I', 'T'),
276    1,
277    RTEMS_MINIMUM_STACK_SIZE,
278    RTEMS_DEFAULT_MODES,
279    RTEMS_DEFAULT_ATTRIBUTES,
280    &id
281  );
282  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
283
284  sc = rtems_task_start(id, delay_switch_task, 0);
285  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
286
287  /* Wait for delay switch task */
288  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
289
290  /* Wait for delay switch extension */
291  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
292
293  sc = rtems_task_create(
294    rtems_build_name('W', 'A', 'I', 'T'),
295    1,
296    RTEMS_MINIMUM_STACK_SIZE,
297    RTEMS_DEFAULT_MODES,
298    RTEMS_DEFAULT_ATTRIBUTES,
299    &id
300  );
301  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
302
303  sc = rtems_task_delete(id);
304  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
305
306  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
307}
308
309static void Init(rtems_task_argument arg)
310{
311  TEST_BEGIN();
312
313  if (rtems_get_processor_count() >= CPU_COUNT) {
314    test_restart();
315    test_delete();
316    test_set_life_protection(0);
317    test_set_life_protection(1);
318    test_wait_for_execution_stop();
319  }
320
321  TEST_END();
322  rtems_test_exit(0);
323}
324
325#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
326#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
327
328#define CONFIGURE_SMP_APPLICATION
329
330#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
331
332#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
333
334#define CONFIGURE_INITIAL_EXTENSIONS \
335  { \
336    .thread_restart = restart_extension, \
337    .thread_delete = delete_extension, \
338    .thread_terminate = terminate_extension, \
339    .thread_switch = switch_extension \
340  }, \
341  RTEMS_TEST_INITIAL_EXTENSION
342
343#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
344
345#define CONFIGURE_INIT
346
347#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.