source: rtems/testsuites/smptests/smpmutex01/init.c @ 0446f680

5
Last change on this file since 0446f680 was 0446f680, checked in by Marçal Comajoan Cara <mcomajoancara@…>, on 12/03/18 at 20:37:32

Spelling and grammar fixes in source code comments (GCI 2018)

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