source: rtems/testsuites/smptests/smpthreadlife01/init.c @ 4bc8d2e

4.11
Last change on this file since 4bc8d2e was 4bc8d2e, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 10, 2014 at 8:58:27 AM

rtems: Rename rtems_smp_get_processor_count()

Rename rtems_smp_get_processor_count() in rtems_get_processor_count().
Make rtems_get_processor_count() a function in uni-processor
configurations to enable ABI compatibility with SMP configurations.

  • Property mode set to 100644
File size: 7.9 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 arg)
186{
187  test_context *ctx = &test_instance;
188  rtems_interrupt_level level;
189
190  rtems_interrupt_disable(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  /* We get deleted as a side effect of enabling the thread life protection */
202  _Thread_Set_life_protection(true);
203  rtems_test_assert(0);
204}
205
206static void test_set_life_protection(void)
207{
208  test_context *ctx = &test_instance;
209  rtems_status_code sc;
210  rtems_id id;
211  rtems_resource_snapshot snapshot;
212
213  rtems_resource_snapshot_take(&snapshot);
214
215  sc = rtems_task_create(
216    rtems_build_name('D', 'E', 'L', 'Y'),
217    1,
218    RTEMS_MINIMUM_STACK_SIZE,
219    RTEMS_DEFAULT_MODES,
220    RTEMS_DEFAULT_ATTRIBUTES,
221    &id
222  );
223  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
224
225  sc = rtems_task_start(id, delay_ipi_task, 0);
226  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
227
228  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
229
230  sc = rtems_task_delete(id);
231  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
232
233  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
234}
235
236static void delay_switch_task(rtems_task_argument arg)
237{
238  test_context *ctx = &test_instance;
239  rtems_status_code sc;
240  rtems_interrupt_level level;
241
242  rtems_interrupt_disable(level);
243  (void) level;
244
245  ctx->delay_switch_for_executing = _Thread_Get_executing();
246
247  _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT);
248
249  sc = rtems_task_delete(RTEMS_SELF);
250  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
251}
252
253static void test_wait_for_execution_stop(void)
254{
255  test_context *ctx = &test_instance;
256  rtems_status_code sc;
257  rtems_id id;
258  rtems_resource_snapshot snapshot;
259
260  rtems_resource_snapshot_take(&snapshot);
261
262  sc = rtems_task_create(
263    rtems_build_name('S', 'W', 'I', 'T'),
264    1,
265    RTEMS_MINIMUM_STACK_SIZE,
266    RTEMS_DEFAULT_MODES,
267    RTEMS_DEFAULT_ATTRIBUTES,
268    &id
269  );
270  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
271
272  sc = rtems_task_start(id, delay_switch_task, 0);
273  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
274
275  /* Wait for delay switch task */
276  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
277
278  /* Wait for delay switch extension */
279  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
280
281  sc = rtems_task_create(
282    rtems_build_name('W', 'A', 'I', 'T'),
283    1,
284    RTEMS_MINIMUM_STACK_SIZE,
285    RTEMS_DEFAULT_MODES,
286    RTEMS_DEFAULT_ATTRIBUTES,
287    &id
288  );
289  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
290
291  sc = rtems_task_delete(id);
292  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
293
294  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
295}
296
297static void Init(rtems_task_argument arg)
298{
299  TEST_BEGIN();
300
301  if (rtems_get_processor_count() >= CPU_COUNT) {
302    test_restart();
303    test_delete();
304    test_set_life_protection();
305    test_wait_for_execution_stop();
306  }
307
308  TEST_END();
309  rtems_test_exit(0);
310}
311
312#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
313#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
314
315#define CONFIGURE_SMP_APPLICATION
316
317#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
318
319#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
320
321#define CONFIGURE_INITIAL_EXTENSIONS \
322  { \
323    .thread_restart = restart_extension, \
324    .thread_delete = delete_extension, \
325    .thread_terminate = terminate_extension, \
326    .thread_switch = switch_extension \
327  }, \
328  RTEMS_TEST_INITIAL_EXTENSION
329
330#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
331
332#define CONFIGURE_INIT
333
334#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.