File indexing completed on 2025-05-11 08:24:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031
0032 #include <sys/param.h>
0033
0034 #include <stdio.h>
0035 #include <inttypes.h>
0036
0037 #include <rtems.h>
0038 #include <rtems/libcsupport.h>
0039 #include <rtems/score/schedulersmpimpl.h>
0040 #include <rtems/score/smpbarrier.h>
0041 #include <rtems/score/smplock.h>
0042
0043 #include "tmacros.h"
0044
0045 const char rtems_test_name[] = "SMPMRSP 1";
0046
0047 #define CPU_COUNT 32
0048
0049 #define MRSP_COUNT 32
0050
0051 #define SWITCH_EVENT_COUNT 32
0052
0053 typedef struct {
0054 uint32_t sleep;
0055 uint32_t timeout;
0056 uint32_t obtain[MRSP_COUNT];
0057 uint32_t cpu[CPU_COUNT];
0058 } counter;
0059
0060 typedef struct {
0061 uint32_t cpu_index;
0062 const Thread_Control *executing;
0063 const Thread_Control *heir;
0064 const Thread_Control *heir_node;
0065 Priority_Control heir_priority;
0066 } switch_event;
0067
0068 typedef struct {
0069 rtems_id main_task_id;
0070 rtems_id migration_task_id;
0071 rtems_id low_task_id[2];
0072 rtems_id high_task_id[2];
0073 rtems_id timer_id;
0074 rtems_id counting_sem_id;
0075 rtems_id mrsp_ids[MRSP_COUNT];
0076 rtems_id scheduler_ids[CPU_COUNT];
0077 rtems_id worker_ids[2 * CPU_COUNT];
0078 volatile bool stop_worker[2 * CPU_COUNT];
0079 counter counters[2 * CPU_COUNT];
0080 uint32_t migration_counters[CPU_COUNT];
0081 Thread_Control *worker_task;
0082 SMP_barrier_Control barrier;
0083 SMP_lock_Control switch_lock;
0084 size_t switch_index;
0085 switch_event switch_events[32];
0086 volatile bool high_run[2];
0087 volatile bool low_run[2];
0088 } test_context;
0089
0090 static test_context test_instance = {
0091 .switch_lock = SMP_LOCK_INITIALIZER("test instance switch lock")
0092 };
0093
0094 static void busy_wait(void)
0095 {
0096 rtems_interval later = rtems_clock_tick_later(2);
0097
0098 while (rtems_clock_tick_before(later)) {
0099
0100 }
0101 }
0102
0103 static void barrier_init(test_context *ctx)
0104 {
0105 _SMP_barrier_Control_initialize(&ctx->barrier);
0106 }
0107
0108 static void barrier(test_context *ctx, SMP_barrier_State *bs)
0109 {
0110 _SMP_barrier_Wait(&ctx->barrier, bs, 2);
0111 }
0112
0113 static void barrier_and_delay(test_context *ctx, SMP_barrier_State *bs)
0114 {
0115 barrier(ctx, bs);
0116 busy_wait();
0117 }
0118
0119 static rtems_task_priority get_prio(rtems_id task_id)
0120 {
0121 rtems_status_code sc;
0122 rtems_task_priority prio;
0123
0124 sc = rtems_task_set_priority(task_id, RTEMS_CURRENT_PRIORITY, &prio);
0125 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0126
0127 return prio;
0128 }
0129
0130 static void wait_for_prio(rtems_id task_id, rtems_task_priority prio)
0131 {
0132 while (get_prio(task_id) != prio) {
0133
0134 }
0135 }
0136
0137 static void assert_prio(rtems_id task_id, rtems_task_priority expected_prio)
0138 {
0139 rtems_test_assert(get_prio(task_id) == expected_prio);
0140 }
0141
0142 static void change_prio(rtems_id task_id, rtems_task_priority prio)
0143 {
0144 rtems_status_code sc;
0145
0146 sc = rtems_task_set_priority(task_id, prio, &prio);
0147 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0148 }
0149
0150 static void assert_executing_worker(test_context *ctx)
0151 {
0152 rtems_test_assert(
0153 _CPU_Context_Get_is_executing(&ctx->worker_task->Registers)
0154 );
0155 }
0156
0157 static void switch_extension(Thread_Control *executing, Thread_Control *heir)
0158 {
0159 test_context *ctx = &test_instance;
0160 SMP_lock_Context lock_context;
0161 size_t i;
0162
0163 _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
0164
0165 i = ctx->switch_index;
0166 if (i < SWITCH_EVENT_COUNT) {
0167 switch_event *e = &ctx->switch_events[i];
0168 Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node(heir);
0169
0170 e->cpu_index = rtems_scheduler_get_processor();
0171 e->executing = executing;
0172 e->heir = heir;
0173 e->heir_node = _Scheduler_Node_get_owner(&node->Base);
0174 e->heir_priority = node->priority;
0175
0176 ctx->switch_index = i + 1;
0177 }
0178
0179 _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
0180 }
0181
0182 static void reset_switch_events(test_context *ctx)
0183 {
0184 SMP_lock_Context lock_context;
0185
0186 _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
0187 ctx->switch_index = 0;
0188 _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
0189 }
0190
0191 static size_t get_switch_events(test_context *ctx)
0192 {
0193 SMP_lock_Context lock_context;
0194 size_t events;
0195
0196 _SMP_lock_ISR_disable_and_acquire(&ctx->switch_lock, &lock_context);
0197 events = ctx->switch_index;
0198 _SMP_lock_Release_and_ISR_enable(&ctx->switch_lock, &lock_context);
0199
0200 return events;
0201 }
0202
0203 static void print_switch_events(test_context *ctx)
0204 {
0205 size_t n = get_switch_events(ctx);
0206 size_t i;
0207
0208 for (i = 0; i < n; ++i) {
0209 switch_event *e = &ctx->switch_events[i];
0210 char ex[5];
0211 char hr[5];
0212 char hn[5];
0213
0214 rtems_object_get_name(e->executing->Object.id, sizeof(ex), &ex[0]);
0215 rtems_object_get_name(e->heir->Object.id, sizeof(hr), &hr[0]);
0216 rtems_object_get_name(e->heir_node->Object.id, sizeof(hn), &hn[0]);
0217
0218 printf(
0219 "[%" PRIu32 "] %4s -> %4s (prio %3" PRIu64 ", node %4s)\n",
0220 e->cpu_index,
0221 &ex[0],
0222 &hr[0],
0223 e->heir_priority,
0224 &hn[0]
0225 );
0226 }
0227 }
0228
0229 static void create_timer(test_context *ctx)
0230 {
0231 rtems_status_code sc;
0232
0233 sc = rtems_timer_create(
0234 rtems_build_name('T', 'I', 'M', 'R'),
0235 &ctx->timer_id
0236 );
0237 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0238 }
0239
0240 static void delete_timer(test_context *ctx)
0241 {
0242 rtems_status_code sc;
0243
0244 sc = rtems_timer_delete(ctx->timer_id);
0245 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0246 }
0247
0248 static void fire_timer(
0249 test_context *ctx,
0250 rtems_interval interval,
0251 rtems_timer_service_routine_entry routine
0252 )
0253 {
0254 rtems_status_code sc;
0255
0256 sc = rtems_timer_fire_after(ctx->timer_id, interval, routine, ctx);
0257 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0258 }
0259
0260 static void create_mrsp_sema(
0261 test_context *ctx,
0262 rtems_id *id,
0263 rtems_task_priority prio
0264 )
0265 {
0266 uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
0267 uint32_t index;
0268 rtems_status_code sc;
0269
0270 sc = rtems_semaphore_create(
0271 rtems_build_name('M', 'R', 'S', 'P'),
0272 1,
0273 RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
0274 RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
0275 prio,
0276 id
0277 );
0278 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0279
0280 for (index = 1; index < cpu_count; index = ((index + 2) & ~UINT32_C(1))) {
0281 rtems_task_priority old_prio;
0282
0283 old_prio = 1;
0284 sc = rtems_semaphore_set_priority(
0285 *id,
0286 ctx->scheduler_ids[index],
0287 prio,
0288 &old_prio
0289 );
0290 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0291 rtems_test_assert(old_prio == 0);
0292 }
0293 }
0294
0295 static void run_task(rtems_task_argument arg)
0296 {
0297 volatile bool *run = (volatile bool *) arg;
0298
0299 *run = true;
0300
0301 while (true) {
0302
0303 }
0304 }
0305
0306 static void obtain_and_release_worker(rtems_task_argument arg)
0307 {
0308 test_context *ctx = &test_instance;
0309 rtems_status_code sc;
0310 SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
0311
0312 ctx->worker_task = _Thread_Get_executing();
0313
0314 assert_prio(RTEMS_SELF, 4);
0315
0316
0317 barrier(ctx, &barrier_state);
0318
0319 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
0320 rtems_test_assert(sc == RTEMS_TIMEOUT);
0321
0322 assert_prio(RTEMS_SELF, 4);
0323
0324
0325 barrier(ctx, &barrier_state);
0326
0327 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
0328 rtems_test_assert(sc == RTEMS_TIMEOUT);
0329
0330 assert_prio(RTEMS_SELF, 2);
0331
0332
0333 barrier(ctx, &barrier_state);
0334
0335
0336 barrier(ctx, &barrier_state);
0337
0338 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0339 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0340
0341 assert_prio(RTEMS_SELF, 3);
0342
0343 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0344 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0345
0346 assert_prio(RTEMS_SELF, 4);
0347
0348
0349 barrier(ctx, &barrier_state);
0350
0351 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, 4);
0352 rtems_test_assert(sc == RTEMS_TIMEOUT);
0353
0354 assert_prio(RTEMS_SELF, 4);
0355
0356 sc = rtems_task_suspend(ctx->high_task_id[0]);
0357 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0358
0359
0360 barrier(ctx, &barrier_state);
0361
0362 while (true) {
0363
0364 }
0365 }
0366
0367 static void test_mrsp_obtain_and_release(test_context *ctx)
0368 {
0369 rtems_status_code sc;
0370 rtems_task_priority prio;
0371 rtems_id scheduler_id;
0372 SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
0373
0374 puts("test MrsP obtain and release");
0375
0376 change_prio(RTEMS_SELF, 3);
0377
0378 barrier_init(ctx);
0379 reset_switch_events(ctx);
0380
0381 ctx->high_run[0] = false;
0382
0383 sc = rtems_task_create(
0384 rtems_build_name('H', 'I', 'G', '0'),
0385 1,
0386 RTEMS_MINIMUM_STACK_SIZE,
0387 RTEMS_DEFAULT_MODES,
0388 RTEMS_DEFAULT_ATTRIBUTES,
0389 &ctx->high_task_id[0]
0390 );
0391 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0392
0393
0394
0395 sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
0396 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0397
0398 rtems_test_assert(ctx->scheduler_ids[0] == scheduler_id);
0399
0400
0401
0402 create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 2);
0403
0404 assert_prio(RTEMS_SELF, 3);
0405
0406 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0407 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0408
0409 assert_prio(RTEMS_SELF, 2);
0410
0411
0412
0413
0414
0415
0416 prio = RTEMS_CURRENT_PRIORITY;
0417 sc = rtems_semaphore_set_priority(
0418 ctx->mrsp_ids[0],
0419 ctx->scheduler_ids[0],
0420 prio,
0421 &prio
0422 );
0423 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0424 rtems_test_assert(prio == 2);
0425
0426
0427
0428 prio = 3;
0429 sc = rtems_semaphore_set_priority(
0430 ctx->mrsp_ids[0],
0431 ctx->scheduler_ids[1],
0432 prio,
0433 &prio
0434 );
0435 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0436 rtems_test_assert(prio == 2);
0437
0438
0439
0440 prio = RTEMS_CURRENT_PRIORITY;
0441 sc = rtems_semaphore_set_priority(
0442 ctx->mrsp_ids[0],
0443 ctx->scheduler_ids[0],
0444 prio,
0445 &prio
0446 );
0447 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0448 rtems_test_assert(prio == 2);
0449
0450 prio = RTEMS_CURRENT_PRIORITY;
0451 sc = rtems_semaphore_set_priority(
0452 ctx->mrsp_ids[0],
0453 ctx->scheduler_ids[1],
0454 prio,
0455 &prio
0456 );
0457 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0458 rtems_test_assert(prio == 3);
0459
0460
0461
0462 sc = rtems_task_create(
0463 rtems_build_name('W', 'O', 'R', 'K'),
0464 255,
0465 RTEMS_MINIMUM_STACK_SIZE,
0466 RTEMS_DEFAULT_MODES,
0467 RTEMS_DEFAULT_ATTRIBUTES,
0468 &ctx->worker_ids[0]
0469 );
0470 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0471
0472 sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1], 4);
0473 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0474
0475 sc = rtems_task_start(ctx->worker_ids[0], obtain_and_release_worker, 0);
0476 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0477
0478
0479 barrier_and_delay(ctx, &barrier_state);
0480
0481 assert_prio(ctx->worker_ids[0], 3);
0482 assert_executing_worker(ctx);
0483
0484
0485 barrier_and_delay(ctx, &barrier_state);
0486
0487 assert_prio(ctx->worker_ids[0], 3);
0488 change_prio(ctx->worker_ids[0], 2);
0489 assert_executing_worker(ctx);
0490
0491
0492 barrier(ctx, &barrier_state);
0493
0494 assert_prio(ctx->worker_ids[0], 2);
0495 change_prio(ctx->worker_ids[0], 4);
0496
0497
0498 barrier_and_delay(ctx, &barrier_state);
0499
0500 assert_prio(ctx->worker_ids[0], 3);
0501 assert_executing_worker(ctx);
0502
0503 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0504 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0505
0506
0507
0508 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0509 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0510
0511
0512 barrier_and_delay(ctx, &barrier_state);
0513
0514 sc = rtems_task_start(
0515 ctx->high_task_id[0],
0516 run_task,
0517 (rtems_task_argument) &ctx->high_run[0]
0518 );
0519 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0520
0521 rtems_test_assert(rtems_scheduler_get_processor() == 1);
0522
0523 while (rtems_scheduler_get_processor() != 0) {
0524
0525 }
0526
0527 rtems_test_assert(ctx->high_run[0]);
0528
0529 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0530 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0531
0532 print_switch_events(ctx);
0533
0534
0535 barrier(ctx, &barrier_state);
0536
0537 sc = rtems_task_delete(ctx->worker_ids[0]);
0538 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0539
0540 sc = rtems_task_delete(ctx->high_task_id[0]);
0541 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0542
0543 sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
0544 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0545 }
0546
0547 static void obtain_after_migration_worker(rtems_task_argument arg)
0548 {
0549 test_context *ctx = &test_instance;
0550 rtems_status_code sc;
0551 SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
0552
0553 assert_prio(RTEMS_SELF, 3);
0554
0555 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0556 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0557
0558 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0559 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0560
0561
0562 barrier(ctx, &barrier_state);
0563
0564 while (true) {
0565
0566 }
0567 }
0568
0569 static void obtain_after_migration_high(rtems_task_argument arg)
0570 {
0571 test_context *ctx = &test_instance;
0572 rtems_status_code sc;
0573 SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
0574
0575 assert_prio(RTEMS_SELF, 2);
0576
0577 sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0578 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0579
0580
0581 barrier(ctx, &barrier_state);
0582
0583
0584 barrier(ctx, &barrier_state);
0585
0586 sc = rtems_semaphore_release(ctx->mrsp_ids[1]);
0587 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0588
0589 rtems_task_suspend(RTEMS_SELF);
0590 rtems_test_assert(0);
0591 }
0592
0593 static void test_mrsp_obtain_after_migration(test_context *ctx)
0594 {
0595 rtems_status_code sc;
0596 rtems_task_priority prio;
0597 rtems_id scheduler_id;
0598 SMP_barrier_State barrier_state;
0599
0600 puts("test MrsP obtain after migration");
0601
0602 change_prio(RTEMS_SELF, 3);
0603
0604 barrier_init(ctx);
0605 reset_switch_events(ctx);
0606
0607
0608
0609 sc = rtems_task_create(
0610 rtems_build_name('H', 'I', 'G', '0'),
0611 2,
0612 RTEMS_MINIMUM_STACK_SIZE,
0613 RTEMS_DEFAULT_MODES,
0614 RTEMS_DEFAULT_ATTRIBUTES,
0615 &ctx->high_task_id[0]
0616 );
0617 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0618
0619 sc = rtems_task_create(
0620 rtems_build_name('W', 'O', 'R', 'K'),
0621 255,
0622 RTEMS_MINIMUM_STACK_SIZE,
0623 RTEMS_DEFAULT_MODES,
0624 RTEMS_DEFAULT_ATTRIBUTES,
0625 &ctx->worker_ids[0]
0626 );
0627 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0628
0629 sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1], 3);
0630 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0631
0632
0633
0634 create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 3);
0635 create_mrsp_sema(ctx, &ctx->mrsp_ids[1], 2);
0636 create_mrsp_sema(ctx, &ctx->mrsp_ids[2], 1);
0637
0638 prio = 4;
0639 sc = rtems_semaphore_set_priority(
0640 ctx->mrsp_ids[2],
0641 ctx->scheduler_ids[1],
0642 prio,
0643 &prio
0644 );
0645 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0646 rtems_test_assert(prio == 1);
0647
0648
0649
0650 sc = rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id);
0651 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0652
0653 rtems_test_assert(ctx->scheduler_ids[0] == scheduler_id);
0654
0655 assert_prio(RTEMS_SELF, 3);
0656
0657 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0658 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0659
0660 assert_prio(RTEMS_SELF, 3);
0661
0662
0663
0664 sc = rtems_task_start(ctx->worker_ids[0], obtain_after_migration_worker, 0);
0665 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0666
0667 sc = rtems_task_start(ctx->high_task_id[0], obtain_after_migration_high, 0);
0668 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0669
0670 rtems_test_assert(rtems_scheduler_get_processor() == 1);
0671
0672
0673 _SMP_barrier_State_initialize(&barrier_state);
0674 barrier(ctx, &barrier_state);
0675
0676 sc = rtems_task_suspend(ctx->high_task_id[0]);
0677 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0678
0679 rtems_test_assert(rtems_scheduler_get_processor() == 1);
0680
0681
0682
0683
0684
0685
0686 sc = rtems_semaphore_obtain(ctx->mrsp_ids[2], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0687 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0688
0689 assert_prio(RTEMS_SELF, 1);
0690
0691 rtems_test_assert(rtems_scheduler_get_processor() == 1);
0692
0693 sc = rtems_semaphore_release(ctx->mrsp_ids[2]);
0694 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0695
0696 sc = rtems_task_resume(ctx->high_task_id[0]);
0697 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0698
0699
0700 barrier(ctx, &barrier_state);
0701
0702 rtems_test_assert(rtems_scheduler_get_processor() == 1);
0703
0704
0705 barrier_init(ctx);
0706 _SMP_barrier_State_initialize(&barrier_state);
0707
0708 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0709 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0710
0711 rtems_test_assert(rtems_scheduler_get_processor() == 0);
0712
0713 print_switch_events(ctx);
0714
0715
0716 barrier(ctx, &barrier_state);
0717
0718 sc = rtems_task_delete(ctx->worker_ids[0]);
0719 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0720
0721 sc = rtems_task_delete(ctx->high_task_id[0]);
0722 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0723
0724 sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
0725 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0726
0727 sc = rtems_semaphore_delete(ctx->mrsp_ids[1]);
0728 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0729
0730 sc = rtems_semaphore_delete(ctx->mrsp_ids[2]);
0731 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0732 }
0733
0734 static void test_mrsp_flush_error(test_context *ctx)
0735 {
0736 rtems_status_code sc;
0737 rtems_id id;
0738
0739 puts("test MrsP flush error");
0740
0741 create_mrsp_sema(ctx, &id, 1);
0742
0743 sc = rtems_semaphore_flush(id);
0744 rtems_test_assert(sc == RTEMS_NOT_DEFINED);
0745
0746 sc = rtems_semaphore_delete(id);
0747 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0748 }
0749
0750 static void test_mrsp_initially_locked(void)
0751 {
0752 rtems_status_code sc;
0753 rtems_id id;
0754
0755 puts("test MrsP initially locked");
0756
0757 sc = rtems_semaphore_create(
0758 rtems_build_name('M', 'R', 'S', 'P'),
0759 0,
0760 RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
0761 RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
0762 1,
0763 &id
0764 );
0765 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0766
0767 sc = rtems_semaphore_release(id);
0768 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0769
0770 sc = rtems_semaphore_delete(id);
0771 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0772 }
0773
0774 static void test_mrsp_nested_obtain_error(test_context *ctx)
0775 {
0776 rtems_status_code sc;
0777 rtems_id id;
0778
0779 puts("test MrsP nested obtain error");
0780
0781 create_mrsp_sema(ctx, &id, 1);
0782
0783 sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0784 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0785
0786 sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0787 rtems_test_assert(sc == RTEMS_INCORRECT_STATE);
0788
0789 sc = rtems_semaphore_release(id);
0790 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0791
0792 sc = rtems_semaphore_delete(id);
0793 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0794 }
0795
0796 static void deadlock_timer(rtems_id timer_id, void *arg)
0797 {
0798 test_context *ctx = arg;
0799
0800 change_prio(ctx->main_task_id, 1);
0801 }
0802
0803 static void deadlock_worker(rtems_task_argument arg)
0804 {
0805 test_context *ctx = &test_instance;
0806 rtems_status_code sc;
0807
0808 sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0809 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0810
0811 fire_timer(ctx, 2, deadlock_timer);
0812
0813 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0814 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0815
0816 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0817 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0818
0819 sc = rtems_semaphore_release(ctx->mrsp_ids[1]);
0820 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0821
0822 sc = rtems_event_transient_send(ctx->main_task_id);
0823 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0824
0825 rtems_task_suspend(RTEMS_SELF);
0826 rtems_test_assert(0);
0827 }
0828
0829 static void test_mrsp_deadlock_error(test_context *ctx)
0830 {
0831 rtems_status_code sc;
0832 rtems_task_priority prio = 2;
0833
0834 puts("test MrsP deadlock error");
0835
0836 change_prio(RTEMS_SELF, prio);
0837
0838 create_timer(ctx);
0839 create_mrsp_sema(ctx, &ctx->mrsp_ids[0], prio);
0840 create_mrsp_sema(ctx, &ctx->mrsp_ids[1], prio);
0841
0842 sc = rtems_task_create(
0843 rtems_build_name('W', 'O', 'R', 'K'),
0844 prio,
0845 RTEMS_MINIMUM_STACK_SIZE,
0846 RTEMS_DEFAULT_MODES,
0847 RTEMS_DEFAULT_ATTRIBUTES,
0848 &ctx->worker_ids[0]
0849 );
0850 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0851
0852 sc = rtems_task_start(ctx->worker_ids[0], deadlock_worker, 0);
0853 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0854
0855 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0856 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0857
0858 sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
0859 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0860
0861 prio = 1;
0862 sc = rtems_semaphore_set_priority(
0863 ctx->mrsp_ids[1],
0864 ctx->scheduler_ids[0],
0865 prio,
0866 &prio
0867 );
0868 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0869 rtems_test_assert(prio == 2);
0870
0871 sc = rtems_semaphore_obtain(ctx->mrsp_ids[1], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0872 rtems_test_assert(sc == RTEMS_INCORRECT_STATE);
0873
0874 sc = rtems_semaphore_set_priority(
0875 ctx->mrsp_ids[1],
0876 ctx->scheduler_ids[0],
0877 prio,
0878 &prio
0879 );
0880 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0881
0882 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
0883 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0884
0885 sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0886 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0887
0888 sc = rtems_task_delete(ctx->worker_ids[0]);
0889 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0890
0891 sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
0892 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0893
0894 sc = rtems_semaphore_delete(ctx->mrsp_ids[1]);
0895 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0896
0897 delete_timer(ctx);
0898 }
0899
0900 static void test_mrsp_multiple_obtain(test_context *ctx)
0901 {
0902 rtems_status_code sc;
0903 rtems_id sem_a_id;
0904 rtems_id sem_b_id;
0905 rtems_id sem_c_id;
0906
0907 puts("test MrsP multiple obtain");
0908
0909 change_prio(RTEMS_SELF, 4);
0910
0911 create_mrsp_sema(ctx, &sem_a_id, 3);
0912 create_mrsp_sema(ctx, &sem_b_id, 2);
0913 create_mrsp_sema(ctx, &sem_c_id, 1);
0914
0915 assert_prio(RTEMS_SELF, 4);
0916
0917 sc = rtems_semaphore_obtain(sem_a_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0918 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0919
0920 assert_prio(RTEMS_SELF, 3);
0921
0922 sc = rtems_semaphore_obtain(sem_b_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0923 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0924
0925 assert_prio(RTEMS_SELF, 2);
0926
0927 sc = rtems_semaphore_obtain(sem_c_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0928 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0929
0930 assert_prio(RTEMS_SELF, 1);
0931
0932 sc = rtems_semaphore_release(sem_c_id);
0933 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0934
0935 assert_prio(RTEMS_SELF, 2);
0936
0937 sc = rtems_semaphore_release(sem_b_id);
0938 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0939
0940 assert_prio(RTEMS_SELF, 3);
0941
0942 sc = rtems_semaphore_release(sem_a_id);
0943 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0944
0945 assert_prio(RTEMS_SELF, 4);
0946
0947 sc = rtems_semaphore_obtain(sem_a_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0948 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0949
0950 assert_prio(RTEMS_SELF, 3);
0951
0952 sc = rtems_semaphore_obtain(sem_b_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0953 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0954
0955 assert_prio(RTEMS_SELF, 2);
0956
0957 sc = rtems_semaphore_obtain(sem_c_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0958 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0959
0960 assert_prio(RTEMS_SELF, 1);
0961 change_prio(RTEMS_SELF, 3);
0962 assert_prio(RTEMS_SELF, 1);
0963
0964 sc = rtems_semaphore_release(sem_c_id);
0965 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0966
0967 assert_prio(RTEMS_SELF, 2);
0968
0969 sc = rtems_semaphore_release(sem_b_id);
0970 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0971
0972 assert_prio(RTEMS_SELF, 3);
0973
0974 sc = rtems_semaphore_release(sem_a_id);
0975 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0976
0977 assert_prio(RTEMS_SELF, 3);
0978
0979 sc = rtems_semaphore_delete(sem_a_id);
0980 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0981
0982 sc = rtems_semaphore_delete(sem_b_id);
0983 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0984
0985 sc = rtems_semaphore_delete(sem_c_id);
0986 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0987 }
0988
0989 static void ready_unlock_worker(rtems_task_argument arg)
0990 {
0991 test_context *ctx = &test_instance;
0992 rtems_status_code sc;
0993 SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
0994
0995 assert_prio(RTEMS_SELF, 4);
0996
0997
0998 barrier(ctx, &barrier_state);
0999
1000 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1001 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1002
1003 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1004 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1005
1006 assert_prio(RTEMS_SELF, 4);
1007
1008
1009 barrier(ctx, &barrier_state);
1010
1011 while (true) {
1012
1013 }
1014 }
1015
1016 static void unblock_ready_timer(rtems_id timer_id, void *arg)
1017 {
1018 test_context *ctx = arg;
1019 rtems_status_code sc;
1020
1021 sc = rtems_task_start(
1022 ctx->high_task_id[0],
1023 run_task,
1024 (rtems_task_argument) &ctx->high_run[0]
1025 );
1026 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1027
1028 sc = rtems_task_suspend(ctx->high_task_id[0]);
1029 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1030
1031 sc = rtems_task_resume(ctx->high_task_id[0]);
1032 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1033
1034
1035
1036
1037
1038
1039 sc = rtems_event_transient_send(ctx->main_task_id);
1040 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1041
1042 sc = rtems_task_suspend(ctx->high_task_id[0]);
1043 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1044 }
1045
1046 static void unblock_ready_owner(test_context *ctx)
1047 {
1048 rtems_status_code sc;
1049
1050 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1051 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1052
1053 assert_prio(RTEMS_SELF, 3);
1054
1055 fire_timer(ctx, 2, unblock_ready_timer);
1056
1057 sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1058 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1059
1060 rtems_test_assert(!ctx->high_run[0]);
1061 }
1062
1063 static void unblock_owner_before_rival_timer(rtems_id timer_id, void *arg)
1064 {
1065 test_context *ctx = arg;
1066 rtems_status_code sc;
1067
1068 sc = rtems_task_suspend(ctx->high_task_id[0]);
1069 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1070
1071 sc = rtems_task_suspend(ctx->high_task_id[1]);
1072 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1073 }
1074
1075 static void unblock_owner_after_rival_timer(rtems_id timer_id, void *arg)
1076 {
1077 test_context *ctx = arg;
1078 rtems_status_code sc;
1079
1080 sc = rtems_task_suspend(ctx->high_task_id[1]);
1081 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1082
1083 sc = rtems_task_suspend(ctx->high_task_id[0]);
1084 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1085 }
1086
1087 static void various_block_unblock(test_context *ctx)
1088 {
1089 rtems_status_code sc;
1090 SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
1091
1092
1093 barrier_and_delay(ctx, &barrier_state);
1094
1095 sc = rtems_task_suspend(ctx->worker_ids[0]);
1096 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1097
1098 busy_wait();
1099
1100 sc = rtems_task_start(
1101 ctx->high_task_id[1],
1102 run_task,
1103 (rtems_task_argument) &ctx->high_run[1]
1104 );
1105 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1106
1107 while (!ctx->high_run[1]) {
1108
1109 }
1110
1111 sc = rtems_task_resume(ctx->worker_ids[0]);
1112 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1113
1114
1115
1116 sc = rtems_task_suspend(ctx->worker_ids[0]);
1117 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1118
1119 sc = rtems_task_suspend(ctx->high_task_id[1]);
1120 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1121
1122 sc = rtems_task_resume(ctx->high_task_id[1]);
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 rtems_test_assert(rtems_scheduler_get_processor() == 0);
1129
1130
1131
1132 sc = rtems_task_suspend(ctx->high_task_id[1]);
1133 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1134
1135 sc = rtems_task_resume(ctx->high_task_id[0]);
1136 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1137
1138 rtems_test_assert(rtems_scheduler_get_processor() == 1);
1139
1140 sc = rtems_task_suspend(ctx->worker_ids[0]);
1141 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1142
1143 sc = rtems_task_resume(ctx->worker_ids[0]);
1144 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1145
1146
1147
1148
1149
1150
1151 fire_timer(ctx, 2, unblock_owner_before_rival_timer);
1152
1153
1154 sc = rtems_task_resume(ctx->high_task_id[1]);
1155 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1156
1157
1158
1159
1160
1161
1162 sc = rtems_task_resume(ctx->high_task_id[0]);
1163 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1164
1165 fire_timer(ctx, 2, unblock_owner_after_rival_timer);
1166
1167
1168 sc = rtems_task_resume(ctx->high_task_id[1]);
1169 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1170
1171 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1172 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1173
1174 rtems_test_assert(rtems_scheduler_get_processor() == 0);
1175
1176 assert_prio(RTEMS_SELF, 4);
1177
1178
1179 barrier(ctx, &barrier_state);
1180 }
1181
1182 static void start_low_task(test_context *ctx, size_t i)
1183 {
1184 rtems_status_code sc;
1185
1186 sc = rtems_task_create(
1187 rtems_build_name('L', 'O', 'W', '0' + i),
1188 255,
1189 RTEMS_MINIMUM_STACK_SIZE,
1190 RTEMS_DEFAULT_MODES,
1191 RTEMS_DEFAULT_ATTRIBUTES,
1192 &ctx->low_task_id[i]
1193 );
1194 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1195
1196 sc = rtems_task_set_scheduler(ctx->low_task_id[i], ctx->scheduler_ids[i], 5);
1197 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1198
1199 sc = rtems_task_start(
1200 ctx->low_task_id[i],
1201 run_task,
1202 (rtems_task_argument) &ctx->low_run[i]
1203 );
1204 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1205 }
1206
1207 static void test_mrsp_various_block_and_unblock(test_context *ctx)
1208 {
1209 rtems_status_code sc;
1210
1211 puts("test MrsP various block and unblock");
1212
1213 change_prio(RTEMS_SELF, 4);
1214
1215 barrier_init(ctx);
1216 reset_switch_events(ctx);
1217
1218 ctx->low_run[0] = false;
1219 ctx->low_run[1] = false;
1220 ctx->high_run[0] = false;
1221 ctx->high_run[1] = false;
1222
1223 create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 3);
1224 assert_prio(RTEMS_SELF, 4);
1225
1226 sc = rtems_task_create(
1227 rtems_build_name('H', 'I', 'G', '0'),
1228 2,
1229 RTEMS_MINIMUM_STACK_SIZE,
1230 RTEMS_DEFAULT_MODES,
1231 RTEMS_DEFAULT_ATTRIBUTES,
1232 &ctx->high_task_id[0]
1233 );
1234 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1235
1236 sc = rtems_task_create(
1237 rtems_build_name('H', 'I', 'G', '1'),
1238 255,
1239 RTEMS_MINIMUM_STACK_SIZE,
1240 RTEMS_DEFAULT_MODES,
1241 RTEMS_DEFAULT_ATTRIBUTES,
1242 &ctx->high_task_id[1]
1243 );
1244 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1245
1246 sc = rtems_task_set_scheduler(ctx->high_task_id[1], ctx->scheduler_ids[1], 2);
1247 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1248
1249 sc = rtems_task_create(
1250 rtems_build_name('W', 'O', 'R', 'K'),
1251 255,
1252 RTEMS_MINIMUM_STACK_SIZE,
1253 RTEMS_DEFAULT_MODES,
1254 RTEMS_DEFAULT_ATTRIBUTES,
1255 &ctx->worker_ids[0]
1256 );
1257 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1258
1259 sc = rtems_task_set_scheduler(ctx->worker_ids[0], ctx->scheduler_ids[1], 4);
1260 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1261
1262 sc = rtems_task_start(ctx->worker_ids[0], ready_unlock_worker, 0);
1263 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1264
1265 create_timer(ctx);
1266
1267
1268 start_low_task(ctx, 0);
1269 start_low_task(ctx, 1);
1270
1271 unblock_ready_owner(ctx);
1272 various_block_unblock(ctx);
1273
1274 rtems_test_assert(!ctx->low_run[0]);
1275 rtems_test_assert(!ctx->low_run[1]);
1276
1277 print_switch_events(ctx);
1278 delete_timer(ctx);
1279
1280 sc = rtems_task_delete(ctx->high_task_id[0]);
1281 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1282
1283 sc = rtems_task_delete(ctx->high_task_id[1]);
1284 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1285
1286 sc = rtems_task_delete(ctx->worker_ids[0]);
1287 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1288
1289 sc = rtems_task_delete(ctx->low_task_id[0]);
1290 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1291
1292 sc = rtems_task_delete(ctx->low_task_id[1]);
1293 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1294
1295 sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
1296 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1297 }
1298
1299 static void test_mrsp_obtain_and_sleep_and_release(test_context *ctx)
1300 {
1301 rtems_status_code sc;
1302 rtems_id sem_id;
1303 rtems_id run_task_id;
1304 volatile bool run = false;
1305
1306 puts("test MrsP obtain and sleep and release");
1307
1308 change_prio(RTEMS_SELF, 1);
1309
1310 reset_switch_events(ctx);
1311
1312 sc = rtems_task_create(
1313 rtems_build_name(' ', 'R', 'U', 'N'),
1314 2,
1315 RTEMS_MINIMUM_STACK_SIZE,
1316 RTEMS_DEFAULT_MODES,
1317 RTEMS_DEFAULT_ATTRIBUTES,
1318 &run_task_id
1319 );
1320 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1321
1322 sc = rtems_task_start(run_task_id, run_task, (rtems_task_argument) &run);
1323 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1324
1325 create_mrsp_sema(ctx, &sem_id, 1);
1326
1327 rtems_test_assert(!run);
1328
1329 sc = rtems_task_wake_after(2);
1330 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1331
1332 rtems_test_assert(run);
1333 run = false;
1334
1335 sc = rtems_semaphore_obtain(sem_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1336 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1337
1338 rtems_test_assert(!run);
1339
1340 sc = rtems_task_wake_after(2);
1341 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1342
1343 rtems_test_assert(!run);
1344
1345 sc = rtems_semaphore_release(sem_id);
1346 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1347
1348 print_switch_events(ctx);
1349
1350 sc = rtems_semaphore_delete(sem_id);
1351 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1352
1353 sc = rtems_task_delete(run_task_id);
1354 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1355 }
1356
1357 static void help_task(rtems_task_argument arg)
1358 {
1359 test_context *ctx = &test_instance;
1360 rtems_status_code sc;
1361
1362 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1363 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1364
1365 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1366 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1367
1368 while (true) {
1369
1370 }
1371 }
1372
1373 static void test_mrsp_obtain_and_release_with_help(test_context *ctx)
1374 {
1375 rtems_status_code sc;
1376 rtems_id help_task_id;
1377 rtems_id run_task_id;
1378 volatile bool run = false;
1379
1380 puts("test MrsP obtain and release with help");
1381
1382 change_prio(RTEMS_SELF, 3);
1383
1384 reset_switch_events(ctx);
1385
1386 create_mrsp_sema(ctx, &ctx->mrsp_ids[0], 2);
1387
1388 sc = rtems_semaphore_obtain(ctx->mrsp_ids[0], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1389 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1390
1391 assert_prio(RTEMS_SELF, 2);
1392
1393 sc = rtems_task_create(
1394 rtems_build_name('H', 'E', 'L', 'P'),
1395 255,
1396 RTEMS_MINIMUM_STACK_SIZE,
1397 RTEMS_DEFAULT_MODES,
1398 RTEMS_DEFAULT_ATTRIBUTES,
1399 &help_task_id
1400 );
1401 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1402
1403 sc = rtems_task_set_scheduler(
1404 help_task_id,
1405 ctx->scheduler_ids[1],
1406 3
1407 );
1408 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1409
1410 sc = rtems_task_start(help_task_id, help_task, 0);
1411 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1412
1413 sc = rtems_task_create(
1414 rtems_build_name(' ', 'R', 'U', 'N'),
1415 4,
1416 RTEMS_MINIMUM_STACK_SIZE,
1417 RTEMS_DEFAULT_MODES,
1418 RTEMS_DEFAULT_ATTRIBUTES,
1419 &run_task_id
1420 );
1421 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1422
1423 sc = rtems_task_start(run_task_id, run_task, (rtems_task_argument) &run);
1424 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1425
1426 wait_for_prio(help_task_id, 2);
1427
1428 sc = rtems_task_wake_after(2);
1429 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1430
1431 rtems_test_assert(rtems_scheduler_get_processor() == 0);
1432 rtems_test_assert(!run);
1433
1434 change_prio(run_task_id, 1);
1435
1436 rtems_test_assert(rtems_scheduler_get_processor() == 1);
1437
1438 while (!run) {
1439
1440 }
1441
1442 sc = rtems_task_wake_after(2);
1443 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1444
1445 rtems_test_assert(rtems_scheduler_get_processor() == 1);
1446
1447 change_prio(run_task_id, 4);
1448
1449 rtems_test_assert(rtems_scheduler_get_processor() == 1);
1450
1451
1452
1453
1454
1455 sc = rtems_task_suspend(run_task_id);
1456 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1457
1458 rtems_test_assert(rtems_scheduler_get_processor() == 1);
1459
1460 change_prio(RTEMS_SELF, 1);
1461 change_prio(RTEMS_SELF, 3);
1462
1463 sc = rtems_semaphore_release(ctx->mrsp_ids[0]);
1464 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1465
1466 rtems_test_assert(rtems_scheduler_get_processor() == 0);
1467
1468 assert_prio(RTEMS_SELF, 3);
1469
1470 wait_for_prio(help_task_id, 3);
1471
1472 print_switch_events(ctx);
1473
1474 sc = rtems_semaphore_delete(ctx->mrsp_ids[0]);
1475 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1476
1477 sc = rtems_task_delete(help_task_id);
1478 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1479
1480 sc = rtems_task_delete(run_task_id);
1481 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1482 }
1483
1484 static uint32_t simple_random(uint32_t v)
1485 {
1486 v *= 1664525;
1487 v += 1013904223;
1488
1489 return v;
1490 }
1491
1492 static rtems_interval timeout(uint32_t v)
1493 {
1494 return (v >> 23) % 4;
1495 }
1496
1497 static void load_worker(rtems_task_argument index)
1498 {
1499 test_context *ctx = &test_instance;
1500 rtems_status_code sc;
1501 uint32_t v = index;
1502
1503 while (!ctx->stop_worker[index]) {
1504 uint32_t i = (v >> 13) % MRSP_COUNT;
1505
1506 assert_prio(RTEMS_SELF, 3 + CPU_COUNT + index);
1507
1508 if ((v >> 7) % 1024 == 0) {
1509
1510
1511 ++ctx->counters[index].sleep;
1512
1513 sc = rtems_task_wake_after(1);
1514 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1515
1516 ++ctx->counters[index].cpu[rtems_scheduler_get_processor()];
1517 } else {
1518 uint32_t n = (v >> 17) % (i + 1);
1519 uint32_t s;
1520 uint32_t t;
1521
1522
1523 for (s = 0; s <= n; ++s) {
1524 uint32_t k = i - s;
1525
1526 sc = rtems_semaphore_obtain(ctx->mrsp_ids[k], RTEMS_WAIT, timeout(v));
1527 if (sc == RTEMS_SUCCESSFUL) {
1528 ++ctx->counters[index].obtain[n];
1529
1530 assert_prio(RTEMS_SELF, 3 + k);
1531 } else {
1532 rtems_test_assert(sc == RTEMS_TIMEOUT);
1533
1534 ++ctx->counters[index].timeout;
1535
1536 break;
1537 }
1538
1539 ++ctx->counters[index].cpu[rtems_scheduler_get_processor()];
1540
1541 v = simple_random(v);
1542 }
1543
1544
1545 for (t = 0; t < s; ++t) {
1546 uint32_t k = i + t - s + 1;
1547
1548 sc = rtems_semaphore_release(ctx->mrsp_ids[k]);
1549 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1550
1551 ++ctx->counters[index].cpu[rtems_scheduler_get_processor()];
1552 }
1553 }
1554
1555 v = simple_random(v);
1556 }
1557
1558 sc = rtems_semaphore_release(ctx->counting_sem_id);
1559 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1560
1561 rtems_task_suspend(RTEMS_SELF);
1562 rtems_test_assert(0);
1563 }
1564
1565 static void migration_task(rtems_task_argument arg)
1566 {
1567 test_context *ctx = &test_instance;
1568 rtems_status_code sc;
1569 uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
1570 uint32_t v = 0xdeadbeef;
1571
1572 while (true) {
1573 uint32_t cpu_index = (v >> 5) % cpu_count;
1574
1575 sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->scheduler_ids[cpu_index], 2);
1576 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1577
1578 ++ctx->migration_counters[rtems_scheduler_get_processor()];
1579
1580 v = simple_random(v);
1581 }
1582 }
1583
1584 static void test_mrsp_load(test_context *ctx)
1585 {
1586 rtems_status_code sc;
1587 uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
1588 uint32_t index;
1589
1590 puts("test MrsP load");
1591
1592 change_prio(RTEMS_SELF, 2);
1593
1594 sc = rtems_task_create(
1595 rtems_build_name('M', 'I', 'G', 'R'),
1596 2,
1597 RTEMS_MINIMUM_STACK_SIZE,
1598 RTEMS_DEFAULT_MODES,
1599 RTEMS_DEFAULT_ATTRIBUTES,
1600 &ctx->migration_task_id
1601 );
1602 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1603
1604 sc = rtems_task_start(ctx->migration_task_id, migration_task, 0);
1605 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1606
1607 sc = rtems_semaphore_create(
1608 rtems_build_name('S', 'Y', 'N', 'C'),
1609 0,
1610 RTEMS_COUNTING_SEMAPHORE,
1611 0,
1612 &ctx->counting_sem_id
1613 );
1614 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1615
1616 for (index = 0; index < MRSP_COUNT; ++index) {
1617 create_mrsp_sema(ctx, &ctx->mrsp_ids[index], 3 + index);
1618 }
1619
1620 for (index = 0; index < cpu_count; ++index) {
1621 uint32_t a = 2 * index;
1622 uint32_t b = a + 1;
1623
1624 sc = rtems_task_create(
1625 'A' + a,
1626 255,
1627 RTEMS_MINIMUM_STACK_SIZE,
1628 RTEMS_DEFAULT_MODES,
1629 RTEMS_DEFAULT_ATTRIBUTES,
1630 &ctx->worker_ids[a]
1631 );
1632 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1633
1634 sc = rtems_task_set_scheduler(
1635 ctx->worker_ids[a],
1636 ctx->scheduler_ids[index],
1637 3 + MRSP_COUNT + a
1638 );
1639 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1640
1641 sc = rtems_task_start(
1642 ctx->worker_ids[a],
1643 load_worker,
1644 (rtems_task_argument) a
1645 );
1646 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1647
1648 sc = rtems_task_create(
1649 'A' + b,
1650 255,
1651 RTEMS_MINIMUM_STACK_SIZE,
1652 RTEMS_DEFAULT_MODES,
1653 RTEMS_DEFAULT_ATTRIBUTES,
1654 &ctx->worker_ids[b]
1655 );
1656 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1657
1658 sc = rtems_task_set_scheduler(
1659 ctx->worker_ids[b],
1660 ctx->scheduler_ids[index],
1661 3 + MRSP_COUNT + b
1662 );
1663 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1664
1665 sc = rtems_task_start(
1666 ctx->worker_ids[b],
1667 load_worker,
1668 (rtems_task_argument) b
1669 );
1670 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1671 }
1672
1673 sc = rtems_task_wake_after(30 * rtems_clock_get_ticks_per_second());
1674 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1675
1676 for (index = 0; index < 2 * cpu_count; ++index) {
1677 ctx->stop_worker[index] = true;
1678 }
1679
1680 for (index = 0; index < 2 * cpu_count; ++index) {
1681 sc = rtems_semaphore_obtain(
1682 ctx->counting_sem_id,
1683 RTEMS_WAIT,
1684 RTEMS_NO_TIMEOUT
1685 );
1686 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1687 }
1688
1689 for (index = 0; index < 2 * cpu_count; ++index) {
1690 sc = rtems_task_delete(ctx->worker_ids[index]);
1691 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1692 }
1693
1694 for (index = 0; index < MRSP_COUNT; ++index) {
1695 sc = rtems_semaphore_delete(ctx->mrsp_ids[index]);
1696 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1697 }
1698
1699 sc = rtems_semaphore_delete(ctx->counting_sem_id);
1700 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1701
1702 sc = rtems_task_delete(ctx->migration_task_id);
1703 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1704
1705 for (index = 0; index < 2 * cpu_count; ++index) {
1706 uint32_t nest_level;
1707 uint32_t cpu_index;
1708
1709 printf(
1710 "worker[%" PRIu32 "]\n"
1711 " sleep = %" PRIu32 "\n"
1712 " timeout = %" PRIu32 "\n",
1713 index,
1714 ctx->counters[index].sleep,
1715 ctx->counters[index].timeout
1716 );
1717
1718 for (nest_level = 0; nest_level < MRSP_COUNT; ++nest_level) {
1719 printf(
1720 " obtain[%" PRIu32 "] = %" PRIu32 "\n",
1721 nest_level,
1722 ctx->counters[index].obtain[nest_level]
1723 );
1724 }
1725
1726 for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
1727 printf(
1728 " cpu[%" PRIu32 "] = %" PRIu32 "\n",
1729 cpu_index,
1730 ctx->counters[index].cpu[cpu_index]
1731 );
1732 }
1733 }
1734
1735 for (index = 0; index < cpu_count; ++index) {
1736 printf(
1737 "migrations[%" PRIu32 "] = %" PRIu32 "\n",
1738 index,
1739 ctx->migration_counters[index]
1740 );
1741 }
1742 }
1743
1744 static void Init(rtems_task_argument arg)
1745 {
1746 test_context *ctx = &test_instance;
1747 rtems_status_code sc;
1748 rtems_resource_snapshot snapshot;
1749 uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
1750 uint32_t cpu_index;
1751
1752 TEST_BEGIN();
1753
1754 rtems_resource_snapshot_take(&snapshot);
1755
1756 ctx->main_task_id = rtems_task_self();
1757
1758 for (cpu_index = 0; cpu_index < MIN(2, cpu_count); ++cpu_index) {
1759 sc = rtems_scheduler_ident(cpu_index, &ctx->scheduler_ids[cpu_index]);
1760 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1761 }
1762
1763 for (cpu_index = 2; cpu_index < cpu_count; ++cpu_index) {
1764 sc = rtems_scheduler_ident(
1765 cpu_index / 2 + 1,
1766 &ctx->scheduler_ids[cpu_index]
1767 );
1768 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
1769 }
1770
1771 test_mrsp_flush_error(ctx);
1772 test_mrsp_initially_locked();
1773 test_mrsp_nested_obtain_error(ctx);
1774 test_mrsp_deadlock_error(ctx);
1775 test_mrsp_multiple_obtain(ctx);
1776
1777 if (cpu_count > 1) {
1778 test_mrsp_various_block_and_unblock(ctx);
1779 test_mrsp_obtain_after_migration(ctx);
1780 test_mrsp_obtain_and_sleep_and_release(ctx);
1781 test_mrsp_obtain_and_release_with_help(ctx);
1782 test_mrsp_obtain_and_release(ctx);
1783 test_mrsp_load(ctx);
1784 }
1785
1786 rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
1787
1788 TEST_END();
1789 rtems_test_exit(0);
1790 }
1791
1792 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
1793
1794 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
1795 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
1796
1797 #define CONFIGURE_MAXIMUM_TASKS (2 * CPU_COUNT + 2)
1798 #define CONFIGURE_MAXIMUM_SEMAPHORES (MRSP_COUNT + 1)
1799 #define CONFIGURE_MAXIMUM_TIMERS 1
1800
1801 #define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
1802
1803 #define CONFIGURE_SCHEDULER_SIMPLE_SMP
1804
1805 #include <rtems/scheduler.h>
1806
1807 RTEMS_SCHEDULER_SIMPLE_SMP(0);
1808 RTEMS_SCHEDULER_SIMPLE_SMP(1);
1809 RTEMS_SCHEDULER_SIMPLE_SMP(2);
1810 RTEMS_SCHEDULER_SIMPLE_SMP(3);
1811 RTEMS_SCHEDULER_SIMPLE_SMP(4);
1812 RTEMS_SCHEDULER_SIMPLE_SMP(5);
1813 RTEMS_SCHEDULER_SIMPLE_SMP(6);
1814 RTEMS_SCHEDULER_SIMPLE_SMP(7);
1815 RTEMS_SCHEDULER_SIMPLE_SMP(8);
1816 RTEMS_SCHEDULER_SIMPLE_SMP(9);
1817 RTEMS_SCHEDULER_SIMPLE_SMP(10);
1818 RTEMS_SCHEDULER_SIMPLE_SMP(11);
1819 RTEMS_SCHEDULER_SIMPLE_SMP(12);
1820 RTEMS_SCHEDULER_SIMPLE_SMP(13);
1821 RTEMS_SCHEDULER_SIMPLE_SMP(14);
1822 RTEMS_SCHEDULER_SIMPLE_SMP(15);
1823 RTEMS_SCHEDULER_SIMPLE_SMP(16);
1824
1825 #define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
1826 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(0, 0), \
1827 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(1, 1), \
1828 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(2, 2), \
1829 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(3, 3), \
1830 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(4, 4), \
1831 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(5, 5), \
1832 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(6, 6), \
1833 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(7, 7), \
1834 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(8, 8), \
1835 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(9, 9), \
1836 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(10, 10), \
1837 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(11, 11), \
1838 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(12, 12), \
1839 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(13, 13), \
1840 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(14, 14), \
1841 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(15, 15), \
1842 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(16, 16)
1843
1844 #define CONFIGURE_SCHEDULER_ASSIGNMENTS \
1845 RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
1846 RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1847 RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1848 RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1849 RTEMS_SCHEDULER_ASSIGN(3, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1850 RTEMS_SCHEDULER_ASSIGN(3, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1851 RTEMS_SCHEDULER_ASSIGN(4, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1852 RTEMS_SCHEDULER_ASSIGN(4, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1853 RTEMS_SCHEDULER_ASSIGN(5, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1854 RTEMS_SCHEDULER_ASSIGN(5, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1855 RTEMS_SCHEDULER_ASSIGN(6, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1856 RTEMS_SCHEDULER_ASSIGN(6, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1857 RTEMS_SCHEDULER_ASSIGN(7, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1858 RTEMS_SCHEDULER_ASSIGN(7, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1859 RTEMS_SCHEDULER_ASSIGN(8, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1860 RTEMS_SCHEDULER_ASSIGN(8, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1861 RTEMS_SCHEDULER_ASSIGN(9, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1862 RTEMS_SCHEDULER_ASSIGN(9, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1863 RTEMS_SCHEDULER_ASSIGN(10, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1864 RTEMS_SCHEDULER_ASSIGN(10, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1865 RTEMS_SCHEDULER_ASSIGN(11, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1866 RTEMS_SCHEDULER_ASSIGN(11, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1867 RTEMS_SCHEDULER_ASSIGN(12, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1868 RTEMS_SCHEDULER_ASSIGN(12, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1869 RTEMS_SCHEDULER_ASSIGN(13, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1870 RTEMS_SCHEDULER_ASSIGN(13, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1871 RTEMS_SCHEDULER_ASSIGN(14, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1872 RTEMS_SCHEDULER_ASSIGN(14, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1873 RTEMS_SCHEDULER_ASSIGN(15, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1874 RTEMS_SCHEDULER_ASSIGN(15, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1875 RTEMS_SCHEDULER_ASSIGN(16, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
1876 RTEMS_SCHEDULER_ASSIGN(16, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
1877
1878 #define CONFIGURE_INITIAL_EXTENSIONS \
1879 { .thread_switch = switch_extension }, \
1880 RTEMS_TEST_INITIAL_EXTENSION
1881
1882 #define CONFIGURE_INIT_TASK_NAME rtems_build_name('M', 'A', 'I', 'N')
1883 #define CONFIGURE_INIT_TASK_PRIORITY 2
1884
1885 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
1886
1887 #define CONFIGURE_INIT
1888
1889 #include <rtems/confdefs.h>