source: rtems/testsuites/smptests/smpmrsp01/init.c @ 0e754fac

5
Last change on this file since 0e754fac was 3a27248, checked in by Sebastian Huber <sebastian.huber@…>, on 10/21/16 at 07:23:58

score: First part of new MrsP implementation

Update #2556.

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