source: rtems/testsuites/smptests/smpscheduler03/init.c @ 4962d24d

4.115
Last change on this file since 4962d24d was 4962d24d, checked in by Sebastian Huber <sebastian.huber@…>, on 06/11/14 at 14:34:51

smptests/smpscheduler03: Test all SMP schedulers

  • Property mode set to 100644
File size: 6.4 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 <stdio.h>
20#include <inttypes.h>
21
22#include <rtems.h>
23#include <rtems/libcsupport.h>
24#include <rtems/score/threadimpl.h>
25#include <rtems/score/schedulersmpimpl.h>
26
27#include "tmacros.h"
28
29const char rtems_test_name[] = "SMPSCHEDULER 3";
30
31#define CPU_MAX 3
32
33#define SCHED_NAME(i) rtems_build_name(' ', ' ', ' ', (char) ('A' + (i)))
34
35typedef struct {
36  rtems_id barrier_id;
37  rtems_id task_id[CPU_MAX];
38  uint32_t cpu_index[CPU_MAX];
39} test_context;
40
41static test_context test_instance;
42
43static void barrier_wait(test_context *ctx)
44{
45  rtems_status_code sc;
46
47  sc = rtems_barrier_wait(ctx->barrier_id, RTEMS_NO_TIMEOUT);
48  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
49}
50
51static void task(rtems_task_argument arg)
52{
53  rtems_test_assert(0);
54}
55
56static void test_case(
57  Thread_Control *executing,
58  Scheduler_SMP_Node *node,
59  Scheduler_SMP_Node_state start_state,
60  Priority_Control prio,
61  bool prepend_it,
62  Scheduler_SMP_Node_state new_state
63)
64{
65  switch (start_state) {
66    case SCHEDULER_SMP_NODE_SCHEDULED:
67      _Thread_Change_priority(executing, 1, true);
68      break;
69    case SCHEDULER_SMP_NODE_READY:
70      _Thread_Change_priority(executing, 4, true);
71      break;
72    default:
73      rtems_test_assert(0);
74      break;
75  }
76  rtems_test_assert(node->state == start_state);
77
78  _Thread_Change_priority(executing, prio, prepend_it);
79  rtems_test_assert(node->state == new_state);
80}
81
82static const Scheduler_SMP_Node_state states[2] = {
83  SCHEDULER_SMP_NODE_SCHEDULED,
84  SCHEDULER_SMP_NODE_READY
85};
86
87static const Priority_Control priorities[2] = { 2, 5 };
88
89static const bool prepend_it[2] = { true, false };
90
91static void test_change_priority(void)
92{
93  rtems_status_code sc;
94  rtems_id task_id;
95  Thread_Control *executing;
96  Scheduler_SMP_Node *node;
97  size_t i;
98  size_t j;
99  size_t k;
100
101  sc = rtems_task_create(
102    rtems_build_name('T', 'A', 'S', 'K'),
103    3,
104    RTEMS_MINIMUM_STACK_SIZE,
105    RTEMS_DEFAULT_MODES,
106    RTEMS_DEFAULT_ATTRIBUTES,
107    &task_id
108  );
109  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
110
111  sc = rtems_task_start(task_id, task, 0);
112  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
113
114  _Thread_Disable_dispatch();
115
116  executing = _Thread_Executing;
117  node = _Scheduler_SMP_Node_get( executing );
118
119  for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
120    for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
121      for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
122        test_case(
123          executing,
124          node,
125          states[i],
126          priorities[j],
127          prepend_it[k],
128          states[j]
129        );
130      }
131    }
132  }
133
134  _Thread_Change_priority(executing, 1, true);
135  rtems_test_assert(node->state == SCHEDULER_SMP_NODE_SCHEDULED);
136
137  _Thread_Enable_dispatch();
138
139  sc = rtems_task_delete(task_id);
140  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
141}
142
143static void test_task(rtems_task_argument arg)
144{
145  test_context *ctx = &test_instance;
146
147  test_change_priority();
148
149  ctx->cpu_index[arg] = rtems_get_current_processor();
150
151  barrier_wait(ctx);
152
153  rtems_task_suspend(RTEMS_SELF);
154  rtems_test_assert(0);
155}
156
157static void done(uint32_t cpu_index)
158{
159  printf("test done on processor %" PRIu32 "\n", cpu_index);
160}
161
162static void Init(rtems_task_argument arg)
163{
164  test_context *ctx = &test_instance;
165  rtems_status_code sc;
166  rtems_resource_snapshot snapshot;
167  uint32_t cpu_count = rtems_get_processor_count();
168  uint32_t cpu_index;
169
170  TEST_BEGIN();
171
172  rtems_resource_snapshot_take(&snapshot);
173
174  sc = rtems_barrier_create(
175    rtems_build_name('B', 'A', 'R', 'I'),
176    RTEMS_BARRIER_AUTOMATIC_RELEASE,
177    cpu_count,
178    &ctx->barrier_id
179  );
180  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
181
182  for (cpu_index = 1; cpu_index < cpu_count; ++cpu_index) {
183    rtems_id scheduler_id;
184
185    sc = rtems_task_create(
186      rtems_build_name('T', 'A', 'S', 'K'),
187      1,
188      RTEMS_MINIMUM_STACK_SIZE,
189      RTEMS_DEFAULT_MODES,
190      RTEMS_DEFAULT_ATTRIBUTES,
191      &ctx->task_id[cpu_index]
192    );
193    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
194
195    sc = rtems_scheduler_ident(SCHED_NAME(cpu_index), &scheduler_id);
196    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
197
198    sc = rtems_task_set_scheduler(ctx->task_id[cpu_index], scheduler_id);
199    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
200
201    sc = rtems_task_start(ctx->task_id[cpu_index], test_task, cpu_index);
202    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
203  }
204
205  test_change_priority();
206
207  barrier_wait(ctx);
208
209  sc = rtems_barrier_delete(ctx->barrier_id);
210  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
211
212  done(0);
213
214  for (cpu_index = 1; cpu_index < cpu_count; ++cpu_index) {
215    sc = rtems_task_delete(ctx->task_id[cpu_index]);
216    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
217
218    rtems_test_assert(ctx->cpu_index[cpu_index] == cpu_index);
219
220    done(cpu_index);
221  }
222
223  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
224
225  TEST_END();
226  rtems_test_exit(0);
227}
228
229#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
230#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
231
232#define CONFIGURE_SMP_APPLICATION
233
234#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_MAX
235
236#define CONFIGURE_MAXIMUM_PRIORITY 255
237
238#define CONFIGURE_SCHEDULER_PRIORITY_SMP
239#define CONFIGURE_SCHEDULER_SIMPLE_SMP
240#define CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
241
242#include <rtems/scheduler.h>
243
244RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP(a, CONFIGURE_MAXIMUM_PRIORITY + 1);
245
246RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b);
247
248RTEMS_SCHEDULER_CONTEXT_PRIORITY_AFFINITY_SMP(
249  c,
250  CONFIGURE_MAXIMUM_PRIORITY + 1
251);
252
253#define CONFIGURE_SCHEDULER_CONTROLS \
254  RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP(a, SCHED_NAME(0)), \
255  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(b, SCHED_NAME(1)), \
256  RTEMS_SCHEDULER_CONTROL_PRIORITY_AFFINITY_SMP(c, SCHED_NAME(2))
257
258#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
259  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
260  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
261  RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
262
263#define CONFIGURE_MAXIMUM_TASKS 6
264#define CONFIGURE_MAXIMUM_BARRIERS 1
265
266#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
267
268#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
269
270#define CONFIGURE_INIT
271
272#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.