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

4.115
Last change on this file since 6570876 was 27783f6, checked in by Sebastian Huber <sebastian.huber@…>, on 07/10/14 at 12:27:42

score: Fix scheduler helping implementation

Do not extract the idle threads from the ready set so that there is
always a thread available for comparison.

  • Property mode set to 100644
File size: 34.5 KB
Line 
1/*
2 * Copyright (c) 2014 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 <stdio.h>
20#include <inttypes.h>
21
22#include <rtems.h>
23#include <rtems/libcsupport.h>
24#include <rtems/score/schedulersmpimpl.h>
25#include <rtems/score/smpbarrier.h>
26#include <rtems/score/smplock.h>
27
28#define TESTS_USE_PRINTK
29#include "tmacros.h"
30
31const char rtems_test_name[] = "SMPMRSP 1";
32
33#define CPU_COUNT 32
34
35#define MRSP_COUNT 32
36
37#define SWITCH_EVENT_COUNT 32
38
39typedef struct {
40  uint32_t sleep;
41  uint32_t timeout;
42  uint32_t obtain[MRSP_COUNT];
43  uint32_t cpu[CPU_COUNT];
44} counter;
45
46typedef struct {
47  uint32_t cpu_index;
48  const Thread_Control *executing;
49  const Thread_Control *heir;
50  const Thread_Control *heir_node;
51  Priority_Control heir_priority;
52} switch_event;
53
54typedef struct {
55  rtems_id main_task_id;
56  rtems_id migration_task_id;
57  rtems_id counting_sem_id;
58  rtems_id mrsp_ids[MRSP_COUNT];
59  rtems_id scheduler_ids[CPU_COUNT];
60  rtems_id worker_ids[2 * CPU_COUNT];
61  volatile bool stop_worker[CPU_COUNT];
62  counter counters[2 * CPU_COUNT];
63  uint32_t migration_counters[CPU_COUNT];
64  Thread_Control *worker_task;
65  SMP_barrier_Control barrier;
66  SMP_lock_Control switch_lock;
67  size_t switch_index;
68  switch_event switch_events[32];
69} test_context;
70
71static test_context test_instance = {
72  .barrier = SMP_BARRIER_CONTROL_INITIALIZER,
73  .switch_lock = SMP_LOCK_INITIALIZER("test instance switch lock")
74};
75
76static void barrier(test_context *ctx, SMP_barrier_State *bs)
77{
78  _SMP_barrier_Wait(&ctx->barrier, bs, 2);
79}
80
81static rtems_task_priority get_prio(rtems_id task_id)
82{
83  rtems_status_code sc;
84  rtems_task_priority prio;
85
86  sc = rtems_task_set_priority(task_id, RTEMS_CURRENT_PRIORITY, &prio);
87  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
88
89  return prio;
90}
91
92static void wait_for_prio(rtems_id task_id, rtems_task_priority prio)
93{
94  while (get_prio(task_id) != prio) {
95    /* Wait */
96  }
97}
98
99static void assert_prio(rtems_id task_id, rtems_task_priority expected_prio)
100{
101  rtems_test_assert(get_prio(task_id) == expected_prio);
102}
103
104static void change_prio(rtems_id task_id, rtems_task_priority prio)
105{
106  rtems_status_code sc;
107
108  sc = rtems_task_set_priority(task_id, prio, &prio);
109  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
110}
111
112static void assert_executing_worker(test_context *ctx)
113{
114  rtems_test_assert(
115    _CPU_Context_Get_is_executing(&ctx->worker_task->Registers)
116  );
117}
118
119static void switch_extension(Thread_Control *executing, Thread_Control *heir)
120{
121  test_context *ctx = &test_instance;
122  SMP_lock_Context lock_context;
123  size_t i;
124
125  _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
126
127  i = ctx->switch_index;
128  if (i < SWITCH_EVENT_COUNT) {
129    switch_event *e = &ctx->switch_events[i];
130    Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node(heir);
131
132    e->cpu_index = rtems_get_current_processor();
133    e->executing = executing;
134    e->heir = heir;
135    e->heir_node = _Scheduler_Node_get_owner(&node->Base);
136    e->heir_priority = node->priority;
137
138    ctx->switch_index = i + 1;
139  }
140
141  _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
142}
143
144static void reset_switch_events(test_context *ctx)
145{
146  SMP_lock_Context lock_context;
147
148  _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
149  ctx->switch_index = 0;
150  _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
151}
152
153static size_t get_switch_events(test_context *ctx)
154{
155  SMP_lock_Context lock_context;
156  size_t events;
157
158  _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
159  events = ctx->switch_index;
160  _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
161
162  return events;
163}
164
165static void print_switch_events(test_context *ctx)
166{
167  size_t n = get_switch_events(ctx);
168  size_t i;
169
170  for (i = 0; i < n; ++i) {
171    switch_event *e = &ctx->switch_events[i];
172    char ex[5];
173    char hr[5];
174    char hn[5];
175
176    rtems_object_get_name(e->executing->Object.id, sizeof(ex), &ex[0]);
177    rtems_object_get_name(e->heir->Object.id, sizeof(hr), &hr[0]);
178    rtems_object_get_name(e->heir_node->Object.id, sizeof(hn), &hn[0]);
179
180    printf(
181      "[%" PRIu32 "] %4s -> %4s (prio %3" PRIu32 ", node %4s)\n",
182      e->cpu_index,
183      &ex[0],
184      &hr[0],
185      e->heir_priority,
186      &hn[0]
187    );
188  }
189}
190
191static void obtain_and_release_worker(rtems_task_argument arg)
192{
193  test_context *ctx = &test_instance;
194  rtems_status_code sc;
195  SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
196
197  ctx->worker_task = _Thread_Get_executing();
198
199  assert_prio(RTEMS_SELF, 3);
200
201  /* Obtain with timeout (A) */
202  barrier(ctx, &barrier_state);
203
204  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
205  rtems_test_assert(sc == RTEMS_TIMEOUT);
206
207  assert_prio(RTEMS_SELF, 3);
208
209  /* Obtain with priority change and timeout (B) */
210  barrier(ctx, &barrier_state);
211
212  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
213  rtems_test_assert(sc == RTEMS_TIMEOUT);
214
215  assert_prio(RTEMS_SELF, 1);
216
217  /* Restore priority (C) */
218  barrier(ctx, &barrier_state);
219
220  /* Obtain without timeout (D) */
221  barrier(ctx, &barrier_state);
222
223  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
224  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
225
226  assert_prio(RTEMS_SELF, 2);
227
228  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
229  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
230
231  assert_prio(RTEMS_SELF, 3);
232
233  /* Worker done (E) */
234  barrier(ctx, &barrier_state);
235
236  rtems_task_suspend(RTEMS_SELF);
237  rtems_test_assert(0);
238}
239
240static void test_mrsp_obtain_and_release(test_context *ctx)
241{
242  rtems_status_code sc;
243  rtems_task_priority prio;
244  rtems_id scheduler_id;
245  SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
246
247  puts("test MrsP obtain and release");
248
249  change_prio(RTEMS_SELF, 2);
250
251  /* Check executing task parameters */
252
253  sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
254  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
255
256  rtems_test_assert(ctx->scheduler_ids[0] == scheduler_id);
257
258  /* Create a MrsP semaphore object and lock it */
259
260  sc = rtems_semaphore_create(
261    rtems_build_name('M', 'R', 'S', 'P'),
262    1,
263    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
264      | RTEMS_BINARY_SEMAPHORE,
265    1,
266    &ctx->mrsp_ids[0]
267  );
268  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
269
270  assert_prio(RTEMS_SELF, 2);
271
272  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
273  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
274
275  assert_prio(RTEMS_SELF, 1);
276
277  /*
278   * The ceiling priority values per scheduler are equal to the value specified
279   * for object creation.
280   */
281
282  prio = RTEMS_CURRENT_PRIORITY;
283  sc = rtems_semaphore_set_priority(
284    ctx->mrsp_ids[0],
285    ctx->scheduler_ids[0],
286    prio,
287    &prio
288  );
289  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
290  rtems_test_assert(prio == 1);
291
292  /* Check the old value and set a new ceiling priority for scheduler B */
293
294  prio = 2;
295  sc = rtems_semaphore_set_priority(
296    ctx->mrsp_ids[0],
297    ctx->scheduler_ids[1],
298    prio,
299    &prio
300  );
301  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
302  rtems_test_assert(prio == 1);
303
304  /* Check the ceiling priority values */
305
306  prio = RTEMS_CURRENT_PRIORITY;
307  sc = rtems_semaphore_set_priority(
308    ctx->mrsp_ids[0],
309    ctx->scheduler_ids[0],
310    prio,
311    &prio
312  );
313  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
314  rtems_test_assert(prio == 1);
315
316  prio = RTEMS_CURRENT_PRIORITY;
317  sc = rtems_semaphore_set_priority(
318    ctx->mrsp_ids[0],
319    ctx->scheduler_ids[1],
320    prio,
321    &prio
322  );
323  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
324  rtems_test_assert(prio == 2);
325
326  /* Check that a thread waiting to get ownership remains executing */
327
328  sc = rtems_task_create(
329    rtems_build_name('W', 'O', 'R', 'K'),
330    3,
331    RTEMS_MINIMUM_STACK_SIZE,
332    RTEMS_DEFAULT_MODES,
333    RTEMS_DEFAULT_ATTRIBUTES,
334    &ctx->worker_ids[0]
335  );
336  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
337
338  sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1]);
339  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
340
341  sc = rtems_task_start(ctx->worker_ids[0], obtain_and_release_worker, 0);
342  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
343
344  /* Obtain with timeout (A) */
345  barrier(ctx, &barrier_state);
346
347  sc = rtems_task_wake_after(2);
348  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
349
350  assert_prio(ctx->worker_ids[0], 2);
351  assert_executing_worker(ctx);
352
353  /* Obtain with priority change and timeout (B) */
354  barrier(ctx, &barrier_state);
355
356  sc = rtems_task_wake_after(2);
357  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
358
359  assert_prio(ctx->worker_ids[0], 2);
360  change_prio(ctx->worker_ids[0], 1);
361  assert_executing_worker(ctx);
362
363  /* Restore priority (C) */
364  barrier(ctx, &barrier_state);
365
366  assert_prio(ctx->worker_ids[0], 1);
367  change_prio(ctx->worker_ids[0], 3);
368
369  /* Obtain without timeout (D) */
370  barrier(ctx, &barrier_state);
371
372  sc = rtems_task_wake_after(2);
373  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
374
375  assert_prio(ctx->worker_ids[0], 2);
376  assert_executing_worker(ctx);
377
378  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
379  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
380
381  /* Worker done (E) */
382  barrier(ctx, &barrier_state);
383
384  sc = rtems_task_delete(ctx->worker_ids[0]);
385  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
386
387  sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
388  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
389}
390
391static void test_mrsp_flush_error(void)
392{
393  rtems_status_code sc;
394  rtems_id id;
395
396  puts("test MrsP flush error");
397
398  sc = rtems_semaphore_create(
399    rtems_build_name('M', 'R', 'S', 'P'),
400    1,
401    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
402      | RTEMS_BINARY_SEMAPHORE,
403    1,
404    &id
405  );
406  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
407
408  sc = rtems_semaphore_flush(id);
409  rtems_test_assert(sc == RTEMS_NOT_DEFINED);
410
411  sc = rtems_semaphore_delete(id);
412  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
413}
414
415static void test_mrsp_initially_locked_error(void)
416{
417  rtems_status_code sc;
418  rtems_id id;
419
420  puts("test MrsP initially locked error");
421
422  sc = rtems_semaphore_create(
423    rtems_build_name('M', 'R', 'S', 'P'),
424    0,
425    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
426      | RTEMS_BINARY_SEMAPHORE,
427    1,
428    &id
429  );
430  rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
431}
432
433static void test_mrsp_nested_obtain_error(void)
434{
435  rtems_status_code sc;
436  rtems_id id;
437
438  puts("test MrsP nested obtain error");
439
440  sc = rtems_semaphore_create(
441    rtems_build_name('M', 'R', 'S', 'P'),
442    1,
443    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
444      | RTEMS_BINARY_SEMAPHORE,
445    1,
446    &id
447  );
448  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
449
450  sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
451  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
452
453  sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
454  rtems_test_assert(sc == RTEMS_UNSATISFIED);
455
456  sc = rtems_semaphore_release(id);
457  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
458
459  sc = rtems_semaphore_delete(id);
460  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
461}
462
463static void test_mrsp_unlock_order_error(void)
464{
465  rtems_status_code sc;
466  rtems_id id_a;
467  rtems_id id_b;
468
469  puts("test MrsP unlock order error");
470
471  sc = rtems_semaphore_create(
472    rtems_build_name(' ', ' ', ' ', 'A'),
473    1,
474    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
475      | RTEMS_BINARY_SEMAPHORE,
476    1,
477    &id_a
478  );
479  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
480
481  sc = rtems_semaphore_create(
482    rtems_build_name(' ', ' ', ' ', 'B'),
483    1,
484    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
485      | RTEMS_BINARY_SEMAPHORE,
486    1,
487    &id_b
488  );
489  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
490
491  sc = rtems_semaphore_obtain(id_a, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
492  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
493
494  sc = rtems_semaphore_obtain(id_b, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
495  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
496
497  sc = rtems_semaphore_release(id_a);
498  rtems_test_assert(sc == RTEMS_INCORRECT_STATE);
499
500  sc = rtems_semaphore_release(id_b);
501  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
502
503  sc = rtems_semaphore_release(id_a);
504  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
505
506  sc = rtems_semaphore_delete(id_a);
507  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
508
509  sc = rtems_semaphore_delete(id_b);
510  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
511}
512
513static void deadlock_worker(rtems_task_argument arg)
514{
515  test_context *ctx = &test_instance;
516  rtems_status_code sc;
517
518  sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
519  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
520
521  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
522  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
523
524  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
525  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
526
527  sc = rtems_semaphore_release(ctx->mrsp_ids[1]);
528  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
529
530  sc = rtems_event_transient_send(ctx->main_task_id);
531  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
532
533  rtems_task_suspend(RTEMS_SELF);
534  rtems_test_assert(0);
535}
536
537static void test_mrsp_deadlock_error(test_context *ctx)
538{
539  rtems_status_code sc;
540  rtems_task_priority prio = 2;
541
542  puts("test MrsP deadlock error");
543
544  change_prio(RTEMS_SELF, prio);
545
546  sc = rtems_semaphore_create(
547    rtems_build_name(' ', ' ', ' ', 'A'),
548    1,
549    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
550      | RTEMS_BINARY_SEMAPHORE,
551    prio,
552    &ctx->mrsp_ids[0]
553  );
554  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
555
556  sc = rtems_semaphore_create(
557    rtems_build_name(' ', ' ', ' ', 'B'),
558    1,
559    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
560      | RTEMS_BINARY_SEMAPHORE,
561    prio,
562    &ctx->mrsp_ids[1]
563  );
564  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
565
566  sc = rtems_task_create(
567    rtems_build_name('W', 'O', 'R', 'K'),
568    prio,
569    RTEMS_MINIMUM_STACK_SIZE,
570    RTEMS_DEFAULT_MODES,
571    RTEMS_DEFAULT_ATTRIBUTES,
572    &ctx->worker_ids[0]
573  );
574  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
575
576  sc = rtems_task_start(ctx->worker_ids[0], deadlock_worker, 0);
577  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
578
579  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
580  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
581
582  sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
583  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
584
585  sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
586  rtems_test_assert(sc == RTEMS_UNSATISFIED);
587
588  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
589  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
590
591  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
592  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
593
594  sc = rtems_task_delete(ctx->worker_ids[0]);
595  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
596
597  sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
598  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
599
600  sc = rtems_semaphore_delete(ctx->mrsp_ids[1]);
601  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
602}
603
604static void test_mrsp_multiple_obtain(void)
605{
606  rtems_status_code sc;
607  rtems_id sem_a_id;
608  rtems_id sem_b_id;
609  rtems_id sem_c_id;
610
611  puts("test MrsP multiple obtain");
612
613  change_prio(RTEMS_SELF, 4);
614
615  sc = rtems_semaphore_create(
616    rtems_build_name(' ', ' ', ' ', 'A'),
617    1,
618    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
619      | RTEMS_BINARY_SEMAPHORE,
620    3,
621    &sem_a_id
622  );
623  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
624
625  sc = rtems_semaphore_create(
626    rtems_build_name(' ', ' ', ' ', 'B'),
627    1,
628    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
629      | RTEMS_BINARY_SEMAPHORE,
630    2,
631    &sem_b_id
632  );
633  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
634
635  sc = rtems_semaphore_create(
636    rtems_build_name(' ', ' ', ' ', 'C'),
637    1,
638    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
639      | RTEMS_BINARY_SEMAPHORE,
640    1,
641    &sem_c_id
642  );
643  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
644
645  assert_prio(RTEMS_SELF, 4);
646
647  sc = rtems_semaphore_obtain(sem_a_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
648  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
649
650  assert_prio(RTEMS_SELF, 3);
651
652  sc = rtems_semaphore_obtain(sem_b_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
653  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
654
655  assert_prio(RTEMS_SELF, 2);
656
657  sc = rtems_semaphore_obtain(sem_c_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
658  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
659
660  assert_prio(RTEMS_SELF, 1);
661
662  sc = rtems_semaphore_release(sem_c_id);
663  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
664
665  assert_prio(RTEMS_SELF, 2);
666
667  sc = rtems_semaphore_release(sem_b_id);
668  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
669
670  assert_prio(RTEMS_SELF, 3);
671
672  sc = rtems_semaphore_release(sem_a_id);
673  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
674
675  assert_prio(RTEMS_SELF, 4);
676
677  sc = rtems_semaphore_obtain(sem_a_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
678  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
679
680  assert_prio(RTEMS_SELF, 3);
681
682  sc = rtems_semaphore_obtain(sem_b_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
683  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
684
685  assert_prio(RTEMS_SELF, 2);
686
687  sc = rtems_semaphore_obtain(sem_c_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
688  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
689
690  assert_prio(RTEMS_SELF, 1);
691  change_prio(RTEMS_SELF, 3);
692  assert_prio(RTEMS_SELF, 1);
693
694  sc = rtems_semaphore_release(sem_c_id);
695  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
696
697  assert_prio(RTEMS_SELF, 2);
698
699  sc = rtems_semaphore_release(sem_b_id);
700  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
701
702  assert_prio(RTEMS_SELF, 3);
703
704  sc = rtems_semaphore_release(sem_a_id);
705  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
706
707  assert_prio(RTEMS_SELF, 3);
708
709  sc = rtems_semaphore_delete(sem_a_id);
710  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
711
712  sc = rtems_semaphore_delete(sem_b_id);
713  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
714
715  sc = rtems_semaphore_delete(sem_c_id);
716  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
717
718  change_prio(RTEMS_SELF, 2);
719  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
720}
721
722static void run_task(rtems_task_argument arg)
723{
724  volatile bool *run = (volatile bool *) arg;
725
726  while (true) {
727    *run = true;
728  }
729}
730
731static void test_mrsp_obtain_and_sleep_and_release(test_context *ctx)
732{
733  rtems_status_code sc;
734  rtems_id sem_id;
735  rtems_id run_task_id;
736  volatile bool run = false;
737
738  puts("test MrsP obtain and sleep and release");
739
740  change_prio(RTEMS_SELF, 1);
741
742  reset_switch_events(ctx);
743
744  sc = rtems_task_create(
745    rtems_build_name(' ', 'R', 'U', 'N'),
746    2,
747    RTEMS_MINIMUM_STACK_SIZE,
748    RTEMS_DEFAULT_MODES,
749    RTEMS_DEFAULT_ATTRIBUTES,
750    &run_task_id
751  );
752  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
753
754  sc = rtems_task_start(run_task_id, run_task, (rtems_task_argument) &run);
755  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
756
757  sc = rtems_semaphore_create(
758    rtems_build_name('S', 'E', 'M', 'A'),
759    1,
760    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
761      | RTEMS_BINARY_SEMAPHORE,
762    1,
763    &sem_id
764  );
765  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
766
767  rtems_test_assert(!run);
768
769  sc = rtems_task_wake_after(2);
770  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
771
772  rtems_test_assert(run);
773  run = false;
774
775  sc = rtems_semaphore_obtain(sem_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
776  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
777
778  rtems_test_assert(!run);
779
780  sc = rtems_task_wake_after(2);
781  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
782
783  rtems_test_assert(!run);
784
785  sc = rtems_semaphore_release(sem_id);
786  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
787
788  print_switch_events(ctx);
789
790  sc = rtems_semaphore_delete(sem_id);
791  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
792
793  sc = rtems_task_delete(run_task_id);
794  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
795}
796
797static void help_task(rtems_task_argument arg)
798{
799  test_context *ctx = &test_instance;
800  rtems_status_code sc;
801
802  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
803  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
804
805  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
806  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
807
808  while (true) {
809    /* Do nothing */
810  }
811}
812
813static void test_mrsp_obtain_and_release_with_help(test_context *ctx)
814{
815  rtems_status_code sc;
816  rtems_id help_task_id;
817  rtems_id run_task_id;
818  volatile bool run = false;
819
820  puts("test MrsP obtain and release with help");
821
822  change_prio(RTEMS_SELF, 3);
823
824  reset_switch_events(ctx);
825
826  sc = rtems_semaphore_create(
827    rtems_build_name('S', 'E', 'M', 'A'),
828    1,
829    RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
830      | RTEMS_BINARY_SEMAPHORE,
831    2,
832    &ctx->mrsp_ids[0]
833  );
834  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
835
836  sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
837  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
838
839  assert_prio(RTEMS_SELF, 2);
840
841  sc = rtems_task_create(
842    rtems_build_name('H', 'E', 'L', 'P'),
843    3,
844    RTEMS_MINIMUM_STACK_SIZE,
845    RTEMS_DEFAULT_MODES,
846    RTEMS_DEFAULT_ATTRIBUTES,
847    &help_task_id
848  );
849  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
850
851  sc = rtems_task_set_scheduler(
852    help_task_id,
853    ctx->scheduler_ids[1]
854  );
855  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
856
857  sc = rtems_task_start(help_task_id, help_task, 0);
858  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
859
860  sc = rtems_task_create(
861    rtems_build_name(' ', 'R', 'U', 'N'),
862    4,
863    RTEMS_MINIMUM_STACK_SIZE,
864    RTEMS_DEFAULT_MODES,
865    RTEMS_DEFAULT_ATTRIBUTES,
866    &run_task_id
867  );
868  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
869
870  sc = rtems_task_start(run_task_id, run_task, (rtems_task_argument) &run);
871  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
872
873  wait_for_prio(help_task_id, 2);
874
875  sc = rtems_task_wake_after(2);
876  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
877
878  rtems_test_assert(rtems_get_current_processor() == 0);
879  rtems_test_assert(!run);
880
881  change_prio(run_task_id, 1);
882
883  rtems_test_assert(rtems_get_current_processor() == 1);
884
885  while (!run) {
886    /* Wait */
887  }
888
889  sc = rtems_task_wake_after(2);
890  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
891
892  rtems_test_assert(rtems_get_current_processor() == 1);
893
894  change_prio(run_task_id, 4);
895
896  rtems_test_assert(rtems_get_current_processor() == 1);
897
898  sc = rtems_task_wake_after(2);
899  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
900
901  rtems_test_assert(rtems_get_current_processor() == 1);
902
903  /*
904   * With this operation the scheduler instance 0 has now only the main and the
905   * idle threads in the ready set.
906   */
907  sc = rtems_task_suspend(run_task_id);
908  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
909
910  rtems_test_assert(rtems_get_current_processor() == 1);
911
912  change_prio(RTEMS_SELF, 1);
913  change_prio(RTEMS_SELF, 3);
914
915  sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
916  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
917
918  rtems_test_assert(rtems_get_current_processor() == 0);
919
920  assert_prio(RTEMS_SELF, 3);
921
922  wait_for_prio(help_task_id, 3);
923
924  print_switch_events(ctx);
925
926  sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
927  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
928
929  sc = rtems_task_delete(help_task_id);
930  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
931
932  sc = rtems_task_delete(run_task_id);
933  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
934}
935
936static uint32_t simple_random(uint32_t v)
937{
938  v *= 1664525;
939  v += 1013904223;
940
941  return v;
942}
943
944static rtems_interval timeout(uint32_t v)
945{
946  return (v >> 23) % 4;
947}
948
949static void load_worker(rtems_task_argument index)
950{
951  test_context *ctx = &test_instance;
952  rtems_status_code sc;
953  uint32_t v = index;
954
955  while (!ctx->stop_worker[index]) {
956    uint32_t i = (v >> 13) % MRSP_COUNT;
957
958    assert_prio(RTEMS_SELF, 3 + CPU_COUNT + index);
959
960    if ((v >> 7) % 1024 == 0) {
961      /* Give some time to the lower priority tasks */
962
963      ++ctx->counters[index].sleep;
964
965      sc = rtems_task_wake_after(1);
966      rtems_test_assert(sc == RTEMS_SUCCESSFUL);
967
968      ++ctx->counters[index].cpu[rtems_get_current_processor()];
969    } else {
970      uint32_t n = (v >> 17) % (i + 1);
971      uint32_t s;
972      uint32_t t;
973
974      /* Nested obtain */
975      for (s = 0; s <= n; ++s) {
976        uint32_t k = i - s;
977
978        sc = rtems_semaphore_obtain(ctx->mrsp_ids[k], RTEMS_WAIT, timeout(v));
979        if (sc == RTEMS_SUCCESSFUL) {
980          ++ctx->counters[index].obtain[n];
981
982          assert_prio(RTEMS_SELF, 3 + k);
983        } else {
984          rtems_test_assert(sc == RTEMS_TIMEOUT);
985
986          ++ctx->counters[index].timeout;
987
988          break;
989        }
990
991        ++ctx->counters[index].cpu[rtems_get_current_processor()];
992
993        v = simple_random(v);
994      }
995
996      /* Release in reverse obtain order */
997      for (t = 0; t < s; ++t) {
998        uint32_t k = i + t - s + 1;
999
1000        sc = rtems_semaphore_release(ctx->mrsp_ids[k]);
1001        rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1002
1003        ++ctx->counters[index].cpu[rtems_get_current_processor()];
1004      }
1005    }
1006
1007    v = simple_random(v);
1008  }
1009
1010  sc = rtems_semaphore_release(ctx->counting_sem_id);
1011  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1012
1013  rtems_task_suspend(RTEMS_SELF);
1014  rtems_test_assert(0);
1015}
1016
1017static void migration_task(rtems_task_argument arg)
1018{
1019  test_context *ctx = &test_instance;
1020  rtems_status_code sc;
1021  uint32_t cpu_count = rtems_get_processor_count();
1022  uint32_t v = 0xdeadbeef;
1023
1024  while (true) {
1025    uint32_t cpu_index = (v >> 5) % cpu_count;
1026
1027    sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->scheduler_ids[cpu_index]);
1028    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1029
1030    ++ctx->migration_counters[rtems_get_current_processor()];
1031
1032    v = simple_random(v);
1033  }
1034}
1035
1036static void test_mrsp_load(test_context *ctx)
1037{
1038  rtems_status_code sc;
1039  uint32_t cpu_count = rtems_get_processor_count();
1040  uint32_t index;
1041
1042  puts("test MrsP load");
1043
1044  change_prio(RTEMS_SELF, 2);
1045
1046  sc = rtems_task_create(
1047    rtems_build_name('M', 'I', 'G', 'R'),
1048    2,
1049    RTEMS_MINIMUM_STACK_SIZE,
1050    RTEMS_DEFAULT_MODES,
1051    RTEMS_DEFAULT_ATTRIBUTES,
1052    &ctx->migration_task_id
1053  );
1054  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1055
1056  sc = rtems_task_start(ctx->migration_task_id, migration_task, 0);
1057  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1058
1059  sc = rtems_semaphore_create(
1060    rtems_build_name('S', 'Y', 'N', 'C'),
1061    0,
1062    RTEMS_COUNTING_SEMAPHORE,
1063    0,
1064    &ctx->counting_sem_id
1065  );
1066  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1067
1068  for (index = 0; index < MRSP_COUNT; ++index) {
1069    sc = rtems_semaphore_create(
1070      'A' + index,
1071      1,
1072      RTEMS_MULTIPROCESSOR_RESOURCE_SHARING
1073        | RTEMS_BINARY_SEMAPHORE,
1074      3 + index,
1075      &ctx->mrsp_ids[index]
1076    );
1077    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1078  }
1079
1080  for (index = 0; index < cpu_count; ++index) {
1081    uint32_t a = 2 * index;
1082    uint32_t b = a + 1;
1083
1084    sc = rtems_task_create(
1085      'A' + a,
1086      3 + MRSP_COUNT + a,
1087      RTEMS_MINIMUM_STACK_SIZE,
1088      RTEMS_DEFAULT_MODES,
1089      RTEMS_DEFAULT_ATTRIBUTES,
1090      &ctx->worker_ids[a]
1091    );
1092    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1093
1094    sc = rtems_task_set_scheduler(
1095      ctx->worker_ids[a],
1096      ctx->scheduler_ids[index]
1097    );
1098    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1099
1100    sc = rtems_task_start(
1101      ctx->worker_ids[a],
1102      load_worker,
1103      (rtems_task_argument) a
1104    );
1105    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1106
1107    sc = rtems_task_create(
1108      'A' + b,
1109      3 + MRSP_COUNT + b,
1110      RTEMS_MINIMUM_STACK_SIZE,
1111      RTEMS_DEFAULT_MODES,
1112      RTEMS_DEFAULT_ATTRIBUTES,
1113      &ctx->worker_ids[b]
1114    );
1115    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1116
1117    sc = rtems_task_set_scheduler(
1118      ctx->worker_ids[b],
1119      ctx->scheduler_ids[index]
1120    );
1121    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1122
1123    sc = rtems_task_start(
1124      ctx->worker_ids[b],
1125      load_worker,
1126      (rtems_task_argument) b
1127    );
1128    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1129  }
1130
1131  sc = rtems_task_wake_after(30 * rtems_clock_get_ticks_per_second());
1132  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1133
1134  for (index = 0; index < 2 * cpu_count; ++index) {
1135    ctx->stop_worker[index] = true;
1136  }
1137
1138  for (index = 0; index < 2 * cpu_count; ++index) {
1139    sc = rtems_semaphore_obtain(
1140      ctx->counting_sem_id,
1141      RTEMS_WAIT,
1142      RTEMS_NO_TIMEOUT
1143    );
1144    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1145  }
1146
1147  for (index = 0; index < 2 * cpu_count; ++index) {
1148    sc = rtems_task_delete(ctx->worker_ids[index]);
1149    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1150  }
1151
1152  for (index = 0; index < MRSP_COUNT; ++index) {
1153    sc = rtems_semaphore_delete(ctx->mrsp_ids[index]);
1154    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1155  }
1156
1157  sc = rtems_semaphore_delete(ctx->counting_sem_id);
1158  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1159
1160  sc = rtems_task_delete(ctx->migration_task_id);
1161  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1162
1163  for (index = 0; index < 2 * cpu_count; ++index) {
1164    uint32_t nest_level;
1165    uint32_t cpu_index;
1166
1167    printf(
1168      "worker[%" PRIu32 "]\n"
1169        "  sleep = %" PRIu32 "\n"
1170        "  timeout = %" PRIu32 "\n",
1171      index,
1172      ctx->counters[index].sleep,
1173      ctx->counters[index].timeout
1174    );
1175
1176    for (nest_level = 0; nest_level < MRSP_COUNT; ++nest_level) {
1177      printf(
1178        "  obtain[%" PRIu32 "] = %" PRIu32 "\n",
1179        nest_level,
1180        ctx->counters[index].obtain[nest_level]
1181      );
1182    }
1183
1184    for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
1185      printf(
1186        "  cpu[%" PRIu32 "] = %" PRIu32 "\n",
1187        cpu_index,
1188        ctx->counters[index].cpu[cpu_index]
1189      );
1190    }
1191  }
1192
1193  for (index = 0; index < cpu_count; ++index) {
1194    printf(
1195      "migrations[%" PRIu32 "] = %" PRIu32 "\n",
1196      index,
1197      ctx->migration_counters[index]
1198    );
1199  }
1200}
1201
1202static void Init(rtems_task_argument arg)
1203{
1204  test_context *ctx = &test_instance;
1205  rtems_status_code sc;
1206  rtems_resource_snapshot snapshot;
1207  uint32_t cpu_count = rtems_get_processor_count();
1208  uint32_t cpu_index;
1209
1210  TEST_BEGIN();
1211
1212  rtems_resource_snapshot_take(&snapshot);
1213
1214  ctx->main_task_id = rtems_task_self();
1215
1216  for (cpu_index = 0; cpu_index < 2; ++cpu_index) {
1217    sc = rtems_scheduler_ident(cpu_index, &ctx->scheduler_ids[cpu_index]);
1218    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1219  }
1220
1221  for (cpu_index = 2; cpu_index < cpu_count; ++cpu_index) {
1222    sc = rtems_scheduler_ident(
1223      cpu_index / 2 + 1,
1224      &ctx->scheduler_ids[cpu_index]
1225    );
1226    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1227  }
1228
1229  test_mrsp_flush_error();
1230  test_mrsp_initially_locked_error();
1231  test_mrsp_nested_obtain_error();
1232  test_mrsp_unlock_order_error();
1233  test_mrsp_deadlock_error(ctx);
1234  test_mrsp_multiple_obtain();
1235  test_mrsp_obtain_and_sleep_and_release(ctx);
1236  test_mrsp_obtain_and_release_with_help(ctx);
1237  test_mrsp_obtain_and_release(ctx);
1238  test_mrsp_load(ctx);
1239
1240  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
1241
1242  TEST_END();
1243  rtems_test_exit(0);
1244}
1245
1246#define CONFIGURE_SMP_APPLICATION
1247
1248#define CONFIGURE_MICROSECONDS_PER_TICK 1000
1249
1250#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
1251#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
1252
1253#define CONFIGURE_MAXIMUM_TASKS (2 * CPU_COUNT + 2)
1254#define CONFIGURE_MAXIMUM_SEMAPHORES (MRSP_COUNT + 1)
1255#define CONFIGURE_MAXIMUM_MRSP_SEMAPHORES MRSP_COUNT
1256#define CONFIGURE_MAXIMUM_TIMERS 1
1257
1258#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
1259
1260#define CONFIGURE_SCHEDULER_SIMPLE_SMP
1261
1262#include <rtems/scheduler.h>
1263
1264RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(0);
1265RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(1);
1266RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(2);
1267RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(3);
1268RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(4);
1269RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(5);
1270RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(6);
1271RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(7);
1272RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(8);
1273RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(9);
1274RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(10);
1275RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(11);
1276RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(12);
1277RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(13);
1278RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(14);
1279RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(15);
1280RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(16);
1281
1282#define CONFIGURE_SCHEDULER_CONTROLS \
1283  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(0, 0), \
1284  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(1, 1), \
1285  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(2, 2), \
1286  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(3, 3), \
1287  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(4, 4), \
1288  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(5, 5), \
1289  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(6, 6), \
1290  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(7, 7), \
1291  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(8, 8), \
1292  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(9, 9), \
1293  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(10, 10), \
1294  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(11, 11), \
1295  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(12, 12), \
1296  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(13, 13), \
1297  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(14, 14), \
1298  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(15, 15), \
1299  RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(16, 16)
1300
1301#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
1302  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
1303  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
1304  RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1305  RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1306  RTEMS_SCHEDULER_ASSIGN(3, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1307  RTEMS_SCHEDULER_ASSIGN(3, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1308  RTEMS_SCHEDULER_ASSIGN(4, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1309  RTEMS_SCHEDULER_ASSIGN(4, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1310  RTEMS_SCHEDULER_ASSIGN(5, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1311  RTEMS_SCHEDULER_ASSIGN(5, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1312  RTEMS_SCHEDULER_ASSIGN(6, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1313  RTEMS_SCHEDULER_ASSIGN(6, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1314  RTEMS_SCHEDULER_ASSIGN(7, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1315  RTEMS_SCHEDULER_ASSIGN(7, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1316  RTEMS_SCHEDULER_ASSIGN(8, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1317  RTEMS_SCHEDULER_ASSIGN(8, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1318  RTEMS_SCHEDULER_ASSIGN(9, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1319  RTEMS_SCHEDULER_ASSIGN(9, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1320  RTEMS_SCHEDULER_ASSIGN(10, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1321  RTEMS_SCHEDULER_ASSIGN(10, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1322  RTEMS_SCHEDULER_ASSIGN(11, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1323  RTEMS_SCHEDULER_ASSIGN(11, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1324  RTEMS_SCHEDULER_ASSIGN(12, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1325  RTEMS_SCHEDULER_ASSIGN(12, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1326  RTEMS_SCHEDULER_ASSIGN(13, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1327  RTEMS_SCHEDULER_ASSIGN(13, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1328  RTEMS_SCHEDULER_ASSIGN(14, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1329  RTEMS_SCHEDULER_ASSIGN(14, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1330  RTEMS_SCHEDULER_ASSIGN(15, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1331  RTEMS_SCHEDULER_ASSIGN(15, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1332  RTEMS_SCHEDULER_ASSIGN(16, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1333  RTEMS_SCHEDULER_ASSIGN(16, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
1334
1335#define CONFIGURE_INITIAL_EXTENSIONS \
1336  { .thread_switch = switch_extension }, \
1337  RTEMS_TEST_INITIAL_EXTENSION
1338
1339#define CONFIGURE_INIT_TASK_NAME rtems_build_name('M', 'A', 'I', 'N')
1340#define CONFIGURE_INIT_TASK_PRIORITY 2
1341
1342#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
1343
1344#define CONFIGURE_INIT
1345
1346#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.