source: rtems/testsuites/smptests/smpmrsp01/init.c @ ec5d95e1

5
Last change on this file since ec5d95e1 was ec5d95e1, checked in by Sebastian Huber <sebastian.huber@…>, on 06/23/16 at 08:31:04

smptests/smpmrsp01: Fix due to API changes

Commit 77ff5599e0d8e6d91190a379be21a332f83252b0 introduced a change in
the rtems_semaphore_create() behaviour for MrsP semaphores. The ceiling
priorities for all schedulers except the scheduler of the executing
thread are initialized to zero.

  • Property mode set to 100644
File size: 47.9 KB
Line 
1/*
2 * Copyright (c) 2014-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 <sys/param.h>
20
21#include <stdio.h>
22#include <inttypes.h>
23
24#include <rtems.h>
25#include <rtems/libcsupport.h>
26#include <rtems/score/schedulersmpimpl.h>
27#include <rtems/score/smpbarrier.h>
28#include <rtems/score/smplock.h>
29
30#define TESTS_USE_PRINTK
31#include "tmacros.h"
32
33const char rtems_test_name[] = "SMPMRSP 1";
34
35#define CPU_COUNT 32
36
37#define MRSP_COUNT 32
38
39#define SWITCH_EVENT_COUNT 32
40
41typedef struct {
42  uint32_t sleep;
43  uint32_t timeout;
44  uint32_t obtain[MRSP_COUNT];
45  uint32_t cpu[CPU_COUNT];
46} counter;
47
48typedef struct {
49  uint32_t cpu_index;
50  const Thread_Control *executing;
51  const Thread_Control *heir;
52  const Thread_Control *heir_node;
53  Priority_Control heir_priority;
54} switch_event;
55
56typedef struct {
57  rtems_id main_task_id;
58  rtems_id migration_task_id;
59  rtems_id low_task_id[2];
60  rtems_id high_task_id[2];
61  rtems_id timer_id;
62  rtems_id counting_sem_id;
63  rtems_id mrsp_ids[MRSP_COUNT];
64  rtems_id scheduler_ids[CPU_COUNT];
65  rtems_id worker_ids[2 * CPU_COUNT];
66  volatile bool stop_worker[2 * CPU_COUNT];
67  counter counters[2 * CPU_COUNT];
68  uint32_t migration_counters[CPU_COUNT];
69  Thread_Control *worker_task;
70  SMP_barrier_Control barrier;
71  SMP_lock_Control switch_lock;
72  size_t switch_index;
73  switch_event switch_events[32];
74  volatile bool high_run[2];
75  volatile bool low_run[2];
76} test_context;
77
78static test_context test_instance = {
79  .switch_lock = SMP_LOCK_INITIALIZER("test instance switch lock")
80};
81
82static void busy_wait(void)
83{
84  rtems_interval later = rtems_clock_tick_later(2);
85
86  while (rtems_clock_tick_before(later)) {
87    /* Wait */
88  }
89}
90
91static void barrier_init(test_context *ctx)
92{
93  _SMP_barrier_Control_initialize(&ctx->barrier);
94}
95
96static void barrier(test_context *ctx, SMP_barrier_State *bs)
97{
98  _SMP_barrier_Wait(&ctx->barrier, bs, 2);
99}
100
101static void barrier_and_delay(test_context *ctx, SMP_barrier_State *bs)
102{
103  barrier(ctx, bs);
104  busy_wait();
105}
106
107static rtems_task_priority get_prio(rtems_id task_id)
108{
109  rtems_status_code sc;
110  rtems_task_priority prio;
111
112  sc = rtems_task_set_priority(task_id, RTEMS_CURRENT_PRIORITY, &prio);
113  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
114
115  return prio;
116}
117
118static void wait_for_prio(rtems_id task_id, rtems_task_priority prio)
119{
120  while (get_prio(task_id) != prio) {
121    /* Wait */
122  }
123}
124
125static void assert_prio(rtems_id task_id, rtems_task_priority expected_prio)
126{
127  rtems_test_assert(get_prio(task_id) == expected_prio);
128}
129
130static void change_prio(rtems_id task_id, rtems_task_priority prio)
131{
132  rtems_status_code sc;
133
134  sc = rtems_task_set_priority(task_id, prio, &prio);
135  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
136}
137
138static void assert_executing_worker(test_context *ctx)
139{
140  rtems_test_assert(
141    _CPU_Context_Get_is_executing(&ctx->worker_task->Registers)
142  );
143}
144
145static void switch_extension(Thread_Control *executing, Thread_Control *heir)
146{
147  test_context *ctx = &test_instance;
148  SMP_lock_Context lock_context;
149  size_t i;
150
151  _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
152
153  i = ctx->switch_index;
154  if (i < SWITCH_EVENT_COUNT) {
155    switch_event *e = &ctx->switch_events[i];
156    Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node(heir);
157
158    e->cpu_index = rtems_get_current_processor();
159    e->executing = executing;
160    e->heir = heir;
161    e->heir_node = _Scheduler_Node_get_owner(&node->Base);
162    e->heir_priority = node->priority;
163
164    ctx->switch_index = i + 1;
165  }
166
167  _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
168}
169
170static void reset_switch_events(test_context *ctx)
171{
172  SMP_lock_Context lock_context;
173
174  _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
175  ctx->switch_index = 0;
176  _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
177}
178
179static size_t get_switch_events(test_context *ctx)
180{
181  SMP_lock_Context lock_context;
182  size_t events;
183
184  _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
185  events = ctx->switch_index;
186  _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
187
188  return events;
189}
190
191static void print_switch_events(test_context *ctx)
192{
193  size_t n = get_switch_events(ctx);
194  size_t i;
195
196  for (i = 0; i < n; ++i) {
197    switch_event *e = &ctx->switch_events[i];
198    char ex[5];
199    char hr[5];
200    char hn[5];
201
202    rtems_object_get_name(e->executing->Object.id, sizeof(ex), &ex[0]);
203    rtems_object_get_name(e->heir->Object.id, sizeof(hr), &hr[0]);
204    rtems_object_get_name(e->heir_node->Object.id, sizeof(hn), &hn[0]);
205
206    printf(
207      "[%" PRIu32 "] %4s -> %4s (prio %3" PRIu32 ", node %4s)\n",
208      e->cpu_index,
209      &ex[0],
210      &hr[0],
211      e->heir_priority,
212      &hn[0]
213    );
214  }
215}
216
217static void create_mrsp_sema(
218  test_context *ctx,
219  rtems_id *id,
220  rtems_task_priority prio
221)
222{
223  uint32_t cpu_count = rtems_get_processor_count();
224  uint32_t index;
225  rtems_status_code sc;
226
227  sc = rtems_semaphore_create(
228    rtems_build_name('M', 'R', 'S', 'P'),
229    1,
230    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
231      | RTEMS_BINARY_SEMAPHORE,
232    prio,
233    id
234  );
235  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
236
237  for (index = 1; index < cpu_count; index = ((index + 2) & ~UINT32_C(1))) {
238    rtems_task_priority old_prio;
239
240    old_prio = 1;
241    sc = rtems_semaphore_set_priority(
242      *id,
243      ctx->scheduler_ids[index],
244      prio,
245      &old_prio
246    );
247    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
248    rtems_test_assert(old_prio == 0);
249  }
250}
251
252static void run_task(rtems_task_argument arg)
253{
254  volatile bool *run = (volatile bool *) arg;
255
256  *run = true;
257
258  while (true) {
259    /* Do nothing */
260  }
261}
262
263static void obtain_and_release_worker(rtems_task_argument arg)
264{
265  test_context *ctx = &test_instance;
266  rtems_status_code sc;
267  SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
268
269  ctx->worker_task = _Thread_Get_executing();
270
271  assert_prio(RTEMS_SELF, 4);
272
273  /* Obtain with timeout (A) */
274  barrier(ctx, &barrier_state);
275
276  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
277  rtems_test_assert(sc == RTEMS_TIMEOUT);
278
279  assert_prio(RTEMS_SELF, 4);
280
281  /* Obtain with priority change and timeout (B) */
282  barrier(ctx, &barrier_state);
283
284  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
285  rtems_test_assert(sc == RTEMS_TIMEOUT);
286
287  assert_prio(RTEMS_SELF, 2);
288
289  /* Restore priority (C) */
290  barrier(ctx, &barrier_state);
291
292  /* Obtain without timeout (D) */
293  barrier(ctx, &barrier_state);
294
295  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
296  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
297
298  assert_prio(RTEMS_SELF, 3);
299
300  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
301  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
302
303  assert_prio(RTEMS_SELF, 4);
304
305  /* Obtain and help with timeout (E) */
306  barrier(ctx, &barrier_state);
307
308  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
309  rtems_test_assert(sc == RTEMS_TIMEOUT);
310
311  assert_prio(RTEMS_SELF, 4);
312
313  sc = rtems_task_suspend(ctx->high_task_id[0]);
314  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
315
316  /* Worker done (H) */
317  barrier(ctx, &barrier_state);
318
319  while (true) {
320    /* Wait for termination */
321  }
322}
323
324static void test_mrsp_obtain_and_release(test_context *ctx)
325{
326  rtems_status_code sc;
327  rtems_task_priority prio;
328  rtems_id scheduler_id;
329  SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
330
331  puts("test MrsP obtain and release");
332
333  change_prio(RTEMS_SELF, 3);
334
335  barrier_init(ctx);
336  reset_switch_events(ctx);
337
338  ctx->high_run[0] = false;
339
340  sc = rtems_task_create(
341    rtems_build_name('H', 'I', 'G', '0'),
342    1,
343    RTEMS_MINIMUM_STACK_SIZE,
344    RTEMS_DEFAULT_MODES,
345    RTEMS_DEFAULT_ATTRIBUTES,
346    &ctx->high_task_id[0]
347  );
348  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
349
350  /* Check executing task parameters */
351
352  sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
353  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
354
355  rtems_test_assert(ctx->scheduler_ids[0] == scheduler_id);
356
357  /* Create a MrsP semaphore object and lock it */
358
359  create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 2);
360
361  assert_prio(RTEMS_SELF, 3);
362
363  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
364  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
365
366  assert_prio(RTEMS_SELF, 2);
367
368  /*
369   * The ceiling priority values per scheduler are equal to the value specified
370   * for object creation.
371   */
372
373  prio = RTEMS_CURRENT_PRIORITY;
374  sc = rtems_semaphore_set_priority(
375    ctx->mrsp_ids[0],
376    ctx->scheduler_ids[0],
377    prio,
378    &prio
379  );
380  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
381  rtems_test_assert(prio == 2);
382
383  /* Check the old value and set a new ceiling priority for scheduler B */
384
385  prio = 3;
386  sc = rtems_semaphore_set_priority(
387    ctx->mrsp_ids[0],
388    ctx->scheduler_ids[1],
389    prio,
390    &prio
391  );
392  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
393  rtems_test_assert(prio == 2);
394
395  /* Check the ceiling priority values */
396
397  prio = RTEMS_CURRENT_PRIORITY;
398  sc = rtems_semaphore_set_priority(
399    ctx->mrsp_ids[0],
400    ctx->scheduler_ids[0],
401    prio,
402    &prio
403  );
404  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
405  rtems_test_assert(prio == 2);
406
407  prio = RTEMS_CURRENT_PRIORITY;
408  sc = rtems_semaphore_set_priority(
409    ctx->mrsp_ids[0],
410    ctx->scheduler_ids[1],
411    prio,
412    &prio
413  );
414  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
415  rtems_test_assert(prio == 3);
416
417  /* Check that a thread waiting to get ownership remains executing */
418
419  sc = rtems_task_create(
420    rtems_build_name('W', 'O', 'R', 'K'),
421    4,
422    RTEMS_MINIMUM_STACK_SIZE,
423    RTEMS_DEFAULT_MODES,
424    RTEMS_DEFAULT_ATTRIBUTES,
425    &ctx->worker_ids[0]
426  );
427  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
428
429  sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1]);
430  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
431
432  sc = rtems_task_start(ctx->worker_ids[0], obtain_and_release_worker, 0);
433  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
434
435  /* Obtain with timeout (A) */
436  barrier_and_delay(ctx, &barrier_state);
437
438  assert_prio(ctx->worker_ids[0], 3);
439  assert_executing_worker(ctx);
440
441  /* Obtain with priority change and timeout (B) */
442  barrier_and_delay(ctx, &barrier_state);
443
444  assert_prio(ctx->worker_ids[0], 3);
445  change_prio(ctx->worker_ids[0], 2);
446  assert_executing_worker(ctx);
447
448  /* Restore priority (C) */
449  barrier(ctx, &barrier_state);
450
451  assert_prio(ctx->worker_ids[0], 2);
452  change_prio(ctx->worker_ids[0], 4);
453
454  /* Obtain without timeout (D) */
455  barrier_and_delay(ctx, &barrier_state);
456
457  assert_prio(ctx->worker_ids[0], 3);
458  assert_executing_worker(ctx);
459
460  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
461  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
462
463  /* Check that a timeout works in case the waiting thread actually helps */
464
465  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
466  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
467
468  /* Obtain and help with timeout (E) */
469  barrier_and_delay(ctx, &barrier_state);
470
471  sc = rtems_task_start(
472    ctx->high_task_id[0],
473    run_task,
474    (rtems_task_argument) &ctx->high_run[0]
475  );
476  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
477
478  rtems_test_assert(rtems_get_current_processor() == 1);
479
480  while (rtems_get_current_processor() != 0) {
481    /* Wait */
482  }
483
484  rtems_test_assert(ctx->high_run[0]);
485
486  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
487  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
488
489  print_switch_events(ctx);
490
491  /* Worker done (H) */
492  barrier(ctx, &barrier_state);
493
494  sc = rtems_task_delete(ctx->worker_ids[0]);
495  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
496
497  sc = rtems_task_delete(ctx->high_task_id[0]);
498  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
499
500  sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
501  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
502}
503
504static void obtain_after_migration_worker(rtems_task_argument arg)
505{
506  test_context *ctx = &test_instance;
507  rtems_status_code sc;
508  SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
509
510  assert_prio(RTEMS_SELF, 3);
511
512  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
513  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
514
515  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
516  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
517
518  /* Worker done (K) */
519  barrier(ctx, &barrier_state);
520
521  while (true) {
522    /* Wait for termination */
523  }
524}
525
526static void obtain_after_migration_high(rtems_task_argument arg)
527{
528  test_context *ctx = &test_instance;
529  rtems_status_code sc;
530  SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
531
532  assert_prio(RTEMS_SELF, 2);
533
534  sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
535  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
536
537  /* Obtain done (I) */
538  barrier(ctx, &barrier_state);
539
540  /* Ready to release (J) */
541  barrier(ctx, &barrier_state);
542
543  sc = rtems_semaphore_release(ctx->mrsp_ids[1]);
544  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
545
546  rtems_task_suspend(RTEMS_SELF);
547  rtems_test_assert(0);
548}
549
550static void test_mrsp_obtain_after_migration(test_context *ctx)
551{
552  rtems_status_code sc;
553  rtems_task_priority prio;
554  rtems_id scheduler_id;
555  SMP_barrier_State barrier_state;
556
557  puts("test MrsP obtain after migration");
558
559  change_prio(RTEMS_SELF, 3);
560
561  barrier_init(ctx);
562  reset_switch_events(ctx);
563
564  /* Create tasks */
565
566  sc = rtems_task_create(
567    rtems_build_name('H', 'I', 'G', '0'),
568    2,
569    RTEMS_MINIMUM_STACK_SIZE,
570    RTEMS_DEFAULT_MODES,
571    RTEMS_DEFAULT_ATTRIBUTES,
572    &ctx->high_task_id[0]
573  );
574  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
575
576  sc = rtems_task_create(
577    rtems_build_name('W', 'O', 'R', 'K'),
578    3,
579    RTEMS_MINIMUM_STACK_SIZE,
580    RTEMS_DEFAULT_MODES,
581    RTEMS_DEFAULT_ATTRIBUTES,
582    &ctx->worker_ids[0]
583  );
584  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
585
586  sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1]);
587  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
588
589  /* Create a MrsP semaphore objects */
590
591  create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 3);
592  create_mrsp_sema(ctx, &ctx->mrsp_ids[1], 2);
593  create_mrsp_sema(ctx, &ctx->mrsp_ids[2], 1);
594
595  prio = 4;
596  sc = rtems_semaphore_set_priority(
597    ctx->mrsp_ids[2],
598    ctx->scheduler_ids[1],
599    prio,
600    &prio
601  );
602  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
603  rtems_test_assert(prio == 1);
604
605  /* Check executing task parameters */
606
607  sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
608  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
609
610  rtems_test_assert(ctx->scheduler_ids[0] == scheduler_id);
611
612  assert_prio(RTEMS_SELF, 3);
613
614  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
615  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
616
617  assert_prio(RTEMS_SELF, 3);
618
619  /* Start other tasks */
620
621  sc = rtems_task_start(ctx->worker_ids[0], obtain_after_migration_worker, 0);
622  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
623
624  sc = rtems_task_start(ctx->high_task_id[0], obtain_after_migration_high, 0);
625  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
626
627  rtems_test_assert(rtems_get_current_processor() == 1);
628
629  /* Obtain done (I) */
630  _SMP_barrier_State_initialize(&barrier_state);
631  barrier(ctx, &barrier_state);
632
633  sc = rtems_task_suspend(ctx->high_task_id[0]);
634  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
635
636  rtems_test_assert(rtems_get_current_processor() == 1);
637
638  /*
639   * Obtain second MrsP semaphore and ensure that we change the priority of our
640   * own scheduler node and not the one we are currently using.
641   */
642
643  sc = rtems_semaphore_obtain(ctx->mrsp_ids[2], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
644  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
645
646  assert_prio(RTEMS_SELF, 1);
647
648  rtems_test_assert(rtems_get_current_processor() == 1);
649
650  sc = rtems_semaphore_release(ctx->mrsp_ids[2]);
651  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
652
653  sc = rtems_task_resume(ctx->high_task_id[0]);
654  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
655
656  /* Ready to release (J) */
657  barrier(ctx, &barrier_state);
658
659  rtems_test_assert(rtems_get_current_processor() == 1);
660
661  /* Prepare barrier for worker */
662  barrier_init(ctx);
663  _SMP_barrier_State_initialize(&barrier_state);
664
665  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
666  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
667
668  rtems_test_assert(rtems_get_current_processor() == 0);
669
670  print_switch_events(ctx);
671
672  /* Worker done (K) */
673  barrier(ctx, &barrier_state);
674
675  sc = rtems_task_delete(ctx->worker_ids[0]);
676  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
677
678  sc = rtems_task_delete(ctx->high_task_id[0]);
679  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
680
681  sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
682  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
683
684  sc = rtems_semaphore_delete(ctx->mrsp_ids[1]);
685  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
686
687  sc = rtems_semaphore_delete(ctx->mrsp_ids[2]);
688  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
689}
690
691static void test_mrsp_flush_error(test_context *ctx)
692{
693  rtems_status_code sc;
694  rtems_id id;
695
696  puts("test MrsP flush error");
697
698  create_mrsp_sema(ctx, &id, 1);
699
700  sc = rtems_semaphore_flush(id);
701  rtems_test_assert(sc == RTEMS_NOT_DEFINED);
702
703  sc = rtems_semaphore_delete(id);
704  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
705}
706
707static void test_mrsp_initially_locked_error(void)
708{
709  rtems_status_code sc;
710  rtems_id id;
711
712  puts("test MrsP initially locked error");
713
714  sc = rtems_semaphore_create(
715    rtems_build_name('M', 'R', 'S', 'P'),
716    0,
717    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
718      | RTEMS_BINARY_SEMAPHORE,
719    1,
720    &id
721  );
722  rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
723}
724
725static void test_mrsp_nested_obtain_error(test_context *ctx)
726{
727  rtems_status_code sc;
728  rtems_id id;
729
730  puts("test MrsP nested obtain error");
731
732  create_mrsp_sema(ctx, &id, 1);
733
734  sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
735  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
736
737  sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
738  rtems_test_assert(sc == RTEMS_UNSATISFIED);
739
740  sc = rtems_semaphore_release(id);
741  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
742
743  sc = rtems_semaphore_delete(id);
744  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
745}
746
747static void test_mrsp_unlock_order_error(test_context *ctx)
748{
749  rtems_status_code sc;
750  rtems_id id_a;
751  rtems_id id_b;
752
753  puts("test MrsP unlock order error");
754
755  create_mrsp_sema(ctx, &id_a, 1);
756  create_mrsp_sema(ctx, &id_b, 1);
757
758  sc = rtems_semaphore_obtain(id_a, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
759  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
760
761  sc = rtems_semaphore_obtain(id_b, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
762  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
763
764  sc = rtems_semaphore_release(id_a);
765  rtems_test_assert(sc == RTEMS_INCORRECT_STATE);
766
767  sc = rtems_semaphore_release(id_b);
768  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
769
770  sc = rtems_semaphore_release(id_a);
771  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
772
773  sc = rtems_semaphore_delete(id_a);
774  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
775
776  sc = rtems_semaphore_delete(id_b);
777  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
778}
779
780static void deadlock_worker(rtems_task_argument arg)
781{
782  test_context *ctx = &test_instance;
783  rtems_status_code sc;
784
785  sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
786  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
787
788  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
789  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
790
791  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
792  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
793
794  sc = rtems_semaphore_release(ctx->mrsp_ids[1]);
795  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
796
797  sc = rtems_event_transient_send(ctx->main_task_id);
798  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
799
800  rtems_task_suspend(RTEMS_SELF);
801  rtems_test_assert(0);
802}
803
804static void test_mrsp_deadlock_error(test_context *ctx)
805{
806  rtems_status_code sc;
807  rtems_task_priority prio = 2;
808
809  puts("test MrsP deadlock error");
810
811  change_prio(RTEMS_SELF, prio);
812
813  create_mrsp_sema(ctx, &ctx->mrsp_ids[0], prio);
814  create_mrsp_sema(ctx, &ctx->mrsp_ids[1], prio);
815
816  sc = rtems_task_create(
817    rtems_build_name('W', 'O', 'R', 'K'),
818    prio,
819    RTEMS_MINIMUM_STACK_SIZE,
820    RTEMS_DEFAULT_MODES,
821    RTEMS_DEFAULT_ATTRIBUTES,
822    &ctx->worker_ids[0]
823  );
824  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
825
826  sc = rtems_task_start(ctx->worker_ids[0], deadlock_worker, 0);
827  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
828
829  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
830  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
831
832  sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
833  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
834
835  sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
836  rtems_test_assert(sc == RTEMS_UNSATISFIED);
837
838  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
839  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
840
841  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
842  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
843
844  sc = rtems_task_delete(ctx->worker_ids[0]);
845  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
846
847  sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
848  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
849
850  sc = rtems_semaphore_delete(ctx->mrsp_ids[1]);
851  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
852}
853
854static void test_mrsp_multiple_obtain(test_context *ctx)
855{
856  rtems_status_code sc;
857  rtems_id sem_a_id;
858  rtems_id sem_b_id;
859  rtems_id sem_c_id;
860
861  puts("test MrsP multiple obtain");
862
863  change_prio(RTEMS_SELF, 4);
864
865  create_mrsp_sema(ctx, &sem_a_id, 3);
866  create_mrsp_sema(ctx, &sem_b_id, 2);
867  create_mrsp_sema(ctx, &sem_c_id, 1);
868
869  assert_prio(RTEMS_SELF, 4);
870
871  sc = rtems_semaphore_obtain(sem_a_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
872  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
873
874  assert_prio(RTEMS_SELF, 3);
875
876  sc = rtems_semaphore_obtain(sem_b_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
877  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
878
879  assert_prio(RTEMS_SELF, 2);
880
881  sc = rtems_semaphore_obtain(sem_c_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
882  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
883
884  assert_prio(RTEMS_SELF, 1);
885
886  sc = rtems_semaphore_release(sem_c_id);
887  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
888
889  assert_prio(RTEMS_SELF, 2);
890
891  sc = rtems_semaphore_release(sem_b_id);
892  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
893
894  assert_prio(RTEMS_SELF, 3);
895
896  sc = rtems_semaphore_release(sem_a_id);
897  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
898
899  assert_prio(RTEMS_SELF, 4);
900
901  sc = rtems_semaphore_obtain(sem_a_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
902  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
903
904  assert_prio(RTEMS_SELF, 3);
905
906  sc = rtems_semaphore_obtain(sem_b_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
907  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
908
909  assert_prio(RTEMS_SELF, 2);
910
911  sc = rtems_semaphore_obtain(sem_c_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
912  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
913
914  assert_prio(RTEMS_SELF, 1);
915  change_prio(RTEMS_SELF, 3);
916  assert_prio(RTEMS_SELF, 1);
917
918  sc = rtems_semaphore_release(sem_c_id);
919  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
920
921  assert_prio(RTEMS_SELF, 2);
922
923  sc = rtems_semaphore_release(sem_b_id);
924  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
925
926  assert_prio(RTEMS_SELF, 3);
927
928  sc = rtems_semaphore_release(sem_a_id);
929  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
930
931  assert_prio(RTEMS_SELF, 3);
932
933  sc = rtems_semaphore_delete(sem_a_id);
934  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
935
936  sc = rtems_semaphore_delete(sem_b_id);
937  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
938
939  sc = rtems_semaphore_delete(sem_c_id);
940  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
941}
942
943static void ready_unlock_worker(rtems_task_argument arg)
944{
945  test_context *ctx = &test_instance;
946  rtems_status_code sc;
947  SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
948
949  assert_prio(RTEMS_SELF, 4);
950
951  /* Obtain (F) */
952  barrier(ctx, &barrier_state);
953
954  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
955  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
956
957  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
958  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
959
960  assert_prio(RTEMS_SELF, 4);
961
962  /* Done (G) */
963  barrier(ctx, &barrier_state);
964
965  while (true) {
966    /* Do nothing */
967  }
968}
969
970static void unblock_ready_timer(rtems_id timer_id, void *arg)
971{
972  test_context *ctx = arg;
973  rtems_status_code sc;
974
975  sc = rtems_task_start(
976    ctx->high_task_id[0],
977    run_task,
978    (rtems_task_argument) &ctx->high_run[0]
979  );
980  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
981
982  sc = rtems_task_suspend(ctx->high_task_id[0]);
983  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
984
985  sc = rtems_task_resume(ctx->high_task_id[0]);
986  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
987
988  /*
989   * At this point the scheduler node of the main thread is in the
990   * SCHEDULER_SMP_NODE_READY state and a _Scheduler_SMP_Unblock() operation is
991   * performed.
992   */
993  sc = rtems_event_transient_send(ctx->main_task_id);
994  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
995
996  sc = rtems_task_suspend(ctx->high_task_id[0]);
997  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
998}
999
1000static void unblock_ready_owner(test_context *ctx)
1001{
1002  rtems_status_code sc;
1003
1004  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1005  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1006
1007  assert_prio(RTEMS_SELF, 3);
1008
1009  sc = rtems_timer_fire_after(ctx->timer_id, 2, unblock_ready_timer, ctx);
1010  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1011
1012  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1013  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1014
1015  rtems_test_assert(!ctx->high_run[0]);
1016}
1017
1018static void unblock_owner_before_rival_timer(rtems_id timer_id, void *arg)
1019{
1020  test_context *ctx = arg;
1021  rtems_status_code sc;
1022
1023  sc = rtems_task_suspend(ctx->high_task_id[0]);
1024  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1025
1026  sc = rtems_task_suspend(ctx->high_task_id[1]);
1027  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1028}
1029
1030static void unblock_owner_after_rival_timer(rtems_id timer_id, void *arg)
1031{
1032  test_context *ctx = arg;
1033  rtems_status_code sc;
1034
1035  sc = rtems_task_suspend(ctx->high_task_id[1]);
1036  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1037
1038  sc = rtems_task_suspend(ctx->high_task_id[0]);
1039  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1040}
1041
1042static void various_block_unblock(test_context *ctx)
1043{
1044  rtems_status_code sc;
1045  SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
1046
1047  /* Worker obtain (F) */
1048  barrier_and_delay(ctx, &barrier_state);
1049
1050  sc = rtems_task_suspend(ctx->worker_ids[0]);
1051  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1052
1053  busy_wait();
1054
1055  sc = rtems_task_start(
1056    ctx->high_task_id[1],
1057    run_task,
1058    (rtems_task_argument) &ctx->high_run[1]
1059  );
1060  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1061
1062  while (!ctx->high_run[1]) {
1063    /* Do noting */
1064  }
1065
1066  sc = rtems_task_resume(ctx->worker_ids[0]);
1067  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1068
1069  /* Try to schedule a blocked active rival */
1070
1071  sc = rtems_task_suspend(ctx->worker_ids[0]);
1072  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1073
1074  sc = rtems_task_suspend(ctx->high_task_id[1]);
1075  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1076
1077  sc = rtems_task_resume(ctx->high_task_id[1]);
1078  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1079
1080  sc = rtems_task_resume(ctx->worker_ids[0]);
1081  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1082
1083  rtems_test_assert(rtems_get_current_processor() == 0);
1084
1085  /* Use node of the active rival */
1086
1087  sc = rtems_task_suspend(ctx->high_task_id[1]);
1088  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1089
1090  sc = rtems_task_resume(ctx->high_task_id[0]);
1091  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1092
1093  rtems_test_assert(rtems_get_current_processor() == 1);
1094
1095  sc = rtems_task_suspend(ctx->worker_ids[0]);
1096  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1097
1098  sc = rtems_task_resume(ctx->worker_ids[0]);
1099  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1100
1101  /*
1102   * Try to schedule an active rival with an already scheduled active owner
1103   * user.
1104   */
1105
1106  sc = rtems_timer_fire_after(
1107    ctx->timer_id,
1108    2,
1109    unblock_owner_before_rival_timer,
1110    ctx
1111  );
1112  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1113
1114  /* This will take the processor away from us, the timer will help later */
1115  sc = rtems_task_resume(ctx->high_task_id[1]);
1116  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1117
1118  /*
1119   * Try to schedule an active owner with an already scheduled active rival
1120   * user.
1121   */
1122
1123  sc = rtems_task_resume(ctx->high_task_id[0]);
1124  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1125
1126  sc = rtems_timer_fire_after(
1127    ctx->timer_id,
1128    2,
1129    unblock_owner_after_rival_timer,
1130    ctx
1131  );
1132  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1133
1134  /* This will take the processor away from us, the timer will help later */
1135  sc = rtems_task_resume(ctx->high_task_id[1]);
1136  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1137
1138  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1139  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1140
1141  rtems_test_assert(rtems_get_current_processor() == 0);
1142
1143  assert_prio(RTEMS_SELF, 4);
1144
1145  /* Worker done (G) */
1146  barrier(ctx, &barrier_state);
1147}
1148
1149static void start_low_task(test_context *ctx, size_t i)
1150{
1151  rtems_status_code sc;
1152
1153  sc = rtems_task_create(
1154    rtems_build_name('L', 'O', 'W', '0' + i),
1155    5,
1156    RTEMS_MINIMUM_STACK_SIZE,
1157    RTEMS_DEFAULT_MODES,
1158    RTEMS_DEFAULT_ATTRIBUTES,
1159    &ctx->low_task_id[i]
1160  );
1161  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1162
1163  sc = rtems_task_set_scheduler(ctx->low_task_id[i], ctx->scheduler_ids[i]);
1164  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1165
1166  sc = rtems_task_start(
1167    ctx->low_task_id[i],
1168    run_task,
1169    (rtems_task_argument) &ctx->low_run[i]
1170  );
1171  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1172}
1173
1174static void test_mrsp_various_block_and_unblock(test_context *ctx)
1175{
1176  rtems_status_code sc;
1177
1178  puts("test MrsP various block and unblock");
1179
1180  change_prio(RTEMS_SELF, 4);
1181
1182  barrier_init(ctx);
1183  reset_switch_events(ctx);
1184
1185  ctx->low_run[0] = false;
1186  ctx->low_run[1] = false;
1187  ctx->high_run[0] = false;
1188  ctx->high_run[1] = false;
1189
1190  create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 3);
1191  assert_prio(RTEMS_SELF, 4);
1192
1193  sc = rtems_task_create(
1194    rtems_build_name('H', 'I', 'G', '0'),
1195    2,
1196    RTEMS_MINIMUM_STACK_SIZE,
1197    RTEMS_DEFAULT_MODES,
1198    RTEMS_DEFAULT_ATTRIBUTES,
1199    &ctx->high_task_id[0]
1200  );
1201  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1202
1203  sc = rtems_task_create(
1204    rtems_build_name('H', 'I', 'G', '1'),
1205    2,
1206    RTEMS_MINIMUM_STACK_SIZE,
1207    RTEMS_DEFAULT_MODES,
1208    RTEMS_DEFAULT_ATTRIBUTES,
1209    &ctx->high_task_id[1]
1210  );
1211  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1212
1213  sc = rtems_task_set_scheduler(ctx->high_task_id[1], ctx->scheduler_ids[1]);
1214  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1215
1216  sc = rtems_task_create(
1217    rtems_build_name('W', 'O', 'R', 'K'),
1218    4,
1219    RTEMS_MINIMUM_STACK_SIZE,
1220    RTEMS_DEFAULT_MODES,
1221    RTEMS_DEFAULT_ATTRIBUTES,
1222    &ctx->worker_ids[0]
1223  );
1224  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1225
1226  sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1]);
1227  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1228
1229  sc = rtems_task_start(ctx->worker_ids[0], ready_unlock_worker, 0);
1230  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1231
1232  sc = rtems_timer_create(
1233    rtems_build_name('T', 'I', 'M', 'R'),
1234    &ctx->timer_id
1235  );
1236  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1237
1238  /* In case these tasks run, then we have a MrsP protocol violation */
1239  start_low_task(ctx, 0);
1240  start_low_task(ctx, 1);
1241
1242  unblock_ready_owner(ctx);
1243  various_block_unblock(ctx);
1244
1245  rtems_test_assert(!ctx->low_run[0]);
1246  rtems_test_assert(!ctx->low_run[1]);
1247
1248  print_switch_events(ctx);
1249
1250  sc = rtems_timer_delete(ctx->timer_id);
1251  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1252
1253  sc = rtems_task_delete(ctx->high_task_id[0]);
1254  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1255
1256  sc = rtems_task_delete(ctx->high_task_id[1]);
1257  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1258
1259  sc = rtems_task_delete(ctx->worker_ids[0]);
1260  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1261
1262  sc = rtems_task_delete(ctx->low_task_id[0]);
1263  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1264
1265  sc = rtems_task_delete(ctx->low_task_id[1]);
1266  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1267
1268  sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
1269  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1270}
1271
1272static void test_mrsp_obtain_and_sleep_and_release(test_context *ctx)
1273{
1274  rtems_status_code sc;
1275  rtems_id sem_id;
1276  rtems_id run_task_id;
1277  volatile bool run = false;
1278
1279  puts("test MrsP obtain and sleep and release");
1280
1281  change_prio(RTEMS_SELF, 1);
1282
1283  reset_switch_events(ctx);
1284
1285  sc = rtems_task_create(
1286    rtems_build_name(' ', 'R', 'U', 'N'),
1287    2,
1288    RTEMS_MINIMUM_STACK_SIZE,
1289    RTEMS_DEFAULT_MODES,
1290    RTEMS_DEFAULT_ATTRIBUTES,
1291    &run_task_id
1292  );
1293  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1294
1295  sc = rtems_task_start(run_task_id, run_task, (rtems_task_argument) &run);
1296  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1297
1298  create_mrsp_sema(ctx, &sem_id, 1);
1299
1300  rtems_test_assert(!run);
1301
1302  sc = rtems_task_wake_after(2);
1303  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1304
1305  rtems_test_assert(run);
1306  run = false;
1307
1308  sc = rtems_semaphore_obtain(sem_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1309  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1310
1311  rtems_test_assert(!run);
1312
1313  sc = rtems_task_wake_after(2);
1314  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1315
1316  rtems_test_assert(!run);
1317
1318  sc = rtems_semaphore_release(sem_id);
1319  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1320
1321  print_switch_events(ctx);
1322
1323  sc = rtems_semaphore_delete(sem_id);
1324  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1325
1326  sc = rtems_task_delete(run_task_id);
1327  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1328}
1329
1330static void help_task(rtems_task_argument arg)
1331{
1332  test_context *ctx = &test_instance;
1333  rtems_status_code sc;
1334
1335  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1336  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1337
1338  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1339  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1340
1341  while (true) {
1342    /* Do nothing */
1343  }
1344}
1345
1346static void test_mrsp_obtain_and_release_with_help(test_context *ctx)
1347{
1348  rtems_status_code sc;
1349  rtems_id help_task_id;
1350  rtems_id run_task_id;
1351  volatile bool run = false;
1352
1353  puts("test MrsP obtain and release with help");
1354
1355  change_prio(RTEMS_SELF, 3);
1356
1357  reset_switch_events(ctx);
1358
1359  create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 2);
1360
1361  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1362  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1363
1364  assert_prio(RTEMS_SELF, 2);
1365
1366  sc = rtems_task_create(
1367    rtems_build_name('H', 'E', 'L', 'P'),
1368    3,
1369    RTEMS_MINIMUM_STACK_SIZE,
1370    RTEMS_DEFAULT_MODES,
1371    RTEMS_DEFAULT_ATTRIBUTES,
1372    &help_task_id
1373  );
1374  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1375
1376  sc = rtems_task_set_scheduler(
1377    help_task_id,
1378    ctx->scheduler_ids[1]
1379  );
1380  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1381
1382  sc = rtems_task_start(help_task_id, help_task, 0);
1383  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1384
1385  sc = rtems_task_create(
1386    rtems_build_name(' ', 'R', 'U', 'N'),
1387    4,
1388    RTEMS_MINIMUM_STACK_SIZE,
1389    RTEMS_DEFAULT_MODES,
1390    RTEMS_DEFAULT_ATTRIBUTES,
1391    &run_task_id
1392  );
1393  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1394
1395  sc = rtems_task_start(run_task_id, run_task, (rtems_task_argument) &run);
1396  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1397
1398  wait_for_prio(help_task_id, 2);
1399
1400  sc = rtems_task_wake_after(2);
1401  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1402
1403  rtems_test_assert(rtems_get_current_processor() == 0);
1404  rtems_test_assert(!run);
1405
1406  change_prio(run_task_id, 1);
1407
1408  rtems_test_assert(rtems_get_current_processor() == 1);
1409
1410  while (!run) {
1411    /* Wait */
1412  }
1413
1414  sc = rtems_task_wake_after(2);
1415  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1416
1417  rtems_test_assert(rtems_get_current_processor() == 1);
1418
1419  change_prio(run_task_id, 4);
1420
1421  rtems_test_assert(rtems_get_current_processor() == 1);
1422
1423  sc = rtems_task_wake_after(2);
1424  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1425
1426  rtems_test_assert(rtems_get_current_processor() == 1);
1427
1428  /*
1429   * With this operation the scheduler instance 0 has now only the main and the
1430   * idle threads in the ready set.
1431   */
1432  sc = rtems_task_suspend(run_task_id);
1433  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1434
1435  rtems_test_assert(rtems_get_current_processor() == 1);
1436
1437  change_prio(RTEMS_SELF, 1);
1438  change_prio(RTEMS_SELF, 3);
1439
1440  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1441  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1442
1443  rtems_test_assert(rtems_get_current_processor() == 0);
1444
1445  assert_prio(RTEMS_SELF, 3);
1446
1447  wait_for_prio(help_task_id, 3);
1448
1449  print_switch_events(ctx);
1450
1451  sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
1452  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1453
1454  sc = rtems_task_delete(help_task_id);
1455  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1456
1457  sc = rtems_task_delete(run_task_id);
1458  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1459}
1460
1461static uint32_t simple_random(uint32_t v)
1462{
1463  v *= 1664525;
1464  v += 1013904223;
1465
1466  return v;
1467}
1468
1469static rtems_interval timeout(uint32_t v)
1470{
1471  return (v >> 23) % 4;
1472}
1473
1474static void load_worker(rtems_task_argument index)
1475{
1476  test_context *ctx = &test_instance;
1477  rtems_status_code sc;
1478  uint32_t v = index;
1479
1480  while (!ctx->stop_worker[index]) {
1481    uint32_t i = (v >> 13) % MRSP_COUNT;
1482
1483    assert_prio(RTEMS_SELF, 3 + CPU_COUNT + index);
1484
1485    if ((v >> 7) % 1024 == 0) {
1486      /* Give some time to the lower priority tasks */
1487
1488      ++ctx->counters[index].sleep;
1489
1490      sc = rtems_task_wake_after(1);
1491      rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1492
1493      ++ctx->counters[index].cpu[rtems_get_current_processor()];
1494    } else {
1495      uint32_t n = (v >> 17) % (i + 1);
1496      uint32_t s;
1497      uint32_t t;
1498
1499      /* Nested obtain */
1500      for (s = 0; s <= n; ++s) {
1501        uint32_t k = i - s;
1502
1503        sc = rtems_semaphore_obtain(ctx->mrsp_ids[k], RTEMS_WAIT, timeout(v));
1504        if (sc == RTEMS_SUCCESSFUL) {
1505          ++ctx->counters[index].obtain[n];
1506
1507          assert_prio(RTEMS_SELF, 3 + k);
1508        } else {
1509          rtems_test_assert(sc == RTEMS_TIMEOUT);
1510
1511          ++ctx->counters[index].timeout;
1512
1513          break;
1514        }
1515
1516        ++ctx->counters[index].cpu[rtems_get_current_processor()];
1517
1518        v = simple_random(v);
1519      }
1520
1521      /* Release in reverse obtain order */
1522      for (t = 0; t < s; ++t) {
1523        uint32_t k = i + t - s + 1;
1524
1525        sc = rtems_semaphore_release(ctx->mrsp_ids[k]);
1526        rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1527
1528        ++ctx->counters[index].cpu[rtems_get_current_processor()];
1529      }
1530    }
1531
1532    v = simple_random(v);
1533  }
1534
1535  sc = rtems_semaphore_release(ctx->counting_sem_id);
1536  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1537
1538  rtems_task_suspend(RTEMS_SELF);
1539  rtems_test_assert(0);
1540}
1541
1542static void migration_task(rtems_task_argument arg)
1543{
1544  test_context *ctx = &test_instance;
1545  rtems_status_code sc;
1546  uint32_t cpu_count = rtems_get_processor_count();
1547  uint32_t v = 0xdeadbeef;
1548
1549  while (true) {
1550    uint32_t cpu_index = (v >> 5) % cpu_count;
1551
1552    sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->scheduler_ids[cpu_index]);
1553    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1554
1555    ++ctx->migration_counters[rtems_get_current_processor()];
1556
1557    v = simple_random(v);
1558  }
1559}
1560
1561static void test_mrsp_load(test_context *ctx)
1562{
1563  rtems_status_code sc;
1564  uint32_t cpu_count = rtems_get_processor_count();
1565  uint32_t index;
1566
1567  puts("test MrsP load");
1568
1569  change_prio(RTEMS_SELF, 2);
1570
1571  sc = rtems_task_create(
1572    rtems_build_name('M', 'I', 'G', 'R'),
1573    2,
1574    RTEMS_MINIMUM_STACK_SIZE,
1575    RTEMS_DEFAULT_MODES,
1576    RTEMS_DEFAULT_ATTRIBUTES,
1577    &ctx->migration_task_id
1578  );
1579  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1580
1581  sc = rtems_task_start(ctx->migration_task_id, migration_task, 0);
1582  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1583
1584  sc = rtems_semaphore_create(
1585    rtems_build_name('S', 'Y', 'N', 'C'),
1586    0,
1587    RTEMS_COUNTING_SEMAPHORE,
1588    0,
1589    &ctx->counting_sem_id
1590  );
1591  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1592
1593  for (index = 0; index < MRSP_COUNT; ++index) {
1594    create_mrsp_sema(ctx, &ctx->mrsp_ids[index], 3 + index);
1595  }
1596
1597  for (index = 0; index < cpu_count; ++index) {
1598    uint32_t a = 2 * index;
1599    uint32_t b = a + 1;
1600
1601    sc = rtems_task_create(
1602      'A' + a,
1603      3 + MRSP_COUNT + a,
1604      RTEMS_MINIMUM_STACK_SIZE,
1605      RTEMS_DEFAULT_MODES,
1606      RTEMS_DEFAULT_ATTRIBUTES,
1607      &ctx->worker_ids[a]
1608    );
1609    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1610
1611    sc = rtems_task_set_scheduler(
1612      ctx->worker_ids[a],
1613      ctx->scheduler_ids[index]
1614    );
1615    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1616
1617    sc = rtems_task_start(
1618      ctx->worker_ids[a],
1619      load_worker,
1620      (rtems_task_argument) a
1621    );
1622    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1623
1624    sc = rtems_task_create(
1625      'A' + b,
1626      3 + MRSP_COUNT + b,
1627      RTEMS_MINIMUM_STACK_SIZE,
1628      RTEMS_DEFAULT_MODES,
1629      RTEMS_DEFAULT_ATTRIBUTES,
1630      &ctx->worker_ids[b]
1631    );
1632    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1633
1634    sc = rtems_task_set_scheduler(
1635      ctx->worker_ids[b],
1636      ctx->scheduler_ids[index]
1637    );
1638    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1639
1640    sc = rtems_task_start(
1641      ctx->worker_ids[b],
1642      load_worker,
1643      (rtems_task_argument) b
1644    );
1645    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1646  }
1647
1648  sc = rtems_task_wake_after(30 * rtems_clock_get_ticks_per_second());
1649  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1650
1651  for (index = 0; index < 2 * cpu_count; ++index) {
1652    ctx->stop_worker[index] = true;
1653  }
1654
1655  for (index = 0; index < 2 * cpu_count; ++index) {
1656    sc = rtems_semaphore_obtain(
1657      ctx->counting_sem_id,
1658      RTEMS_WAIT,
1659      RTEMS_NO_TIMEOUT
1660    );
1661    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1662  }
1663
1664  for (index = 0; index < 2 * cpu_count; ++index) {
1665    sc = rtems_task_delete(ctx->worker_ids[index]);
1666    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1667  }
1668
1669  for (index = 0; index < MRSP_COUNT; ++index) {
1670    sc = rtems_semaphore_delete(ctx->mrsp_ids[index]);
1671    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1672  }
1673
1674  sc = rtems_semaphore_delete(ctx->counting_sem_id);
1675  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1676
1677  sc = rtems_task_delete(ctx->migration_task_id);
1678  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1679
1680  for (index = 0; index < 2 * cpu_count; ++index) {
1681    uint32_t nest_level;
1682    uint32_t cpu_index;
1683
1684    printf(
1685      "worker[%" PRIu32 "]\n"
1686        "  sleep = %" PRIu32 "\n"
1687        "  timeout = %" PRIu32 "\n",
1688      index,
1689      ctx->counters[index].sleep,
1690      ctx->counters[index].timeout
1691    );
1692
1693    for (nest_level = 0; nest_level < MRSP_COUNT; ++nest_level) {
1694      printf(
1695        "  obtain[%" PRIu32 "] = %" PRIu32 "\n",
1696        nest_level,
1697        ctx->counters[index].obtain[nest_level]
1698      );
1699    }
1700
1701    for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
1702      printf(
1703        "  cpu[%" PRIu32 "] = %" PRIu32 "\n",
1704        cpu_index,
1705        ctx->counters[index].cpu[cpu_index]
1706      );
1707    }
1708  }
1709
1710  for (index = 0; index < cpu_count; ++index) {
1711    printf(
1712      "migrations[%" PRIu32 "] = %" PRIu32 "\n",
1713      index,
1714      ctx->migration_counters[index]
1715    );
1716  }
1717}
1718
1719static void Init(rtems_task_argument arg)
1720{
1721  test_context *ctx = &test_instance;
1722  rtems_status_code sc;
1723  rtems_resource_snapshot snapshot;
1724  uint32_t cpu_count = rtems_get_processor_count();
1725  uint32_t cpu_index;
1726
1727  TEST_BEGIN();
1728
1729  rtems_resource_snapshot_take(&snapshot);
1730
1731  ctx->main_task_id = rtems_task_self();
1732
1733  for (cpu_index = 0; cpu_index < MIN(2, cpu_count); ++cpu_index) {
1734    sc = rtems_scheduler_ident(cpu_index, &ctx->scheduler_ids[cpu_index]);
1735    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1736  }
1737
1738  for (cpu_index = 2; cpu_index < cpu_count; ++cpu_index) {
1739    sc = rtems_scheduler_ident(
1740      cpu_index / 2 + 1,
1741      &ctx->scheduler_ids[cpu_index]
1742    );
1743    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1744  }
1745
1746  test_mrsp_flush_error(ctx);
1747  test_mrsp_initially_locked_error();
1748  test_mrsp_nested_obtain_error(ctx);
1749  test_mrsp_unlock_order_error(ctx);
1750  test_mrsp_deadlock_error(ctx);
1751  test_mrsp_multiple_obtain(ctx);
1752
1753  if (cpu_count > 1) {
1754    test_mrsp_various_block_and_unblock(ctx);
1755    test_mrsp_obtain_after_migration(ctx);
1756    test_mrsp_obtain_and_sleep_and_release(ctx);
1757    test_mrsp_obtain_and_release_with_help(ctx);
1758    test_mrsp_obtain_and_release(ctx);
1759    test_mrsp_load(ctx);
1760  }
1761
1762  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
1763
1764  TEST_END();
1765  rtems_test_exit(0);
1766}
1767
1768#define CONFIGURE_SMP_APPLICATION
1769
1770#define CONFIGURE_MICROSECONDS_PER_TICK 1000
1771
1772#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
1773#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
1774
1775#define CONFIGURE_MAXIMUM_TASKS (2 * CPU_COUNT + 2)
1776#define CONFIGURE_MAXIMUM_SEMAPHORES (MRSP_COUNT + 1)
1777#define CONFIGURE_MAXIMUM_MRSP_SEMAPHORES MRSP_COUNT
1778#define CONFIGURE_MAXIMUM_TIMERS 1
1779
1780#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
1781
1782#define CONFIGURE_SCHEDULER_SIMPLE_SMP
1783
1784#include <rtems/scheduler.h>
1785
1786RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(0);
1787RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(1);
1788RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(2);
1789RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(3);
1790RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(4);
1791RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(5);
1792RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(6);
1793RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(7);
1794RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(8);
1795RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(9);
1796RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(10);
1797RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(11);
1798RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(12);
1799RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(13);
1800RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(14);
1801RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(15);
1802RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(16);
1803
1804#define CONFIGURE_SCHEDULER_CONTROLS \
1805  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(0, 0), \
1806  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(1, 1), \
1807  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(2, 2), \
1808  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(3, 3), \
1809  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(4, 4), \
1810  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(5, 5), \
1811  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(6, 6), \
1812  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(7, 7), \
1813  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(8, 8), \
1814  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(9, 9), \
1815  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(10, 10), \
1816  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(11, 11), \
1817  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(12, 12), \
1818  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(13, 13), \
1819  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(14, 14), \
1820  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(15, 15), \
1821  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(16, 16)
1822
1823#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
1824  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
1825  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1826  RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1827  RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1828  RTEMS_SCHEDULER_ASSIGN(3, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1829  RTEMS_SCHEDULER_ASSIGN(3, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1830  RTEMS_SCHEDULER_ASSIGN(4, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1831  RTEMS_SCHEDULER_ASSIGN(4, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1832  RTEMS_SCHEDULER_ASSIGN(5, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1833  RTEMS_SCHEDULER_ASSIGN(5, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1834  RTEMS_SCHEDULER_ASSIGN(6, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1835  RTEMS_SCHEDULER_ASSIGN(6, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1836  RTEMS_SCHEDULER_ASSIGN(7, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1837  RTEMS_SCHEDULER_ASSIGN(7, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1838  RTEMS_SCHEDULER_ASSIGN(8, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1839  RTEMS_SCHEDULER_ASSIGN(8, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1840  RTEMS_SCHEDULER_ASSIGN(9, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1841  RTEMS_SCHEDULER_ASSIGN(9, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1842  RTEMS_SCHEDULER_ASSIGN(10, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1843  RTEMS_SCHEDULER_ASSIGN(10, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1844  RTEMS_SCHEDULER_ASSIGN(11, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1845  RTEMS_SCHEDULER_ASSIGN(11, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1846  RTEMS_SCHEDULER_ASSIGN(12, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1847  RTEMS_SCHEDULER_ASSIGN(12, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1848  RTEMS_SCHEDULER_ASSIGN(13, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1849  RTEMS_SCHEDULER_ASSIGN(13, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1850  RTEMS_SCHEDULER_ASSIGN(14, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1851  RTEMS_SCHEDULER_ASSIGN(14, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1852  RTEMS_SCHEDULER_ASSIGN(15, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1853  RTEMS_SCHEDULER_ASSIGN(15, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1854  RTEMS_SCHEDULER_ASSIGN(16, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1855  RTEMS_SCHEDULER_ASSIGN(16, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
1856
1857#define CONFIGURE_INITIAL_EXTENSIONS \
1858  { .thread_switch = switch_extension }, \
1859  RTEMS_TEST_INITIAL_EXTENSION
1860
1861#define CONFIGURE_INIT_TASK_NAME rtems_build_name('M', 'A', 'I', 'N')
1862#define CONFIGURE_INIT_TASK_PRIORITY 2
1863
1864#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
1865
1866#define CONFIGURE_INIT
1867
1868#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.