source: rtems/testsuites/smptests/smpmutex01/init.c @ 98c6d50

5
Last change on this file since 98c6d50 was 98c6d50, checked in by Chris Johns <chrisj@…>, on 10/19/17 at 05:39:16

testsuite: Use printk for all test output where possible.

  • Remove the printf support leaving the direct printk support configured with TESTS_USE_PRINTK and all other output goes via a buffered vsniprintf call to printk.
  • Control the test's single init for functions and global data with TEST_INIT and not CONFIGURE_INIT. They are now separate.

Updates #3170.

  • Property mode set to 100644
File size: 24.9 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#define TEST_INIT
20
21#include "tmacros.h"
22
23const char rtems_test_name[] = "SMPMUTEX 1";
24
25#define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
26
27#define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
28
29#define PART_COUNT 2
30
31#define TASK_COUNT 9
32
33#define PRIO_NONE 0
34
35/* Value choosen for Qemu, 2 would be sufficient for real targets */
36#define TIMEOUT_IN_TICKS 10
37
38typedef enum {
39  REQ_WAKE_UP_MASTER = RTEMS_EVENT_0,
40  REQ_WAKE_UP_HELPER = RTEMS_EVENT_1,
41  REQ_MTX_OBTAIN = RTEMS_EVENT_2,
42  REQ_MTX_OBTAIN_TIMEOUT = RTEMS_EVENT_3,
43  REQ_MTX_RELEASE = RTEMS_EVENT_4,
44  REQ_MTX_2_OBTAIN = RTEMS_EVENT_5,
45  REQ_MTX_2_RELEASE = RTEMS_EVENT_6,
46  REQ_SEM_OBTAIN_RELEASE = RTEMS_EVENT_7,
47  REQ_SEM_RELEASE = RTEMS_EVENT_8,
48  REQ_SET_DONE = RTEMS_EVENT_9,
49  REQ_WAIT_FOR_DONE = RTEMS_EVENT_10,
50  REQ_SEND_EVENT_2 = RTEMS_EVENT_11,
51  REQ_SEND_EVENT_3 = RTEMS_EVENT_12
52} request_id;
53
54typedef enum {
55  A_1,
56  A_2_0,
57  A_2_1,
58  M,
59  B_4,
60  B_5_0,
61  B_5_1,
62  H_A,
63  H_B,
64  NONE
65} task_id;
66
67typedef struct {
68  rtems_id mtx;
69  rtems_id mtx_2;
70  rtems_id sem;
71  rtems_id tasks[TASK_COUNT];
72  Atomic_Uint done;
73  task_id id_2;
74  rtems_event_set events_2;
75  task_id id_3;
76  rtems_event_set events_3;
77  int generation[TASK_COUNT];
78  int expected_generation[TASK_COUNT];
79} test_context;
80
81static test_context test_instance;
82
83static void assert_cpu(uint32_t expected_cpu)
84{
85  rtems_test_assert(rtems_get_current_processor() == expected_cpu);
86}
87
88static void test_task_get_priority_not_defined(test_context *ctx)
89{
90  rtems_status_code sc;
91  rtems_id scheduler_id;
92  rtems_task_priority priority;
93
94  sc = rtems_scheduler_ident(SCHED_B, &scheduler_id);
95  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
96
97  priority = 0;
98  sc = rtems_task_get_priority(RTEMS_SELF, scheduler_id, &priority);
99  rtems_test_assert(sc == RTEMS_NOT_DEFINED);
100  rtems_test_assert(priority == 0);
101}
102
103static void start_task(
104  test_context *ctx,
105  task_id id,
106  rtems_task_entry entry,
107  rtems_task_priority prio,
108  rtems_name scheduler
109)
110{
111  rtems_status_code sc;
112  rtems_id scheduler_id;
113
114  sc = rtems_task_create(
115    rtems_build_name('T', 'A', 'S', 'K'),
116    prio,
117    RTEMS_MINIMUM_STACK_SIZE,
118    RTEMS_DEFAULT_MODES,
119    RTEMS_DEFAULT_ATTRIBUTES,
120    &ctx->tasks[id]
121  );
122  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
123
124  sc = rtems_scheduler_ident(scheduler, &scheduler_id);
125  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
126
127  sc = rtems_task_set_scheduler(ctx->tasks[id], scheduler_id, prio);
128  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
129
130  sc = rtems_task_start(ctx->tasks[id], entry, id);
131  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
132}
133
134static void send_event(test_context *ctx, task_id id, rtems_event_set events)
135{
136  rtems_status_code sc;
137
138  sc = rtems_event_send(ctx->tasks[id], events);
139  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
140}
141
142static void set_event_2(
143  test_context *ctx,
144  task_id id_2,
145  rtems_event_set events_2
146)
147{
148  ctx->id_2 = id_2;
149  ctx->events_2 = events_2;
150}
151
152static void set_event_3(
153  test_context *ctx,
154  task_id id_3,
155  rtems_event_set events_3
156)
157{
158  ctx->id_3 = id_3;
159  ctx->events_3 = events_3;
160}
161
162static void clear_done(test_context *ctx)
163{
164  _Atomic_Store_uint(&ctx->done, 0, ATOMIC_ORDER_RELAXED);
165}
166
167static void set_done(test_context *ctx)
168{
169  _Atomic_Store_uint(&ctx->done, 1, ATOMIC_ORDER_RELEASE);
170}
171
172static bool is_done(test_context *ctx)
173{
174  return _Atomic_Load_uint(&ctx->done, ATOMIC_ORDER_ACQUIRE) != 0;
175}
176
177static void wait_for_done(test_context *ctx)
178{
179  while (!is_done(ctx)) {
180    /* Wait */
181  }
182}
183
184static void request_pre_emption(test_context *ctx, task_id id)
185{
186  clear_done(ctx);
187  send_event(ctx, id, REQ_SET_DONE);
188  wait_for_done(ctx);
189}
190
191static rtems_event_set wait_for_events(void)
192{
193  rtems_event_set events;
194  rtems_status_code sc;
195
196  sc = rtems_event_receive(
197    RTEMS_ALL_EVENTS,
198    RTEMS_EVENT_ANY | RTEMS_WAIT,
199    RTEMS_NO_TIMEOUT,
200    &events
201  );
202  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
203
204  return events;
205}
206
207static void sync_with_helper_by_id(test_context *ctx, task_id id)
208{
209  rtems_event_set events;
210
211  send_event(ctx, id, REQ_WAKE_UP_HELPER);
212  events = wait_for_events();
213  rtems_test_assert(events == REQ_WAKE_UP_MASTER);
214}
215
216static void sync_with_helper(test_context *ctx)
217{
218  sync_with_helper_by_id(ctx, H_A);
219  sync_with_helper_by_id(ctx, H_B);
220}
221
222static void request(test_context *ctx, task_id id, request_id req)
223{
224  send_event(ctx, id, req);
225  clear_done(ctx);
226
227  if (rtems_get_current_processor() == 0) {
228    id = H_B;
229  } else {
230    id = H_A;
231  }
232
233  send_event(ctx, id, REQ_SET_DONE);
234  wait_for_done(ctx);
235}
236
237static void obtain(test_context *ctx)
238{
239  rtems_status_code sc;
240
241  sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
242  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
243}
244
245static void obtain_timeout(test_context *ctx)
246{
247  rtems_status_code sc;
248
249  sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, TIMEOUT_IN_TICKS);
250  rtems_test_assert(sc == RTEMS_TIMEOUT);
251}
252
253static void release(test_context *ctx)
254{
255  rtems_status_code sc;
256
257  sc = rtems_semaphore_release(ctx->mtx);
258  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
259}
260
261static void obtain_2(test_context *ctx)
262{
263  rtems_status_code sc;
264
265  sc = rtems_semaphore_obtain(ctx->mtx_2, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
266  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
267}
268
269static void release_2(test_context *ctx)
270{
271  rtems_status_code sc;
272
273  sc = rtems_semaphore_release(ctx->mtx_2);
274  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
275}
276
277static void sem_obtain(test_context *ctx)
278{
279  rtems_status_code sc;
280
281  sc = rtems_semaphore_obtain(ctx->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
282  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
283}
284
285static void sem_release(test_context *ctx)
286{
287  rtems_status_code sc;
288
289  sc = rtems_semaphore_release(ctx->sem);
290  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
291}
292
293static void wait(void)
294{
295  rtems_status_code sc;
296
297  sc = rtems_task_wake_after(TIMEOUT_IN_TICKS + 1);
298  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
299}
300
301static void check_generations(test_context *ctx, task_id a, task_id b)
302{
303  size_t i;
304
305  if (a != NONE) {
306    ++ctx->expected_generation[a];
307  }
308
309  if (b != NONE) {
310    ++ctx->expected_generation[b];
311  }
312
313  for (i = 0; i < TASK_COUNT; ++i) {
314    rtems_test_assert(ctx->generation[i] == ctx->expected_generation[i]);
315  }
316}
317
318static void yield(void)
319{
320  rtems_status_code sc;
321
322  sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
323  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
324}
325
326static void set_prio(test_context *ctx, task_id id, rtems_task_priority prio)
327{
328  rtems_status_code sc;
329
330  sc = rtems_task_set_priority(ctx->tasks[id], prio, &prio);
331  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
332}
333
334static void assert_prio(
335  test_context *ctx,
336  task_id id,
337  rtems_task_priority expected
338)
339{
340  rtems_task_priority actual;
341  rtems_status_code sc;
342
343  sc = rtems_task_set_priority(
344    ctx->tasks[id],
345    RTEMS_CURRENT_PRIORITY,
346    &actual
347  );
348  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
349  rtems_test_assert(expected == actual);
350}
351
352static void assert_prio_by_scheduler(
353  test_context *ctx,
354  task_id id,
355  rtems_name scheduler,
356  rtems_task_priority expected
357)
358{
359  rtems_task_priority actual;
360  rtems_status_code sc;
361  rtems_id scheduler_id;
362
363  sc = rtems_scheduler_ident(scheduler, &scheduler_id);
364  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
365
366  actual = PRIO_NONE;
367  sc = rtems_task_get_priority(
368    ctx->tasks[id],
369    scheduler_id,
370    &actual
371  );
372
373  if (expected == PRIO_NONE) {
374    rtems_test_assert(sc == RTEMS_NOT_DEFINED);
375  } else {
376    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
377  }
378
379  rtems_test_assert(actual == expected);
380}
381
382static void helper(rtems_task_argument arg)
383{
384  test_context *ctx = &test_instance;
385
386  while (true) {
387    rtems_event_set events = wait_for_events();
388
389    if ((events & REQ_WAKE_UP_HELPER) != 0) {
390      send_event(ctx, M, REQ_WAKE_UP_MASTER);
391    }
392
393    if ((events & REQ_SEM_RELEASE) != 0) {
394      sem_release(ctx);
395    }
396
397    if ((events & REQ_SET_DONE) != 0) {
398      set_done(ctx);
399    }
400  }
401}
402
403static void worker(rtems_task_argument arg)
404{
405  test_context *ctx = &test_instance;
406  task_id id = arg;
407
408  while (true) {
409    rtems_event_set events = wait_for_events();
410
411    if ((events & REQ_MTX_OBTAIN) != 0) {
412      obtain(ctx);
413      ++ctx->generation[id];
414    }
415
416    if ((events & REQ_MTX_OBTAIN_TIMEOUT) != 0) {
417      obtain_timeout(ctx);
418      ++ctx->generation[id];
419    }
420
421    if ((events & REQ_MTX_RELEASE) != 0) {
422      release(ctx);
423      ++ctx->generation[id];
424    }
425
426    if ((events & REQ_MTX_2_OBTAIN) != 0) {
427      obtain_2(ctx);
428      ++ctx->generation[id];
429    }
430
431    if ((events & REQ_MTX_2_RELEASE) != 0) {
432      release_2(ctx);
433      ++ctx->generation[id];
434    }
435
436    if ((events & REQ_SEM_OBTAIN_RELEASE) != 0) {
437      sem_obtain(ctx);
438      ++ctx->generation[id];
439      sem_release(ctx);
440    }
441
442    if ((events & REQ_SEND_EVENT_2) != 0) {
443      send_event(ctx, ctx->id_2, ctx->events_2);
444    }
445
446    if ((events & REQ_SEND_EVENT_3) != 0) {
447      send_event(ctx, ctx->id_3, ctx->events_3);
448    }
449
450    if ((events & REQ_SET_DONE) != 0) {
451      set_done(ctx);
452    }
453
454    if ((events & REQ_WAIT_FOR_DONE) != 0) {
455      wait_for_done(ctx);
456    }
457  }
458}
459
460static void test_init(test_context *ctx)
461{
462  rtems_status_code sc;
463
464  ctx->tasks[M] = rtems_task_self();
465  start_task(ctx, A_1, worker, 1, SCHED_A);
466  start_task(ctx, A_2_0, worker, 2, SCHED_A);
467  start_task(ctx, A_2_1, worker, 2, SCHED_A);
468  start_task(ctx, B_4, worker, 4, SCHED_B);
469  start_task(ctx, B_5_0, worker, 5, SCHED_B);
470  start_task(ctx, B_5_1, worker, 5, SCHED_B);
471  start_task(ctx, H_A, helper, 3, SCHED_A);
472  start_task(ctx, H_B, helper, 6, SCHED_B);
473
474  sc = rtems_semaphore_create(
475    rtems_build_name('M', 'T', 'X', '1'),
476    1,
477    RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
478    0,
479    &ctx->mtx
480  );
481  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
482
483  sc = rtems_semaphore_create(
484    rtems_build_name('M', 'T', 'X', '2'),
485    1,
486    RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
487    0,
488    &ctx->mtx_2
489  );
490  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
491
492  sc = rtems_semaphore_create(
493    rtems_build_name(' ', 'S', 'E', 'M'),
494    0,
495    RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY,
496    0,
497    &ctx->sem
498  );
499  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
500}
501
502static void test_simple_inheritance(test_context *ctx)
503{
504  obtain(ctx);
505  request(ctx, A_1, REQ_MTX_OBTAIN);
506  check_generations(ctx, NONE, NONE);
507  assert_prio(ctx, M, 1);
508  release(ctx);
509  check_generations(ctx, A_1, NONE);
510  assert_prio(ctx, M, 3);
511  request(ctx, A_1, REQ_MTX_RELEASE);
512  check_generations(ctx, A_1, NONE);
513}
514
515static void test_dequeue_order_one_scheduler_instance(test_context *ctx)
516{
517  obtain(ctx);
518  request(ctx, A_2_0, REQ_MTX_OBTAIN);
519  request(ctx, A_1, REQ_MTX_OBTAIN);
520  request(ctx, A_2_1, REQ_MTX_OBTAIN);
521  check_generations(ctx, NONE, NONE);
522  assert_prio(ctx, M, 1);
523  release(ctx);
524  check_generations(ctx, A_1, NONE);
525  assert_prio(ctx, M, 3);
526  assert_prio(ctx, A_1, 1);
527  request(ctx, A_1, REQ_MTX_RELEASE);
528  check_generations(ctx, A_1, A_2_0);
529  request(ctx, A_2_0, REQ_MTX_RELEASE);
530  check_generations(ctx, A_2_0, A_2_1);
531  request(ctx, A_2_1, REQ_MTX_RELEASE);
532  check_generations(ctx, A_2_1, NONE);
533}
534
535static void test_mixed_queue_two_scheduler_instances(test_context *ctx)
536{
537  obtain(ctx);
538  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
539  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
540
541  request(ctx, B_4, REQ_MTX_OBTAIN_TIMEOUT);
542  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
543  assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
544  check_generations(ctx, NONE, NONE);
545  wait();
546  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
547  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
548  check_generations(ctx, B_4, NONE);
549
550  request(ctx, B_4, REQ_MTX_OBTAIN);
551  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
552  assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
553  check_generations(ctx, NONE, NONE);
554
555  request(ctx, B_5_0, REQ_SEM_OBTAIN_RELEASE);
556  send_event(ctx, H_A, REQ_SEM_RELEASE);
557  check_generations(ctx, NONE, NONE);
558
559  /*
560   * We are in scheduler instance A.  Task B_5_0 of scheduler instance B issued
561   * the counting semaphore obtain before us.  However, we inherited the
562   * priority of B_4, so we get the semaphore before B_5_0 (priority order
563   * within scheduler instance B).
564   */
565  sem_obtain(ctx);
566  check_generations(ctx, NONE, NONE);
567
568  release(ctx);
569  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
570  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
571  sync_with_helper(ctx);
572  check_generations(ctx, B_4, NONE);
573
574  request(ctx, B_4, REQ_MTX_RELEASE);
575  check_generations(ctx, B_4, NONE);
576
577  sem_release(ctx);
578  sync_with_helper(ctx);
579  check_generations(ctx, B_5_0, NONE);
580
581  sem_obtain(ctx);
582}
583
584static void test_mixed_queue_two_scheduler_instances_sem_only(test_context *ctx)
585{
586  request(ctx, B_5_0, REQ_SEM_OBTAIN_RELEASE);
587  send_event(ctx, H_A, REQ_SEM_RELEASE);
588  check_generations(ctx, NONE, NONE);
589
590  /*
591   * We are in scheduler instance A.  Task B_5_0 of scheduler instance B issued
592   * the counting semaphore obtain before us.  No priority inheritance is
593   * involved, so task B_5_0 gets the counting semaphore first.
594   */
595  sem_obtain(ctx);
596  check_generations(ctx, B_5_0, NONE);
597
598  sem_release(ctx);
599}
600
601static void test_simple_inheritance_two_scheduler_instances(test_context *ctx)
602{
603  obtain(ctx);
604  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
605  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
606
607  request(ctx, B_5_0, REQ_MTX_OBTAIN);
608  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
609  assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
610
611  request(ctx, B_4, REQ_MTX_OBTAIN);
612  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
613  assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
614
615  request(ctx, B_5_1, REQ_MTX_OBTAIN);
616  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
617  assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
618  check_generations(ctx, NONE, NONE);
619
620  release(ctx);
621  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
622  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
623  sync_with_helper(ctx);
624  check_generations(ctx, B_4, NONE);
625
626  request(ctx, B_4, REQ_MTX_RELEASE);
627  check_generations(ctx, B_4, B_5_0);
628
629  request(ctx, B_5_0, REQ_MTX_RELEASE);
630  check_generations(ctx, B_5_0, B_5_1);
631
632  request(ctx, B_5_1, REQ_MTX_RELEASE);
633  check_generations(ctx, B_5_1, NONE);
634}
635
636static void test_nested_inheritance_two_scheduler_instances(test_context *ctx)
637{
638  obtain_2(ctx);
639  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
640  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
641
642  request(ctx, B_5_0, REQ_MTX_OBTAIN);
643  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
644  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
645  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
646  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
647  check_generations(ctx, B_5_0, NONE);
648
649  request(ctx, B_5_0, REQ_MTX_2_OBTAIN);
650  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
651  assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
652  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
653  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
654
655  request(ctx, B_4, REQ_MTX_OBTAIN_TIMEOUT);
656  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
657  assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
658  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
659  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 4);
660  wait();
661  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
662  assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
663  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
664  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
665  check_generations(ctx, B_4, NONE);
666
667  request(ctx, B_4, REQ_MTX_OBTAIN);
668  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
669  assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
670  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
671  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 4);
672
673  request(ctx, B_5_1, REQ_MTX_2_OBTAIN);
674  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
675  assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
676  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
677  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 4);
678  check_generations(ctx, NONE, NONE);
679
680  release_2(ctx);
681  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
682  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
683  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
684  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 4);
685  sync_with_helper(ctx);
686  check_generations(ctx, B_5_0, NONE);
687
688  request(ctx, B_5_0, REQ_MTX_RELEASE);
689  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
690  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
691  check_generations(ctx, B_4, B_5_0);
692
693  request(ctx, B_4, REQ_MTX_RELEASE);
694  check_generations(ctx, B_4, NONE);
695
696  request(ctx, B_5_0, REQ_MTX_2_RELEASE);
697  check_generations(ctx, B_5_0, B_5_1);
698
699  request(ctx, B_5_1, REQ_MTX_2_RELEASE);
700  check_generations(ctx, B_5_1, NONE);
701}
702
703static void test_dequeue_order_two_scheduler_instances(test_context *ctx)
704{
705  obtain(ctx);
706  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
707  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
708
709  request(ctx, A_2_0, REQ_MTX_OBTAIN);
710  assert_prio_by_scheduler(ctx, M, SCHED_A, 2);
711  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
712  check_generations(ctx, NONE, NONE);
713
714  request(ctx, B_5_0, REQ_MTX_OBTAIN);
715  assert_prio_by_scheduler(ctx, M, SCHED_A, 2);
716  assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
717  check_generations(ctx, NONE, NONE);
718
719  request(ctx, B_5_1, REQ_MTX_OBTAIN);
720  assert_prio_by_scheduler(ctx, M, SCHED_A, 2);
721  assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
722
723  request(ctx, B_4, REQ_MTX_OBTAIN);
724  assert_prio_by_scheduler(ctx, M, SCHED_A, 2);
725  assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
726
727  request(ctx, A_2_1, REQ_MTX_OBTAIN);
728  assert_prio_by_scheduler(ctx, M, SCHED_A, 2);
729  assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
730
731  request(ctx, A_1, REQ_MTX_OBTAIN);
732  assert_prio_by_scheduler(ctx, M, SCHED_A, 1);
733  assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
734  check_generations(ctx, NONE, NONE);
735
736  release(ctx);
737  sync_with_helper(ctx);
738  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
739  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
740  assert_prio_by_scheduler(ctx, A_1, SCHED_A, 1);
741  assert_prio_by_scheduler(ctx, A_1, SCHED_B, 4);
742  check_generations(ctx, A_1, NONE);
743
744  request(ctx, A_1, REQ_MTX_RELEASE);
745  assert_prio_by_scheduler(ctx, A_1, SCHED_A, 1);
746  assert_prio_by_scheduler(ctx, A_1, SCHED_B, PRIO_NONE);
747  assert_prio_by_scheduler(ctx, B_4, SCHED_A, 2);
748  assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
749  check_generations(ctx, A_1, B_4);
750
751  request(ctx, B_4, REQ_MTX_RELEASE);
752  assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
753  assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
754  assert_prio_by_scheduler(ctx, A_2_0, SCHED_A, 2);
755  assert_prio_by_scheduler(ctx, A_2_0, SCHED_B, 5);
756  check_generations(ctx, B_4, A_2_0);
757
758  request(ctx, A_2_0, REQ_MTX_RELEASE);
759  assert_prio_by_scheduler(ctx, A_2_0, SCHED_A, 2);
760  assert_prio_by_scheduler(ctx, A_2_0, SCHED_B, PRIO_NONE);
761  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, 2);
762  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
763  check_generations(ctx, A_2_0, B_5_0);
764
765  request(ctx, B_5_0, REQ_MTX_RELEASE);
766  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
767  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
768  assert_prio_by_scheduler(ctx, A_2_1, SCHED_A, 2);
769  assert_prio_by_scheduler(ctx, A_2_1, SCHED_B, 5);
770  check_generations(ctx, B_5_0, A_2_1);
771
772  request(ctx, A_2_1, REQ_MTX_RELEASE);
773  assert_prio_by_scheduler(ctx, A_2_1, SCHED_A, 2);
774  assert_prio_by_scheduler(ctx, A_2_1, SCHED_B, PRIO_NONE);
775  assert_prio_by_scheduler(ctx, B_5_1, SCHED_A, PRIO_NONE);
776  assert_prio_by_scheduler(ctx, B_5_1, SCHED_B, 5);
777  check_generations(ctx, A_2_1, B_5_1);
778
779  request(ctx, B_5_1, REQ_MTX_RELEASE);
780  assert_prio_by_scheduler(ctx, B_5_1, SCHED_A, PRIO_NONE);
781  assert_prio_by_scheduler(ctx, B_5_1, SCHED_B, 5);
782  check_generations(ctx, B_5_1, NONE);
783}
784
785static void test_omip_pre_emption(test_context *ctx)
786{
787  assert_cpu(0);
788  obtain(ctx);
789  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
790  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
791
792  request(ctx, B_5_0, REQ_MTX_OBTAIN);
793  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
794  assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
795  check_generations(ctx, NONE, NONE);
796
797  request_pre_emption(ctx, A_1);
798  assert_cpu(1);
799
800  request_pre_emption(ctx, B_4);
801  assert_cpu(0);
802
803  request_pre_emption(ctx, A_1);
804  assert_cpu(1);
805
806  release(ctx);
807  assert_cpu(0);
808  sync_with_helper(ctx);
809  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
810  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
811  check_generations(ctx, B_5_0, NONE);
812
813  request(ctx, B_5_0, REQ_MTX_RELEASE);
814  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
815  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
816  check_generations(ctx, B_5_0, NONE);
817}
818
819static void test_omip_rescue(test_context *ctx)
820{
821  assert_cpu(0);
822  obtain(ctx);
823  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
824  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
825
826  clear_done(ctx);
827  set_event_3(ctx, H_B, REQ_SET_DONE);
828  set_event_2(ctx, B_5_0, REQ_SEND_EVENT_3 | REQ_MTX_OBTAIN);
829  send_event(ctx, A_1, REQ_SEND_EVENT_2 | REQ_WAIT_FOR_DONE);
830  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
831  assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
832  assert_cpu(1);
833
834  release(ctx);
835  assert_cpu(0);
836  sync_with_helper(ctx);
837  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
838  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
839  check_generations(ctx, B_5_0, NONE);
840
841  request(ctx, B_5_0, REQ_MTX_RELEASE);
842  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
843  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
844  check_generations(ctx, B_5_0, NONE);
845}
846
847static void test_omip_timeout(test_context *ctx)
848{
849  assert_cpu(0);
850  obtain(ctx);
851  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
852  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
853
854  clear_done(ctx);
855  set_event_3(ctx, H_B, REQ_SET_DONE);
856  set_event_2(ctx, B_5_0, REQ_SEND_EVENT_3 | REQ_MTX_OBTAIN_TIMEOUT);
857  send_event(ctx, A_1, REQ_SEND_EVENT_2 | REQ_WAIT_FOR_DONE);
858  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
859  assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
860  assert_cpu(1);
861
862  wait();
863  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
864  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
865  check_generations(ctx, B_5_0, NONE);
866  assert_cpu(0);
867
868  release(ctx);
869}
870
871static void test_omip_yield(test_context *ctx)
872{
873  assert_cpu(0);
874  obtain(ctx);
875  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
876  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
877
878  request(ctx, B_5_0, REQ_MTX_OBTAIN);
879  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
880  assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
881  check_generations(ctx, NONE, NONE);
882
883  clear_done(ctx);
884  send_event(ctx, H_A, REQ_SET_DONE);
885  yield();
886  assert_cpu(1);
887  wait_for_done(ctx);
888
889  clear_done(ctx);
890  send_event(ctx, H_B, REQ_SET_DONE);
891  set_prio(ctx, H_B, 5);
892  yield();
893  assert_cpu(1);
894  rtems_test_assert(!is_done(ctx));
895
896  set_prio(ctx, H_B, 4);
897  assert_cpu(0);
898
899  wait_for_done(ctx);
900  set_prio(ctx, H_B, 6);
901
902  release(ctx);
903  sync_with_helper(ctx);
904  assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
905  assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
906  check_generations(ctx, B_5_0, NONE);
907
908  request(ctx, B_5_0, REQ_MTX_RELEASE);
909  assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
910  assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
911  check_generations(ctx, B_5_0, NONE);
912}
913
914static void test(void)
915{
916  test_context *ctx = &test_instance;
917
918  test_init(ctx);
919  test_task_get_priority_not_defined(ctx);
920  test_simple_inheritance(ctx);
921  test_dequeue_order_one_scheduler_instance(ctx);
922  test_mixed_queue_two_scheduler_instances(ctx);
923  test_mixed_queue_two_scheduler_instances_sem_only(ctx);
924  test_simple_inheritance_two_scheduler_instances(ctx);
925  test_nested_inheritance_two_scheduler_instances(ctx);
926  test_dequeue_order_two_scheduler_instances(ctx);
927  test_omip_pre_emption(ctx);
928  test_omip_rescue(ctx);
929  test_omip_timeout(ctx);
930  test_omip_yield(ctx);
931}
932
933static void Init(rtems_task_argument arg)
934{
935  TEST_BEGIN();
936
937  if (rtems_get_processor_count() >= PART_COUNT) {
938    test();
939  }
940
941  TEST_END();
942  rtems_test_exit(0);
943}
944
945#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
946#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
947
948#define CONFIGURE_MAXIMUM_PROCESSORS PART_COUNT
949
950#define CONFIGURE_SCHEDULER_SIMPLE_SMP
951
952#include <rtems/scheduler.h>
953
954RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(a);
955
956RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b);
957
958#define CONFIGURE_SCHEDULER_CONTROLS \
959  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(a, SCHED_A), \
960  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(b, SCHED_B)
961
962#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
963  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
964  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
965
966#define CONFIGURE_MAXIMUM_TASKS TASK_COUNT
967
968#define CONFIGURE_MAXIMUM_SEMAPHORES 3
969
970#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
971
972#define CONFIGURE_INIT_TASK_PRIORITY 3
973
974#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
975
976#define CONFIGURE_INIT
977
978#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.