source: rtems/testsuites/smptests/smpmigration02/init.c @ e266d13

5
Last change on this file since e266d13 was e266d13, checked in by Sebastian Huber <sebastian.huber@…>, on 05/20/16 at 13:10:27

Replace *_Get_interrupt_disable() with *_Get()

Uniformly use *_Get() to get an object by identifier with a lock
context.

  • Property mode set to 100644
File size: 12.2 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 <rtems.h>
20#include <rtems/libcsupport.h>
21#include <rtems/score/objectimpl.h>
22#include <rtems/score/threadimpl.h>
23
24#include "tmacros.h"
25
26const char rtems_test_name[] = "SMPMIGRATION 2";
27
28#define CPU_COUNT 32
29
30#define TASK_COUNT (CPU_COUNT + 1)
31
32#define PRIO_LOW 3
33
34#define PRIO_HIGH 2
35
36typedef struct {
37  uint32_t value;
38  uint32_t cache_line_separation[31];
39} test_counter;
40
41typedef struct {
42  test_counter counters[TASK_COUNT];
43  rtems_id scheduler_ids[CPU_COUNT];
44  rtems_id task_ids[TASK_COUNT];
45} test_context;
46
47static test_context test_instance;
48
49static void migration_task(rtems_task_argument arg)
50{
51  test_context *ctx = &test_instance;
52  rtems_status_code sc;
53  uint32_t cpu_count = rtems_get_processor_count();
54  uint32_t cpu_index = rtems_get_current_processor();
55
56  while (true) {
57    cpu_index = (cpu_index + 1) % cpu_count;
58
59    sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->scheduler_ids[cpu_index]);
60    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
61
62    ++ctx->counters[arg].value;
63
64    rtems_test_assert(cpu_index == rtems_get_current_processor());
65  }
66}
67
68static void test_migrations(test_context *ctx)
69{
70  rtems_status_code sc;
71  uint32_t cpu_count = rtems_get_processor_count();
72  uint32_t task_count = cpu_count + 1;
73  uint32_t task_index;
74
75  for (task_index = 0; task_index < task_count; ++task_index) {
76    rtems_id task_id;
77
78    sc = rtems_task_create(
79      rtems_build_name('T', 'A', 'S', 'K'),
80      task_index > 0 ? PRIO_LOW : PRIO_HIGH,
81      RTEMS_MINIMUM_STACK_SIZE,
82      RTEMS_DEFAULT_MODES,
83      RTEMS_DEFAULT_ATTRIBUTES,
84      &task_id
85    );
86    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
87
88    sc = rtems_task_set_scheduler(task_id, ctx->scheduler_ids[task_index % cpu_count]);
89    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
90
91    sc = rtems_task_start(task_id, migration_task, task_index);
92    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
93
94    ctx->task_ids[task_index] = task_id;
95  }
96
97  sc = rtems_task_wake_after(30 * rtems_clock_get_ticks_per_second());
98  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
99
100  for (task_index = 0; task_index < task_count; ++task_index) {
101    printf(
102      "task %" PRIu32 " counter: %" PRIu32 "\n",
103      task_index,
104      ctx->counters[task_index].value
105    );
106
107    sc = rtems_task_delete(ctx->task_ids[task_index]);
108    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
109  }
110}
111
112static void busy_loop_task(rtems_task_argument arg)
113{
114  while (true) {
115    /* Do nothing */
116  }
117}
118
119static Thread_Control *get_thread_by_id(rtems_id task_id)
120{
121  ISR_lock_Context lock_context;
122  Thread_Control *thread;
123
124  thread = _Thread_Get(task_id, &lock_context);
125  rtems_test_assert(thread != NULL);
126  _ISR_lock_ISR_enable(&lock_context);
127
128  return thread;
129}
130
131static void test_double_migration(test_context *ctx)
132{
133  uint32_t cpu_count = rtems_get_processor_count();
134
135  if (cpu_count >= 2) {
136    rtems_status_code sc;
137    rtems_id task_id;
138    rtems_id scheduler_id;
139    uint32_t cpu_self_index = 0;
140    uint32_t cpu_other_index = 1;
141    Per_CPU_Control *cpu_self = _Per_CPU_Get_by_index(cpu_self_index);
142    Per_CPU_Control *cpu_other = _Per_CPU_Get_by_index(cpu_other_index);
143    Per_CPU_Control *cpu_self_dispatch_disabled;
144    Thread_Control *self;
145    Thread_Control *other;
146
147    sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
148    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
149
150    rtems_test_assert(scheduler_id == ctx->scheduler_ids[cpu_self_index]);
151
152    sc = rtems_task_create(
153      rtems_build_name('T', 'A', 'S', 'K'),
154      2,
155      RTEMS_MINIMUM_STACK_SIZE,
156      RTEMS_DEFAULT_MODES,
157      RTEMS_DEFAULT_ATTRIBUTES,
158      &task_id
159    );
160    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
161
162    other = get_thread_by_id(task_id);
163
164    sc = rtems_task_set_scheduler(
165      task_id,
166      ctx->scheduler_ids[cpu_other_index]
167    );
168    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
169
170    sc = rtems_task_start(task_id, busy_loop_task, 0);
171    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
172
173    while (!_Thread_Is_executing_on_a_processor(other)) {
174      /* Wait */
175    }
176
177    cpu_self_dispatch_disabled = _Thread_Dispatch_disable();
178    rtems_test_assert(cpu_self == cpu_self_dispatch_disabled);
179
180    self = _Thread_Executing;
181
182    rtems_test_assert(cpu_self->executing == self);
183    rtems_test_assert(cpu_self->heir == self);
184    rtems_test_assert(!cpu_self->dispatch_necessary);
185
186    rtems_test_assert(cpu_other->executing == other);
187    rtems_test_assert(cpu_other->heir == other);
188    rtems_test_assert(!cpu_other->dispatch_necessary);
189
190    sc = rtems_task_set_scheduler(
191      RTEMS_SELF,
192      ctx->scheduler_ids[cpu_other_index]
193    );
194    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
195
196    rtems_test_assert(cpu_self->executing == self);
197    rtems_test_assert(cpu_self->heir != self);
198    rtems_test_assert(cpu_self->dispatch_necessary);
199
200    while (_Thread_Is_executing_on_a_processor(other)) {
201      /* Wait */
202    }
203
204    rtems_test_assert(cpu_other->executing == self);
205    rtems_test_assert(cpu_other->heir == self);
206    rtems_test_assert(!cpu_other->dispatch_necessary);
207
208    sc = rtems_task_set_scheduler(
209      RTEMS_SELF,
210      ctx->scheduler_ids[cpu_self_index]
211    );
212    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
213
214    rtems_test_assert(cpu_self->executing == self);
215    rtems_test_assert(cpu_self->heir == self);
216    rtems_test_assert(cpu_self->dispatch_necessary);
217
218    rtems_test_assert(cpu_other->heir == other);
219
220    _Thread_Dispatch_enable(cpu_self_dispatch_disabled);
221
222    while (!_Thread_Is_executing_on_a_processor(other)) {
223      /* Wait */
224    }
225
226    sc = rtems_task_delete(task_id);
227    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
228  }
229}
230
231static void init_scheduler_ids(test_context *ctx)
232{
233  rtems_status_code sc;
234  uint32_t cpu_count = rtems_get_processor_count();
235  uint32_t cpu_index;
236
237  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
238    sc = rtems_scheduler_ident(cpu_index, &ctx->scheduler_ids[cpu_index]);
239    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
240  }
241}
242
243static void Init(rtems_task_argument arg)
244{
245  test_context *ctx = &test_instance;
246  rtems_resource_snapshot snapshot;
247
248  TEST_BEGIN();
249
250  rtems_resource_snapshot_take(&snapshot);
251
252  init_scheduler_ids(ctx);
253  test_double_migration(ctx);
254  test_migrations(ctx);
255
256  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
257
258  TEST_END();
259  rtems_test_exit(0);
260}
261
262#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
263#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
264
265#define CONFIGURE_SMP_APPLICATION
266
267#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
268
269#define CONFIGURE_SCHEDULER_SIMPLE_SMP
270
271#include <rtems/scheduler.h>
272
273RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(0);
274RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(1);
275RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(2);
276RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(3);
277RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(4);
278RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(5);
279RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(6);
280RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(7);
281RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(8);
282RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(9);
283RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(10);
284RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(11);
285RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(12);
286RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(13);
287RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(14);
288RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(15);
289RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(16);
290RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(17);
291RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(18);
292RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(19);
293RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(20);
294RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(21);
295RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(22);
296RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(23);
297RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(24);
298RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(25);
299RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(26);
300RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(27);
301RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(28);
302RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(29);
303RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(30);
304RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(31);
305
306#define CONFIGURE_SCHEDULER_CONTROLS \
307  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(0, 0), \
308  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(1, 1), \
309  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(2, 2), \
310  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(3, 3), \
311  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(4, 4), \
312  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(5, 5), \
313  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(6, 6), \
314  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(7, 7), \
315  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(8, 8), \
316  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(9, 9), \
317  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(10, 10), \
318  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(11, 11), \
319  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(12, 12), \
320  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(13, 13), \
321  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(14, 14), \
322  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(15, 15), \
323  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(16, 16), \
324  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(17, 17), \
325  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(18, 18), \
326  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(19, 19), \
327  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(20, 20), \
328  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(21, 21), \
329  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(22, 22), \
330  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(23, 23), \
331  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(24, 24), \
332  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(25, 25), \
333  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(26, 26), \
334  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(27, 27), \
335  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(28, 28), \
336  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(29, 29), \
337  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(30, 30), \
338  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(31, 31)
339
340#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
341  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
342  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
343  RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
344  RTEMS_SCHEDULER_ASSIGN(3, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
345  RTEMS_SCHEDULER_ASSIGN(4, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
346  RTEMS_SCHEDULER_ASSIGN(5, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
347  RTEMS_SCHEDULER_ASSIGN(6, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
348  RTEMS_SCHEDULER_ASSIGN(7, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
349  RTEMS_SCHEDULER_ASSIGN(8, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
350  RTEMS_SCHEDULER_ASSIGN(9, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
351  RTEMS_SCHEDULER_ASSIGN(10, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
352  RTEMS_SCHEDULER_ASSIGN(11, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
353  RTEMS_SCHEDULER_ASSIGN(12, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
354  RTEMS_SCHEDULER_ASSIGN(13, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
355  RTEMS_SCHEDULER_ASSIGN(14, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
356  RTEMS_SCHEDULER_ASSIGN(15, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
357  RTEMS_SCHEDULER_ASSIGN(16, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
358  RTEMS_SCHEDULER_ASSIGN(17, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
359  RTEMS_SCHEDULER_ASSIGN(18, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
360  RTEMS_SCHEDULER_ASSIGN(19, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
361  RTEMS_SCHEDULER_ASSIGN(20, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
362  RTEMS_SCHEDULER_ASSIGN(21, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
363  RTEMS_SCHEDULER_ASSIGN(22, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
364  RTEMS_SCHEDULER_ASSIGN(23, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
365  RTEMS_SCHEDULER_ASSIGN(24, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
366  RTEMS_SCHEDULER_ASSIGN(25, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
367  RTEMS_SCHEDULER_ASSIGN(26, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
368  RTEMS_SCHEDULER_ASSIGN(27, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
369  RTEMS_SCHEDULER_ASSIGN(28, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
370  RTEMS_SCHEDULER_ASSIGN(29, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
371  RTEMS_SCHEDULER_ASSIGN(30, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
372  RTEMS_SCHEDULER_ASSIGN(31, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
373
374#define CONFIGURE_MAXIMUM_TASKS (1 + TASK_COUNT)
375
376#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
377
378#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
379
380#define CONFIGURE_INIT
381
382#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.