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 "tmacros.h"
0033
0034 const char rtems_test_name[] = "SMPMUTEX 1";
0035
0036 #define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
0037
0038 #define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
0039
0040 #define PART_COUNT 2
0041
0042 #define TASK_COUNT 9
0043
0044 #define PRIO_NONE 0
0045
0046
0047 #define TIMEOUT_IN_TICKS 10
0048
0049 typedef enum {
0050 REQ_WAKE_UP_MASTER = RTEMS_EVENT_0,
0051 REQ_WAKE_UP_HELPER = RTEMS_EVENT_1,
0052 REQ_MTX_OBTAIN = RTEMS_EVENT_2,
0053 REQ_MTX_OBTAIN_TIMEOUT = RTEMS_EVENT_3,
0054 REQ_MTX_OBTAIN_UNSATISFIED = RTEMS_EVENT_4,
0055 REQ_MTX_RELEASE = RTEMS_EVENT_5,
0056 REQ_MTX_2_OBTAIN = RTEMS_EVENT_6,
0057 REQ_MTX_2_RELEASE = RTEMS_EVENT_7,
0058 REQ_SEM_OBTAIN_RELEASE = RTEMS_EVENT_8,
0059 REQ_SEM_RELEASE = RTEMS_EVENT_9,
0060 REQ_SET_DONE = RTEMS_EVENT_10,
0061 REQ_WAIT_FOR_DONE = RTEMS_EVENT_11,
0062 REQ_SEND_EVENT_2 = RTEMS_EVENT_12,
0063 REQ_SEND_EVENT_3 = RTEMS_EVENT_13,
0064 REQ_CEIL_OBTAIN = RTEMS_EVENT_14,
0065 REQ_CEIL_RELEASE = RTEMS_EVENT_15
0066 } request_id;
0067
0068 typedef enum {
0069 A_1,
0070 A_2_0,
0071 A_2_1,
0072 M,
0073 B_4,
0074 B_5_0,
0075 B_5_1,
0076 H_A,
0077 H_B,
0078 NONE
0079 } task_id;
0080
0081 typedef struct {
0082 rtems_id mtx;
0083 rtems_id mtx_2;
0084 rtems_id sem;
0085 rtems_id ceil;
0086 rtems_id tasks[TASK_COUNT];
0087 Atomic_Uint done;
0088 task_id id_2;
0089 rtems_event_set events_2;
0090 task_id id_3;
0091 rtems_event_set events_3;
0092 int generation[TASK_COUNT];
0093 int expected_generation[TASK_COUNT];
0094 } test_context;
0095
0096 static test_context test_instance;
0097
0098 static void assert_cpu(uint32_t expected_cpu)
0099 {
0100 rtems_test_assert(rtems_scheduler_get_processor() == expected_cpu);
0101 }
0102
0103 static void test_task_get_priority_not_defined(test_context *ctx)
0104 {
0105 rtems_status_code sc;
0106 rtems_id scheduler_id;
0107 rtems_task_priority priority;
0108
0109 sc = rtems_scheduler_ident(SCHED_B, &scheduler_id);
0110 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0111
0112 priority = 0;
0113 sc = rtems_task_get_priority(RTEMS_SELF, scheduler_id, &priority);
0114 rtems_test_assert(sc == RTEMS_NOT_DEFINED);
0115 rtems_test_assert(priority == 0);
0116 }
0117
0118 static void start_task(
0119 test_context *ctx,
0120 task_id id,
0121 rtems_task_entry entry,
0122 rtems_task_priority prio,
0123 rtems_name scheduler
0124 )
0125 {
0126 rtems_status_code sc;
0127 rtems_id scheduler_id;
0128
0129 sc = rtems_task_create(
0130 rtems_build_name('T', 'A', 'S', 'K'),
0131 prio,
0132 RTEMS_MINIMUM_STACK_SIZE,
0133 RTEMS_DEFAULT_MODES,
0134 RTEMS_DEFAULT_ATTRIBUTES,
0135 &ctx->tasks[id]
0136 );
0137 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0138
0139 sc = rtems_scheduler_ident(scheduler, &scheduler_id);
0140 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0141
0142 sc = rtems_task_set_scheduler(ctx->tasks[id], scheduler_id, prio);
0143 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0144
0145 sc = rtems_task_start(ctx->tasks[id], entry, id);
0146 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0147 }
0148
0149 static void send_event(test_context *ctx, task_id id, rtems_event_set events)
0150 {
0151 rtems_status_code sc;
0152
0153 sc = rtems_event_send(ctx->tasks[id], events);
0154 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0155 }
0156
0157 static void set_event_2(
0158 test_context *ctx,
0159 task_id id_2,
0160 rtems_event_set events_2
0161 )
0162 {
0163 ctx->id_2 = id_2;
0164 ctx->events_2 = events_2;
0165 }
0166
0167 static void set_event_3(
0168 test_context *ctx,
0169 task_id id_3,
0170 rtems_event_set events_3
0171 )
0172 {
0173 ctx->id_3 = id_3;
0174 ctx->events_3 = events_3;
0175 }
0176
0177 static void clear_done(test_context *ctx)
0178 {
0179 _Atomic_Store_uint(&ctx->done, 0, ATOMIC_ORDER_RELAXED);
0180 }
0181
0182 static void set_done(test_context *ctx)
0183 {
0184 _Atomic_Store_uint(&ctx->done, 1, ATOMIC_ORDER_RELEASE);
0185 }
0186
0187 static bool is_done(test_context *ctx)
0188 {
0189 return _Atomic_Load_uint(&ctx->done, ATOMIC_ORDER_ACQUIRE) != 0;
0190 }
0191
0192 static void wait_for_done(test_context *ctx)
0193 {
0194 while (!is_done(ctx)) {
0195
0196 }
0197 }
0198
0199 static void request_pre_emption(test_context *ctx, task_id id)
0200 {
0201 clear_done(ctx);
0202 send_event(ctx, id, REQ_SET_DONE);
0203 wait_for_done(ctx);
0204 }
0205
0206 static rtems_event_set wait_for_events(void)
0207 {
0208 rtems_event_set events;
0209 rtems_status_code sc;
0210
0211 sc = rtems_event_receive(
0212 RTEMS_ALL_EVENTS,
0213 RTEMS_EVENT_ANY | RTEMS_WAIT,
0214 RTEMS_NO_TIMEOUT,
0215 &events
0216 );
0217 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0218
0219 return events;
0220 }
0221
0222 static void sync_with_helper_by_id(test_context *ctx, task_id id)
0223 {
0224 rtems_event_set events;
0225
0226 send_event(ctx, id, REQ_WAKE_UP_HELPER);
0227 events = wait_for_events();
0228 rtems_test_assert(events == REQ_WAKE_UP_MASTER);
0229 }
0230
0231 static void sync_with_helper(test_context *ctx)
0232 {
0233 sync_with_helper_by_id(ctx, H_A);
0234 sync_with_helper_by_id(ctx, H_B);
0235 }
0236
0237 static void request(test_context *ctx, task_id id, request_id req)
0238 {
0239 send_event(ctx, id, req);
0240 clear_done(ctx);
0241
0242 if (rtems_scheduler_get_processor() == 0) {
0243 id = H_B;
0244 } else {
0245 id = H_A;
0246 }
0247
0248 send_event(ctx, id, REQ_SET_DONE);
0249 wait_for_done(ctx);
0250 }
0251
0252 static void obtain(test_context *ctx)
0253 {
0254 rtems_status_code sc;
0255
0256 sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0257 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0258 }
0259
0260 static void obtain_timeout(test_context *ctx)
0261 {
0262 rtems_status_code sc;
0263
0264 sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, TIMEOUT_IN_TICKS);
0265 rtems_test_assert(sc == RTEMS_TIMEOUT);
0266 }
0267
0268 static void obtain_unsatisfied(test_context *ctx)
0269 {
0270 rtems_status_code sc;
0271
0272 sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0273 rtems_test_assert(sc == RTEMS_UNSATISFIED);
0274 }
0275
0276 static void release(test_context *ctx)
0277 {
0278 rtems_status_code sc;
0279
0280 sc = rtems_semaphore_release(ctx->mtx);
0281 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0282 }
0283
0284 static void flush(test_context *ctx)
0285 {
0286 rtems_status_code sc;
0287
0288 sc = rtems_semaphore_flush(ctx->mtx);
0289 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0290 }
0291
0292 static void obtain_2(test_context *ctx)
0293 {
0294 rtems_status_code sc;
0295
0296 sc = rtems_semaphore_obtain(ctx->mtx_2, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0297 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0298 }
0299
0300 static void release_2(test_context *ctx)
0301 {
0302 rtems_status_code sc;
0303
0304 sc = rtems_semaphore_release(ctx->mtx_2);
0305 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0306 }
0307
0308 static void sem_obtain(test_context *ctx)
0309 {
0310 rtems_status_code sc;
0311
0312 sc = rtems_semaphore_obtain(ctx->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0313 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0314 }
0315
0316 static void sem_release(test_context *ctx)
0317 {
0318 rtems_status_code sc;
0319
0320 sc = rtems_semaphore_release(ctx->sem);
0321 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0322 }
0323
0324 static void ceil_obtain(test_context *ctx)
0325 {
0326 rtems_status_code sc;
0327
0328 sc = rtems_semaphore_obtain(ctx->ceil, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0329 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0330 }
0331
0332 static void ceil_release(test_context *ctx)
0333 {
0334 rtems_status_code sc;
0335
0336 sc = rtems_semaphore_release(ctx->ceil);
0337 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0338 }
0339
0340 static void wait(void)
0341 {
0342 rtems_status_code sc;
0343
0344 sc = rtems_task_wake_after(TIMEOUT_IN_TICKS + 1);
0345 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0346 }
0347
0348 static void check_generations(test_context *ctx, task_id a, task_id b)
0349 {
0350 size_t i;
0351
0352 if (a != NONE) {
0353 ++ctx->expected_generation[a];
0354 }
0355
0356 if (b != NONE) {
0357 ++ctx->expected_generation[b];
0358 }
0359
0360 for (i = 0; i < TASK_COUNT; ++i) {
0361 rtems_test_assert(ctx->generation[i] == ctx->expected_generation[i]);
0362 }
0363 }
0364
0365 static void yield(void)
0366 {
0367 rtems_status_code sc;
0368
0369 sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
0370 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0371 }
0372
0373 static void set_prio(test_context *ctx, task_id id, rtems_task_priority prio)
0374 {
0375 rtems_status_code sc;
0376
0377 sc = rtems_task_set_priority(ctx->tasks[id], prio, &prio);
0378 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0379 }
0380
0381 static void assert_prio(
0382 test_context *ctx,
0383 task_id id,
0384 rtems_task_priority expected
0385 )
0386 {
0387 rtems_task_priority actual;
0388 rtems_status_code sc;
0389
0390 sc = rtems_task_set_priority(
0391 ctx->tasks[id],
0392 RTEMS_CURRENT_PRIORITY,
0393 &actual
0394 );
0395 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0396 rtems_test_assert(expected == actual);
0397 }
0398
0399 static void assert_prio_by_scheduler(
0400 test_context *ctx,
0401 task_id id,
0402 rtems_name scheduler,
0403 rtems_task_priority expected
0404 )
0405 {
0406 rtems_task_priority actual;
0407 rtems_status_code sc;
0408 rtems_id scheduler_id;
0409
0410 sc = rtems_scheduler_ident(scheduler, &scheduler_id);
0411 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0412
0413 actual = PRIO_NONE;
0414 sc = rtems_task_get_priority(
0415 ctx->tasks[id],
0416 scheduler_id,
0417 &actual
0418 );
0419
0420 if (expected == PRIO_NONE) {
0421 rtems_test_assert(sc == RTEMS_NOT_DEFINED);
0422 } else {
0423 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0424 }
0425
0426 rtems_test_assert(actual == expected);
0427 }
0428
0429 static void helper(rtems_task_argument arg)
0430 {
0431 test_context *ctx = &test_instance;
0432
0433 while (true) {
0434 rtems_event_set events = wait_for_events();
0435
0436 if ((events & REQ_WAKE_UP_HELPER) != 0) {
0437 send_event(ctx, M, REQ_WAKE_UP_MASTER);
0438 }
0439
0440 if ((events & REQ_SEM_RELEASE) != 0) {
0441 sem_release(ctx);
0442 }
0443
0444 if ((events & REQ_SET_DONE) != 0) {
0445 set_done(ctx);
0446 }
0447 }
0448 }
0449
0450 static void worker(rtems_task_argument arg)
0451 {
0452 test_context *ctx = &test_instance;
0453 task_id id = arg;
0454
0455 while (true) {
0456 rtems_event_set events = wait_for_events();
0457
0458 if ((events & REQ_MTX_OBTAIN) != 0) {
0459 obtain(ctx);
0460 ++ctx->generation[id];
0461 }
0462
0463 if ((events & REQ_MTX_OBTAIN_TIMEOUT) != 0) {
0464 obtain_timeout(ctx);
0465 ++ctx->generation[id];
0466 }
0467
0468 if ((events & REQ_MTX_OBTAIN_UNSATISFIED) != 0) {
0469 obtain_unsatisfied(ctx);
0470 ++ctx->generation[id];
0471 }
0472
0473 if ((events & REQ_MTX_RELEASE) != 0) {
0474 release(ctx);
0475 ++ctx->generation[id];
0476 }
0477
0478 if ((events & REQ_MTX_2_OBTAIN) != 0) {
0479 obtain_2(ctx);
0480 ++ctx->generation[id];
0481 }
0482
0483 if ((events & REQ_MTX_2_RELEASE) != 0) {
0484 release_2(ctx);
0485 ++ctx->generation[id];
0486 }
0487
0488 if ((events & REQ_SEM_OBTAIN_RELEASE) != 0) {
0489 sem_obtain(ctx);
0490 ++ctx->generation[id];
0491 sem_release(ctx);
0492 }
0493
0494 if ((events & REQ_SEND_EVENT_2) != 0) {
0495 send_event(ctx, ctx->id_2, ctx->events_2);
0496 }
0497
0498 if ((events & REQ_SEND_EVENT_3) != 0) {
0499 send_event(ctx, ctx->id_3, ctx->events_3);
0500 }
0501
0502 if ((events & REQ_CEIL_OBTAIN) != 0) {
0503 ceil_obtain(ctx);
0504 ++ctx->generation[id];
0505 }
0506
0507 if ((events & REQ_CEIL_RELEASE) != 0) {
0508 ceil_release(ctx);
0509 ++ctx->generation[id];
0510 }
0511
0512 if ((events & REQ_SET_DONE) != 0) {
0513 set_done(ctx);
0514 }
0515
0516 if ((events & REQ_WAIT_FOR_DONE) != 0) {
0517 wait_for_done(ctx);
0518 }
0519 }
0520 }
0521
0522 static void test_init(test_context *ctx)
0523 {
0524 rtems_status_code sc;
0525
0526 ctx->tasks[M] = rtems_task_self();
0527 start_task(ctx, A_1, worker, 1, SCHED_A);
0528 start_task(ctx, A_2_0, worker, 2, SCHED_A);
0529 start_task(ctx, A_2_1, worker, 2, SCHED_A);
0530 start_task(ctx, H_A, helper, 3, SCHED_A);
0531
0532 if (rtems_scheduler_get_processor_maximum() >= PART_COUNT) {
0533 start_task(ctx, B_4, worker, 4, SCHED_B);
0534 start_task(ctx, B_5_0, worker, 5, SCHED_B);
0535 start_task(ctx, B_5_1, worker, 5, SCHED_B);
0536 start_task(ctx, H_B, helper, 6, SCHED_B);
0537 }
0538
0539 sc = rtems_semaphore_create(
0540 rtems_build_name('M', 'T', 'X', '1'),
0541 1,
0542 RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
0543 0,
0544 &ctx->mtx
0545 );
0546 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0547
0548 sc = rtems_semaphore_create(
0549 rtems_build_name('M', 'T', 'X', '2'),
0550 1,
0551 RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
0552 0,
0553 &ctx->mtx_2
0554 );
0555 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0556
0557 sc = rtems_semaphore_create(
0558 rtems_build_name(' ', 'S', 'E', 'M'),
0559 0,
0560 RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY,
0561 0,
0562 &ctx->sem
0563 );
0564 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0565
0566 sc = rtems_semaphore_create(
0567 rtems_build_name('C', 'E', 'I', 'L'),
0568 1,
0569 RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING,
0570 1,
0571 &ctx->ceil
0572 );
0573 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0574 }
0575
0576 static void test_simple_inheritance(test_context *ctx)
0577 {
0578 obtain(ctx);
0579 request(ctx, A_1, REQ_MTX_OBTAIN);
0580 check_generations(ctx, NONE, NONE);
0581 assert_prio(ctx, M, 1);
0582 release(ctx);
0583 check_generations(ctx, A_1, NONE);
0584 assert_prio(ctx, M, 3);
0585 request(ctx, A_1, REQ_MTX_RELEASE);
0586 check_generations(ctx, A_1, NONE);
0587 }
0588
0589 static void test_flush_inheritance(test_context *ctx)
0590 {
0591 assert_prio(ctx, M, 3);
0592 obtain(ctx);
0593 send_event(ctx, A_1, REQ_MTX_OBTAIN_UNSATISFIED);
0594 check_generations(ctx, NONE, NONE);
0595 assert_prio(ctx, M, 1);
0596 flush(ctx);
0597 check_generations(ctx, A_1, NONE);
0598 assert_prio(ctx, M, 3);
0599 release(ctx);
0600 }
0601
0602 static void test_ceiling_mutex(test_context *ctx)
0603 {
0604 assert_prio(ctx, M, 3);
0605 ceil_obtain(ctx);
0606 assert_prio(ctx, M, 1);
0607 send_event(ctx, A_1, REQ_CEIL_OBTAIN);
0608 yield();
0609 check_generations(ctx, NONE, NONE);
0610 ceil_release(ctx);
0611 check_generations(ctx, A_1, NONE);
0612 assert_prio(ctx, M, 3);
0613 send_event(ctx, A_1, REQ_CEIL_RELEASE);
0614 check_generations(ctx, A_1, NONE);
0615 }
0616
0617 static void test_dequeue_order_one_scheduler_instance(test_context *ctx)
0618 {
0619 obtain(ctx);
0620 request(ctx, A_2_0, REQ_MTX_OBTAIN);
0621 request(ctx, A_1, REQ_MTX_OBTAIN);
0622 request(ctx, A_2_1, REQ_MTX_OBTAIN);
0623 check_generations(ctx, NONE, NONE);
0624 assert_prio(ctx, M, 1);
0625 release(ctx);
0626 check_generations(ctx, A_1, NONE);
0627 assert_prio(ctx, M, 3);
0628 assert_prio(ctx, A_1, 1);
0629 request(ctx, A_1, REQ_MTX_RELEASE);
0630 check_generations(ctx, A_1, A_2_0);
0631 request(ctx, A_2_0, REQ_MTX_RELEASE);
0632 check_generations(ctx, A_2_0, A_2_1);
0633 request(ctx, A_2_1, REQ_MTX_RELEASE);
0634 check_generations(ctx, A_2_1, NONE);
0635 }
0636
0637 static void test_mixed_queue_two_scheduler_instances(test_context *ctx)
0638 {
0639 obtain(ctx);
0640 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0641 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0642
0643 request(ctx, B_4, REQ_MTX_OBTAIN_TIMEOUT);
0644 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0645 assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
0646 check_generations(ctx, NONE, NONE);
0647 wait();
0648 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0649 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0650 check_generations(ctx, B_4, NONE);
0651
0652 request(ctx, B_4, REQ_MTX_OBTAIN);
0653 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0654 assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
0655 check_generations(ctx, NONE, NONE);
0656
0657 request(ctx, B_5_0, REQ_SEM_OBTAIN_RELEASE);
0658 send_event(ctx, H_A, REQ_SEM_RELEASE);
0659 check_generations(ctx, NONE, NONE);
0660
0661
0662
0663
0664
0665
0666
0667 sem_obtain(ctx);
0668 check_generations(ctx, NONE, NONE);
0669
0670 release(ctx);
0671 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0672 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0673 sync_with_helper(ctx);
0674 check_generations(ctx, B_4, NONE);
0675
0676 request(ctx, B_4, REQ_MTX_RELEASE);
0677 check_generations(ctx, B_4, NONE);
0678
0679 sem_release(ctx);
0680 sync_with_helper(ctx);
0681 check_generations(ctx, B_5_0, NONE);
0682
0683 sem_obtain(ctx);
0684 }
0685
0686 static void test_mixed_queue_two_scheduler_instances_sem_only(test_context *ctx)
0687 {
0688 request(ctx, B_5_0, REQ_SEM_OBTAIN_RELEASE);
0689 send_event(ctx, H_A, REQ_SEM_RELEASE);
0690 check_generations(ctx, NONE, NONE);
0691
0692
0693
0694
0695
0696
0697 sem_obtain(ctx);
0698 check_generations(ctx, B_5_0, NONE);
0699
0700 sem_release(ctx);
0701 }
0702
0703 static void test_two_scheduler_instances_sem_with_inheritance(test_context *ctx)
0704 {
0705 sem_obtain(ctx);
0706
0707 request(ctx, B_4, REQ_MTX_OBTAIN);
0708 check_generations(ctx, B_4, NONE);
0709 assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
0710 assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
0711
0712 request(ctx, B_4, REQ_SEM_OBTAIN_RELEASE);
0713 check_generations(ctx, NONE, NONE);
0714
0715 request(ctx, A_1, REQ_MTX_OBTAIN);
0716 check_generations(ctx, NONE, NONE);
0717 assert_prio_by_scheduler(ctx, B_4, SCHED_A, 1);
0718 assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
0719
0720 sem_release(ctx);
0721 sync_with_helper(ctx);
0722 check_generations(ctx, B_4, NONE);
0723
0724 request(ctx, B_4, REQ_MTX_RELEASE);
0725 check_generations(ctx, B_4, A_1);
0726 assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
0727 assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
0728
0729 request(ctx, A_1, REQ_MTX_RELEASE);
0730 check_generations(ctx, A_1, NONE);
0731 }
0732
0733 static void test_two_scheduler_instances_sem_with_inheritance_timeout(test_context *ctx)
0734 {
0735 sem_obtain(ctx);
0736
0737 request(ctx, B_4, REQ_MTX_OBTAIN);
0738 check_generations(ctx, B_4, NONE);
0739 assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
0740 assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
0741
0742 request(ctx, B_4, REQ_SEM_OBTAIN_RELEASE);
0743 check_generations(ctx, NONE, NONE);
0744
0745 request(ctx, A_1, REQ_MTX_OBTAIN_TIMEOUT);
0746 check_generations(ctx, NONE, NONE);
0747 assert_prio_by_scheduler(ctx, B_4, SCHED_A, 1);
0748 assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
0749 wait();
0750 check_generations(ctx, A_1, NONE);
0751 assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
0752 assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
0753
0754 sem_release(ctx);
0755 sync_with_helper(ctx);
0756 check_generations(ctx, B_4, NONE);
0757
0758 request(ctx, B_4, REQ_MTX_RELEASE);
0759 check_generations(ctx, B_4, NONE);
0760 assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
0761 assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
0762 }
0763
0764 static void test_simple_inheritance_two_scheduler_instances(test_context *ctx)
0765 {
0766 obtain(ctx);
0767 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0768 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0769
0770 request(ctx, B_5_0, REQ_MTX_OBTAIN);
0771 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0772 assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
0773
0774 request(ctx, B_4, REQ_MTX_OBTAIN);
0775 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0776 assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
0777
0778 request(ctx, B_5_1, REQ_MTX_OBTAIN);
0779 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0780 assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
0781 check_generations(ctx, NONE, NONE);
0782
0783 release(ctx);
0784 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0785 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0786 sync_with_helper(ctx);
0787 check_generations(ctx, B_4, NONE);
0788
0789 request(ctx, B_4, REQ_MTX_RELEASE);
0790 check_generations(ctx, B_4, B_5_0);
0791
0792 request(ctx, B_5_0, REQ_MTX_RELEASE);
0793 check_generations(ctx, B_5_0, B_5_1);
0794
0795 request(ctx, B_5_1, REQ_MTX_RELEASE);
0796 check_generations(ctx, B_5_1, NONE);
0797 }
0798
0799 static void test_nested_inheritance_two_scheduler_instances(test_context *ctx)
0800 {
0801 obtain_2(ctx);
0802 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0803 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0804
0805 request(ctx, B_5_0, REQ_MTX_OBTAIN);
0806 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0807 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0808 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
0809 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
0810 check_generations(ctx, B_5_0, NONE);
0811
0812 request(ctx, B_5_0, REQ_MTX_2_OBTAIN);
0813 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0814 assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
0815 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
0816 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
0817
0818 request(ctx, B_4, REQ_MTX_OBTAIN_TIMEOUT);
0819 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0820 assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
0821 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
0822 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 4);
0823 wait();
0824 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0825 assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
0826 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
0827 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
0828 check_generations(ctx, B_4, NONE);
0829
0830 request(ctx, B_4, REQ_MTX_OBTAIN);
0831 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0832 assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
0833 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
0834 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 4);
0835
0836 request(ctx, B_5_1, REQ_MTX_2_OBTAIN);
0837 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0838 assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
0839 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
0840 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 4);
0841 check_generations(ctx, NONE, NONE);
0842
0843 release_2(ctx);
0844 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0845 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0846 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
0847 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 4);
0848 sync_with_helper(ctx);
0849 check_generations(ctx, B_5_0, NONE);
0850
0851 request(ctx, B_5_0, REQ_MTX_RELEASE);
0852 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
0853 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
0854 check_generations(ctx, B_4, B_5_0);
0855
0856 request(ctx, B_4, REQ_MTX_RELEASE);
0857 check_generations(ctx, B_4, NONE);
0858
0859 request(ctx, B_5_0, REQ_MTX_2_RELEASE);
0860 check_generations(ctx, B_5_0, B_5_1);
0861
0862 request(ctx, B_5_1, REQ_MTX_2_RELEASE);
0863 check_generations(ctx, B_5_1, NONE);
0864 }
0865
0866 static void test_dequeue_order_two_scheduler_instances(test_context *ctx)
0867 {
0868 obtain(ctx);
0869 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0870 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0871
0872 request(ctx, A_2_0, REQ_MTX_OBTAIN);
0873 assert_prio_by_scheduler(ctx, M, SCHED_A, 2);
0874 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0875 check_generations(ctx, NONE, NONE);
0876
0877 request(ctx, B_5_0, REQ_MTX_OBTAIN);
0878 assert_prio_by_scheduler(ctx, M, SCHED_A, 2);
0879 assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
0880 check_generations(ctx, NONE, NONE);
0881
0882 request(ctx, B_5_1, REQ_MTX_OBTAIN);
0883 assert_prio_by_scheduler(ctx, M, SCHED_A, 2);
0884 assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
0885
0886 request(ctx, B_4, REQ_MTX_OBTAIN);
0887 assert_prio_by_scheduler(ctx, M, SCHED_A, 2);
0888 assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
0889
0890 request(ctx, A_2_1, REQ_MTX_OBTAIN);
0891 assert_prio_by_scheduler(ctx, M, SCHED_A, 2);
0892 assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
0893
0894 request(ctx, A_1, REQ_MTX_OBTAIN);
0895 assert_prio_by_scheduler(ctx, M, SCHED_A, 1);
0896 assert_prio_by_scheduler(ctx, M, SCHED_B, 4);
0897 check_generations(ctx, NONE, NONE);
0898
0899 release(ctx);
0900 sync_with_helper(ctx);
0901 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0902 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0903 assert_prio_by_scheduler(ctx, A_1, SCHED_A, 1);
0904 assert_prio_by_scheduler(ctx, A_1, SCHED_B, 4);
0905 check_generations(ctx, A_1, NONE);
0906
0907 request(ctx, A_1, REQ_MTX_RELEASE);
0908 assert_prio_by_scheduler(ctx, A_1, SCHED_A, 1);
0909 assert_prio_by_scheduler(ctx, A_1, SCHED_B, PRIO_NONE);
0910 assert_prio_by_scheduler(ctx, B_4, SCHED_A, 2);
0911 assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
0912 check_generations(ctx, A_1, B_4);
0913
0914 request(ctx, B_4, REQ_MTX_RELEASE);
0915 assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
0916 assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
0917 assert_prio_by_scheduler(ctx, A_2_0, SCHED_A, 2);
0918 assert_prio_by_scheduler(ctx, A_2_0, SCHED_B, 5);
0919 check_generations(ctx, B_4, A_2_0);
0920
0921 request(ctx, A_2_0, REQ_MTX_RELEASE);
0922 assert_prio_by_scheduler(ctx, A_2_0, SCHED_A, 2);
0923 assert_prio_by_scheduler(ctx, A_2_0, SCHED_B, PRIO_NONE);
0924 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, 2);
0925 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
0926 check_generations(ctx, A_2_0, B_5_0);
0927
0928 request(ctx, B_5_0, REQ_MTX_RELEASE);
0929 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
0930 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
0931 assert_prio_by_scheduler(ctx, A_2_1, SCHED_A, 2);
0932 assert_prio_by_scheduler(ctx, A_2_1, SCHED_B, 5);
0933 check_generations(ctx, B_5_0, A_2_1);
0934
0935 request(ctx, A_2_1, REQ_MTX_RELEASE);
0936 assert_prio_by_scheduler(ctx, A_2_1, SCHED_A, 2);
0937 assert_prio_by_scheduler(ctx, A_2_1, SCHED_B, PRIO_NONE);
0938 assert_prio_by_scheduler(ctx, B_5_1, SCHED_A, PRIO_NONE);
0939 assert_prio_by_scheduler(ctx, B_5_1, SCHED_B, 5);
0940 check_generations(ctx, A_2_1, B_5_1);
0941
0942 request(ctx, B_5_1, REQ_MTX_RELEASE);
0943 assert_prio_by_scheduler(ctx, B_5_1, SCHED_A, PRIO_NONE);
0944 assert_prio_by_scheduler(ctx, B_5_1, SCHED_B, 5);
0945 check_generations(ctx, B_5_1, NONE);
0946 }
0947
0948 static void test_omip_pre_emption(test_context *ctx)
0949 {
0950 assert_cpu(0);
0951 obtain(ctx);
0952 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0953 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0954
0955 request(ctx, B_5_0, REQ_MTX_OBTAIN);
0956 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0957 assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
0958 check_generations(ctx, NONE, NONE);
0959
0960 request_pre_emption(ctx, A_1);
0961 assert_cpu(1);
0962
0963 request_pre_emption(ctx, B_4);
0964 assert_cpu(0);
0965
0966 request_pre_emption(ctx, A_1);
0967 assert_cpu(1);
0968
0969 release(ctx);
0970 assert_cpu(0);
0971 sync_with_helper(ctx);
0972 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0973 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0974 check_generations(ctx, B_5_0, NONE);
0975
0976 request(ctx, B_5_0, REQ_MTX_RELEASE);
0977 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
0978 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
0979 check_generations(ctx, B_5_0, NONE);
0980 }
0981
0982 static void test_omip_rescue(test_context *ctx)
0983 {
0984 assert_cpu(0);
0985 obtain(ctx);
0986 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0987 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
0988
0989 clear_done(ctx);
0990 set_event_3(ctx, H_B, REQ_SET_DONE);
0991 set_event_2(ctx, B_5_0, REQ_SEND_EVENT_3 | REQ_MTX_OBTAIN);
0992 send_event(ctx, A_1, REQ_SEND_EVENT_2 | REQ_WAIT_FOR_DONE);
0993 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
0994 assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
0995 assert_cpu(1);
0996
0997 release(ctx);
0998 assert_cpu(0);
0999 sync_with_helper(ctx);
1000 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
1001 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
1002 check_generations(ctx, B_5_0, NONE);
1003
1004 request(ctx, B_5_0, REQ_MTX_RELEASE);
1005 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
1006 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
1007 check_generations(ctx, B_5_0, NONE);
1008 }
1009
1010 static void test_omip_timeout(test_context *ctx)
1011 {
1012 assert_cpu(0);
1013 obtain(ctx);
1014 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
1015 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
1016
1017 clear_done(ctx);
1018 set_event_3(ctx, H_B, REQ_SET_DONE);
1019 set_event_2(ctx, B_5_0, REQ_SEND_EVENT_3 | REQ_MTX_OBTAIN_TIMEOUT);
1020 send_event(ctx, A_1, REQ_SEND_EVENT_2 | REQ_WAIT_FOR_DONE);
1021 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
1022 assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
1023 assert_cpu(1);
1024
1025 wait();
1026 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
1027 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
1028 check_generations(ctx, B_5_0, NONE);
1029 assert_cpu(0);
1030
1031 release(ctx);
1032 }
1033
1034 static void test_omip_yield(test_context *ctx)
1035 {
1036 assert_cpu(0);
1037 obtain(ctx);
1038 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
1039 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
1040
1041 request(ctx, B_5_0, REQ_MTX_OBTAIN);
1042 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
1043 assert_prio_by_scheduler(ctx, M, SCHED_B, 5);
1044 check_generations(ctx, NONE, NONE);
1045
1046 clear_done(ctx);
1047 send_event(ctx, H_A, REQ_SET_DONE);
1048 yield();
1049 assert_cpu(1);
1050 wait_for_done(ctx);
1051
1052 clear_done(ctx);
1053 send_event(ctx, H_B, REQ_SET_DONE);
1054 set_prio(ctx, H_B, 5);
1055 yield();
1056 assert_cpu(1);
1057 rtems_test_assert(!is_done(ctx));
1058
1059 set_prio(ctx, H_B, 4);
1060 assert_cpu(0);
1061
1062 wait_for_done(ctx);
1063 set_prio(ctx, H_B, 6);
1064
1065 release(ctx);
1066 sync_with_helper(ctx);
1067 assert_prio_by_scheduler(ctx, M, SCHED_A, 3);
1068 assert_prio_by_scheduler(ctx, M, SCHED_B, PRIO_NONE);
1069 check_generations(ctx, B_5_0, NONE);
1070
1071 request(ctx, B_5_0, REQ_MTX_RELEASE);
1072 assert_prio_by_scheduler(ctx, B_5_0, SCHED_A, PRIO_NONE);
1073 assert_prio_by_scheduler(ctx, B_5_0, SCHED_B, 5);
1074 check_generations(ctx, B_5_0, NONE);
1075 }
1076
1077 static void test(test_context *ctx)
1078 {
1079 test_init(ctx);
1080
1081 if (rtems_scheduler_get_processor_maximum() >= PART_COUNT) {
1082 test_task_get_priority_not_defined(ctx);
1083 test_simple_inheritance(ctx);
1084 test_dequeue_order_one_scheduler_instance(ctx);
1085 test_mixed_queue_two_scheduler_instances(ctx);
1086 test_mixed_queue_two_scheduler_instances_sem_only(ctx);
1087 test_two_scheduler_instances_sem_with_inheritance(ctx);
1088 test_two_scheduler_instances_sem_with_inheritance_timeout(ctx);
1089 test_simple_inheritance_two_scheduler_instances(ctx);
1090 test_nested_inheritance_two_scheduler_instances(ctx);
1091 test_dequeue_order_two_scheduler_instances(ctx);
1092 test_omip_pre_emption(ctx);
1093 test_omip_rescue(ctx);
1094 test_omip_timeout(ctx);
1095 test_omip_yield(ctx);
1096 }
1097
1098 test_flush_inheritance(ctx);
1099 test_ceiling_mutex(ctx);
1100 }
1101
1102 static void Init(rtems_task_argument arg)
1103 {
1104 TEST_BEGIN();
1105 test(&test_instance);
1106 TEST_END();
1107 rtems_test_exit(0);
1108 }
1109
1110 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
1111 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
1112
1113 #define CONFIGURE_MAXIMUM_PROCESSORS PART_COUNT
1114
1115 #define CONFIGURE_SCHEDULER_SIMPLE_SMP
1116
1117 #include <rtems/scheduler.h>
1118
1119 RTEMS_SCHEDULER_SIMPLE_SMP(a);
1120
1121 RTEMS_SCHEDULER_SIMPLE_SMP(b);
1122
1123 #define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
1124 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(a, SCHED_A), \
1125 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(b, SCHED_B)
1126
1127 #define CONFIGURE_SCHEDULER_ASSIGNMENTS \
1128 RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
1129 RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
1130
1131 #define CONFIGURE_MAXIMUM_TASKS TASK_COUNT
1132
1133 #define CONFIGURE_MAXIMUM_SEMAPHORES 4
1134
1135 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
1136
1137 #define CONFIGURE_INIT_TASK_PRIORITY 3
1138
1139 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
1140
1141 #define CONFIGURE_INIT
1142
1143 #include <rtems/confdefs.h>