source: rtems/testsuites/sptests/spcontext01/init.c @ b2765075

4.115
Last change on this file since b2765075 was b2765075, checked in by Sebastian Huber <sebastian.huber@…>, on 06/03/15 at 08:07:23

sptests/spcontext01: Improve output

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Copyright (c) 2013-2015 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
21const char rtems_test_name[] = "SPCONTEXT 1";
22
23#define ITERATION_COUNT 2000
24
25#define PRIORITY_HIGH 2
26
27#define PRIORITY_LOW 3
28
29#define FINISH_EVENT RTEMS_EVENT_0
30
31typedef struct {
32  rtems_id control_task;
33  rtems_id validate_tasks[3];
34  rtems_id timer;
35  size_t task_index;
36  int iteration_counter;
37} test_context;
38
39static test_context test_instance;
40
41static void validate_task(rtems_task_argument arg)
42{
43  _CPU_Context_validate(arg);
44  rtems_test_assert(0);
45}
46
47static void start_validate_task(
48  rtems_id *id,
49  uintptr_t pattern,
50  rtems_task_priority priority,
51  bool fp_unit
52)
53{
54  rtems_status_code sc;
55  rtems_attribute fpu_state;
56
57  fpu_state = fp_unit ? RTEMS_FLOATING_POINT : RTEMS_DEFAULT_ATTRIBUTES;
58
59  sc = rtems_task_create(
60    rtems_build_name('V', 'A', 'L', 'I'),
61    priority,
62    RTEMS_MINIMUM_STACK_SIZE,
63    RTEMS_DEFAULT_MODES,
64    fpu_state,
65    id
66  );
67  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
68
69  sc = rtems_task_start(*id, validate_task, pattern);
70  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
71}
72
73static void reset_timer_or_finish(test_context *self, rtems_id timer)
74{
75  rtems_status_code sc;
76  int i = self->iteration_counter;
77
78  if (i < ITERATION_COUNT) {
79    self->iteration_counter = i + 1;
80
81    sc = rtems_timer_reset(timer);
82    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
83  } else {
84    sc = rtems_event_send(self->control_task, FINISH_EVENT);
85    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
86  }
87}
88
89static void switch_priorities(test_context *self)
90{
91  rtems_status_code sc;
92  size_t index = self->task_index;
93  size_t next = (index + 1) % RTEMS_ARRAY_SIZE(self->validate_tasks);
94  size_t task_current_high = index;
95  size_t task_next_high = next;
96  rtems_task_priority priority;
97
98  self->task_index = next;
99
100  sc = rtems_task_set_priority(
101    self->validate_tasks[task_next_high],
102    PRIORITY_HIGH,
103    &priority
104  );
105  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
106
107  sc = rtems_task_set_priority(
108    self->validate_tasks[task_current_high],
109    PRIORITY_LOW,
110    &priority
111  );
112  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
113}
114
115static void clobber_and_switch_timer(rtems_id timer, void *arg)
116{
117  uintptr_t pattern = (uintptr_t) 0xffffffffffffffffU;
118  test_context *self = arg;
119
120  reset_timer_or_finish(self, self->timer);
121  switch_priorities(self);
122
123  _CPU_Context_volatile_clobber(pattern);
124}
125
126static void start_timer(test_context *self)
127{
128  rtems_status_code sc;
129
130  sc = rtems_timer_create(rtems_build_name('C', 'L', 'S', 'W'), &self->timer);
131  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
132
133  sc = rtems_timer_fire_after(self->timer, 2, clobber_and_switch_timer, self);
134  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
135}
136
137static void wait_for_finish(void)
138{
139  rtems_status_code sc;
140  rtems_event_set out;
141
142  sc = rtems_event_receive(
143    FINISH_EVENT,
144    RTEMS_WAIT | RTEMS_EVENT_ALL,
145    RTEMS_NO_TIMEOUT,
146    &out
147  );
148  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
149  rtems_test_assert(out == FINISH_EVENT);
150}
151
152static void test(
153  test_context *self,
154  bool task_0_fpu,
155  bool task_1_fpu,
156  bool task_2_fpu
157)
158{
159  rtems_status_code sc;
160  uintptr_t pattern_0 = (uintptr_t) 0xaaaaaaaaaaaaaaaaU;
161  uintptr_t pattern_1 = (uintptr_t) 0x5555555555555555U;
162  uintptr_t pattern_2 = (uintptr_t) 0x0000000000000000U;
163
164  memset(self, 0, sizeof(*self));
165
166  self->control_task = rtems_task_self();
167  start_validate_task(
168    &self->validate_tasks[0],
169    pattern_0,
170    PRIORITY_HIGH,
171    task_0_fpu
172  );
173  start_validate_task(
174    &self->validate_tasks[1],
175    pattern_1,
176    PRIORITY_LOW,
177    task_1_fpu
178  );
179  start_validate_task(
180    &self->validate_tasks[2],
181    pattern_2,
182    PRIORITY_LOW,
183    task_2_fpu
184  );
185  start_timer(self);
186  wait_for_finish();
187
188  sc = rtems_task_delete(self->validate_tasks[0]);
189  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
190
191  sc = rtems_task_delete(self->validate_tasks[1]);
192  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
193
194  sc = rtems_task_delete(self->validate_tasks[2]);
195  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
196
197  sc = rtems_timer_delete(self->timer);
198  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
199}
200
201static void test_context_is_executing(void)
202{
203#if defined(RTEMS_SMP)
204  /*
205   * Provide a stack area, since on some architectures the top/bottom of stack
206   * is initialized by _CPU_Context_Initialize().
207   */
208  static char stack[1024];
209
210  Context_Control context;
211  bool is_executing;
212
213  memset(&context, 0, sizeof(context));
214
215  is_executing = _CPU_Context_Get_is_executing(&context);
216  rtems_test_assert(!is_executing);
217
218  _CPU_Context_Set_is_executing(&context, true);
219  is_executing = _CPU_Context_Get_is_executing(&context);
220  rtems_test_assert(is_executing);
221
222  _CPU_Context_Set_is_executing(&context, false);
223  is_executing = _CPU_Context_Get_is_executing(&context);
224  rtems_test_assert(!is_executing);
225
226  _CPU_Context_Set_is_executing(&context, true);
227  _CPU_Context_Initialize(
228    &context,
229    (void *) &stack[0],
230    sizeof(stack),
231    0,
232    NULL,
233    false,
234    NULL
235  );
236  is_executing = _CPU_Context_Get_is_executing(&context);
237  rtems_test_assert(is_executing);
238#endif
239}
240
241static bool is_fp(int i)
242{
243  return i != 0;
244}
245
246static const char *desc(int i)
247{
248  return is_fp(i) ? "F" : "N";
249}
250
251static void Init(rtems_task_argument arg)
252{
253  test_context *self = &test_instance;
254  int i;
255  int j;
256  int k;
257
258  TEST_BEGIN();
259
260  test_context_is_executing();
261
262  for (i = 0; i < 2; ++i) {
263    for (j = 0; j < 2; ++j) {
264      for (k = 0; k < 2; ++k) {
265        printf("Test configuration %s %s %s... ", desc(i), desc(j), desc(k));
266        test(self, is_fp(i), is_fp(j), is_fp(k));
267        printf("done\n");
268      }
269    }
270  }
271
272  TEST_END();
273
274  rtems_test_exit(0);
275}
276
277#define CONFIGURE_MICROSECONDS_PER_TICK 1000
278
279#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
280#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
281
282#define CONFIGURE_MAXIMUM_TASKS 4
283#define CONFIGURE_MAXIMUM_TIMERS 1
284
285#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
286
287#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
288
289#define CONFIGURE_INIT
290
291#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.