source: rtems/testsuites/sptests/spmutex01/init.c @ 9276fde

5
Last change on this file since 9276fde was 9276fde, checked in by Sebastian Huber <sebastian.huber@…>, on 05/11/16 at 15:52:13

score: Fix CORE mutex initialization

The priority inheritance and ceiling CORE mutexes wrongly used the FIFO
queueing discipline. Delete misleading _CORE_mutex_Is_priority(). Bug
introduced by 1e1a91ed11458ddbb27b94d0001d8f0fc2ef7a97.

Add test sptests/spmutex01, since no existing uni-processor test covered
the thread priority queueing discipline for CORE mutexes.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2015, 2016 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[] = "SPMUTEX 1";
22
23#define TASK_COUNT 5
24
25typedef enum {
26  REQ_WAKE_UP_MASTER = RTEMS_EVENT_0,
27  REQ_WAKE_UP_HELPER = RTEMS_EVENT_1,
28  REQ_MTX_OBTAIN = RTEMS_EVENT_2,
29  REQ_MTX_RELEASE = RTEMS_EVENT_3
30} request_id;
31
32typedef enum {
33  A_1,
34  A_2_0,
35  A_2_1,
36  M,
37  H,
38  NONE
39} task_id;
40
41typedef struct {
42  rtems_id mtx;
43  rtems_id tasks[TASK_COUNT];
44  int generation[TASK_COUNT];
45  int expected_generation[TASK_COUNT];
46} test_context;
47
48static test_context test_instance;
49
50static void start_task(
51  test_context *ctx,
52  task_id id,
53  rtems_task_entry entry,
54  rtems_task_priority prio
55)
56{
57  rtems_status_code sc;
58
59  sc = rtems_task_create(
60    rtems_build_name('T', 'A', 'S', 'K'),
61    prio,
62    RTEMS_MINIMUM_STACK_SIZE,
63    RTEMS_DEFAULT_MODES,
64    RTEMS_DEFAULT_ATTRIBUTES,
65    &ctx->tasks[id]
66  );
67  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
68
69  sc = rtems_task_start(ctx->tasks[id], entry, id);
70  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
71}
72
73static void send_event(test_context *ctx, task_id id, rtems_event_set events)
74{
75  rtems_status_code sc;
76
77  sc = rtems_event_send(ctx->tasks[id], events);
78  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
79}
80
81static rtems_event_set wait_for_events(void)
82{
83  rtems_event_set events;
84  rtems_status_code sc;
85
86  sc = rtems_event_receive(
87    RTEMS_ALL_EVENTS,
88    RTEMS_EVENT_ANY | RTEMS_WAIT,
89    RTEMS_NO_TIMEOUT,
90    &events
91  );
92  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
93
94  return events;
95}
96
97static void sync_with_helper(test_context *ctx)
98{
99  rtems_event_set events;
100
101  send_event(ctx, H, REQ_WAKE_UP_HELPER);
102  events = wait_for_events();
103  rtems_test_assert(events == REQ_WAKE_UP_MASTER);
104}
105
106static void request(test_context *ctx, task_id id, request_id req)
107{
108  send_event(ctx, id, req);
109  sync_with_helper(ctx);
110}
111
112static void obtain(test_context *ctx)
113{
114  rtems_status_code sc;
115
116  sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
117  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
118}
119
120static void release(test_context *ctx)
121{
122  rtems_status_code sc;
123
124  sc = rtems_semaphore_release(ctx->mtx);
125  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
126}
127
128static void check_generations(test_context *ctx, task_id a, task_id b)
129{
130  size_t i;
131
132  if (a != NONE) {
133    ++ctx->expected_generation[a];
134  }
135
136  if (b != NONE) {
137    ++ctx->expected_generation[b];
138  }
139
140  for (i = 0; i < TASK_COUNT; ++i) {
141    rtems_test_assert(ctx->generation[i] == ctx->expected_generation[i]);
142  }
143}
144
145static void assert_prio(
146  test_context *ctx,
147  task_id id,
148  rtems_task_priority expected
149)
150{
151  rtems_task_priority actual;
152  rtems_status_code sc;
153
154  sc = rtems_task_set_priority(
155    ctx->tasks[id],
156    RTEMS_CURRENT_PRIORITY,
157    &actual
158  );
159  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
160  rtems_test_assert(expected == actual);
161}
162
163static void helper(rtems_task_argument arg)
164{
165  test_context *ctx = &test_instance;
166
167  while (true) {
168    rtems_event_set events = wait_for_events();
169    rtems_test_assert(events == REQ_WAKE_UP_HELPER);
170    send_event(ctx, M, REQ_WAKE_UP_MASTER);
171  }
172}
173
174static void worker(rtems_task_argument arg)
175{
176  test_context *ctx = &test_instance;
177  task_id id = arg;
178
179  while (true) {
180    rtems_event_set events = wait_for_events();
181
182    if ((events & REQ_MTX_OBTAIN) != 0) {
183      obtain(ctx);
184      ++ctx->generation[id];
185    }
186
187    if ((events & REQ_MTX_RELEASE) != 0) {
188      release(ctx);
189      ++ctx->generation[id];
190    }
191  }
192}
193
194static void test(void)
195{
196  test_context *ctx = &test_instance;
197  rtems_status_code sc;
198
199  ctx->tasks[M] = rtems_task_self();
200  start_task(ctx, A_1, worker, 1);
201  start_task(ctx, A_2_0, worker, 2);
202  start_task(ctx, A_2_1, worker, 2);
203  start_task(ctx, H, helper, 3);
204
205  sc = rtems_semaphore_create(
206    rtems_build_name(' ', 'M', 'T', 'X'),
207    1,
208    RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
209    0,
210    &ctx->mtx
211  );
212  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
213
214  obtain(ctx);
215  request(ctx, A_1, REQ_MTX_OBTAIN);
216  check_generations(ctx, NONE, NONE);
217  assert_prio(ctx, M, 1);
218  release(ctx);
219  check_generations(ctx, A_1, NONE);
220  assert_prio(ctx, M, 3);
221  request(ctx, A_1, REQ_MTX_RELEASE);
222  check_generations(ctx, A_1, NONE);
223
224  obtain(ctx);
225  request(ctx, A_2_0, REQ_MTX_OBTAIN);
226  request(ctx, A_1, REQ_MTX_OBTAIN);
227  request(ctx, A_2_1, REQ_MTX_OBTAIN);
228  check_generations(ctx, NONE, NONE);
229  assert_prio(ctx, M, 1);
230  release(ctx);
231  check_generations(ctx, A_1, NONE);
232  assert_prio(ctx, M, 3);
233  assert_prio(ctx, A_1, 1);
234  request(ctx, A_1, REQ_MTX_RELEASE);
235  check_generations(ctx, A_1, A_2_0);
236  request(ctx, A_2_0, REQ_MTX_RELEASE);
237  check_generations(ctx, A_2_0, A_2_1);
238  request(ctx, A_2_1, REQ_MTX_RELEASE);
239  check_generations(ctx, A_2_1, NONE);
240}
241
242static void Init(rtems_task_argument arg)
243{
244  TEST_BEGIN();
245
246  test();
247
248  TEST_END();
249  rtems_test_exit(0);
250}
251
252#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
253#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
254
255#define CONFIGURE_MAXIMUM_TASKS TASK_COUNT
256
257#define CONFIGURE_MAXIMUM_SEMAPHORES 1
258
259#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
260
261#define CONFIGURE_INIT_TASK_PRIORITY 3
262
263#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
264
265#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
266
267#define CONFIGURE_INIT
268
269#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.