File indexing completed on 2025-05-11 08:24:49
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 #include <sys/lock.h>
0035 #include <errno.h>
0036 #include <limits.h>
0037 #include <setjmp.h>
0038 #include <string.h>
0039 #include <time.h>
0040
0041 const char rtems_test_name[] = "SPSYSLOCK 1";
0042
0043 #define US_PER_TICK 10000
0044
0045 #define EVENT_MTX_ACQUIRE RTEMS_EVENT_0
0046
0047 #define EVENT_MTX_RELEASE RTEMS_EVENT_1
0048
0049 #define EVENT_MTX_PRIO_INV RTEMS_EVENT_2
0050
0051 #define EVENT_REC_MTX_ACQUIRE RTEMS_EVENT_4
0052
0053 #define EVENT_REC_MTX_RELEASE RTEMS_EVENT_5
0054
0055 #define EVENT_REC_MTX_PRIO_INV RTEMS_EVENT_6
0056
0057 #define EVENT_SEM_WAIT RTEMS_EVENT_7
0058
0059 #define EVENT_FUTEX_WAIT RTEMS_EVENT_8
0060
0061 #define EVENT_CONDITION_WAIT RTEMS_EVENT_9
0062
0063 #define EVENT_CONDITION_WAIT_REC RTEMS_EVENT_10
0064
0065 typedef struct {
0066 rtems_id high[2];
0067 rtems_id mid;
0068 rtems_id low;
0069 struct _Mutex_Control mtx;
0070 struct _Mutex_recursive_Control rec_mtx;
0071 struct _Condition_Control cond;
0072 struct _Semaphore_Control sem;
0073 struct _Futex_Control futex;
0074 int val;
0075 int eno[2];
0076 int generation[2];
0077 int current_generation[2];
0078 jmp_buf deadlock_return_context;
0079 } test_context;
0080
0081 static test_context test_instance;
0082
0083 static int generation(test_context *ctx, size_t idx)
0084 {
0085 return ++ctx->current_generation[idx];
0086 }
0087
0088 static void send_event(test_context *ctx, size_t idx, rtems_event_set events)
0089 {
0090 rtems_status_code sc;
0091
0092 sc = rtems_event_send(ctx->high[idx], events);
0093 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0094 }
0095
0096 static void get_abs_timeout(struct timespec *to)
0097 {
0098 int rv;
0099
0100 rv = clock_gettime(CLOCK_REALTIME, to);
0101 rtems_test_assert(rv == 0);
0102
0103 to->tv_nsec += 2 * US_PER_TICK * 1000;
0104 if (to->tv_nsec >= 1000000000) {
0105 ++to->tv_sec;
0106 to->tv_nsec -= 1000000000;
0107 }
0108 }
0109
0110 static bool eq_tq(
0111 const struct _Thread_queue_Queue *a,
0112 const struct _Thread_queue_Queue *b
0113 )
0114 {
0115 return a->_Lock._next_ticket == b->_Lock._next_ticket
0116 && a->_Lock._now_serving == b->_Lock._now_serving
0117 && a->_heads == b->_heads
0118 && a->_owner == b->_owner
0119 && a->_name == b->_name;
0120 }
0121
0122 static bool eq_mtx(
0123 const struct _Mutex_Control *a,
0124 const struct _Mutex_Control *b
0125 )
0126 {
0127 return eq_tq(&a->_Queue, &b->_Queue);
0128 }
0129
0130 static bool eq_rec_mtx(
0131 const struct _Mutex_recursive_Control *a,
0132 const struct _Mutex_recursive_Control *b
0133 )
0134 {
0135 return eq_mtx(&a->_Mutex, &b->_Mutex)
0136 && a->_nest_level == b->_nest_level;
0137 }
0138
0139 static bool eq_cond(
0140 const struct _Condition_Control *a,
0141 const struct _Condition_Control *b
0142 )
0143 {
0144 return eq_tq(&a->_Queue, &b->_Queue);
0145 }
0146
0147 static bool eq_sem(
0148 const struct _Semaphore_Control *a,
0149 const struct _Semaphore_Control *b
0150 )
0151 {
0152 return eq_tq(&a->_Queue, &b->_Queue)
0153 && a->_count == b->_count;
0154 }
0155
0156 static bool eq_futex(
0157 const struct _Futex_Control *a,
0158 const struct _Futex_Control *b
0159 )
0160 {
0161 return eq_tq(&a->_Queue, &b->_Queue);
0162 }
0163
0164 static void test_initialization(test_context *ctx)
0165 {
0166 struct _Mutex_Control mtx = _MUTEX_INITIALIZER;
0167 struct _Mutex_recursive_Control rec_mtx = _MUTEX_RECURSIVE_INITIALIZER;
0168 struct _Condition_Control cond = _CONDITION_INITIALIZER;
0169 struct _Semaphore_Control sem = _SEMAPHORE_INITIALIZER(1);
0170 struct _Futex_Control futex = _FUTEX_INITIALIZER;
0171
0172 _Mutex_Initialize(&ctx->mtx);
0173 _Mutex_recursive_Initialize(&ctx->rec_mtx);
0174 _Condition_Initialize(&ctx->cond);
0175 _Semaphore_Initialize(&ctx->sem, 1);
0176 _Futex_Initialize(&ctx->futex);
0177
0178 rtems_test_assert(eq_mtx(&mtx, &ctx->mtx));
0179 rtems_test_assert(eq_rec_mtx(&rec_mtx, &ctx->rec_mtx));
0180 rtems_test_assert(eq_cond(&cond, &ctx->cond));
0181 rtems_test_assert(eq_sem(&sem, &ctx->sem));
0182 rtems_test_assert(eq_futex(&futex, &ctx->futex));
0183
0184 _Mutex_Destroy(&mtx);
0185 _Mutex_recursive_Destroy(&rec_mtx);
0186 _Condition_Destroy(&cond);
0187 _Semaphore_Destroy(&sem);
0188 _Futex_Destroy(&futex);
0189 }
0190
0191 static void test_recursive_acquire_normal(test_context *ctx)
0192 {
0193 struct _Mutex_Control *mtx = &ctx->mtx;
0194 size_t idx = 0;
0195 int eno;
0196
0197 eno = _Mutex_Try_acquire(mtx);
0198 rtems_test_assert(eno == 0);
0199
0200 eno = _Mutex_Try_acquire(mtx);
0201 rtems_test_assert(eno == EBUSY);
0202
0203 _Mutex_Release(mtx);
0204
0205 eno = _Mutex_Try_acquire(mtx);
0206 rtems_test_assert(eno == 0);
0207
0208 _Mutex_Release(mtx);
0209
0210 _Mutex_Acquire(mtx);
0211
0212 eno = _Mutex_Try_acquire(mtx);
0213 rtems_test_assert(eno == EBUSY);
0214
0215 _Mutex_Release(mtx);
0216
0217 send_event(ctx, idx, EVENT_MTX_ACQUIRE);
0218
0219 eno = _Mutex_Try_acquire(mtx);
0220 rtems_test_assert(eno == EBUSY);
0221
0222 send_event(ctx, idx, EVENT_MTX_RELEASE);
0223 }
0224
0225 static void test_recursive_acquire_recursive(test_context *ctx)
0226 {
0227 struct _Mutex_recursive_Control *mtx = &ctx->rec_mtx;
0228 size_t idx = 0;
0229 int eno;
0230
0231 eno = _Mutex_recursive_Try_acquire(mtx);
0232 rtems_test_assert(eno == 0);
0233
0234 _Mutex_recursive_Acquire(mtx);
0235
0236 eno = _Mutex_recursive_Try_acquire(mtx);
0237 rtems_test_assert(eno == 0);
0238
0239 _Mutex_recursive_Release(mtx);
0240 _Mutex_recursive_Release(mtx);
0241 _Mutex_recursive_Release(mtx);
0242
0243 send_event(ctx, idx, EVENT_REC_MTX_ACQUIRE);
0244
0245 eno = _Mutex_recursive_Try_acquire(mtx);
0246 rtems_test_assert(eno == EBUSY);
0247
0248 send_event(ctx, idx, EVENT_REC_MTX_RELEASE);
0249 }
0250
0251 static void test_prio_acquire_order(test_context *ctx)
0252 {
0253 struct _Mutex_Control *mtx = &ctx->mtx;
0254 size_t a = 0;
0255 size_t b = 1;
0256 int gen_a;
0257 int gen_b;
0258
0259 _Mutex_Acquire(mtx);
0260
0261 gen_a = ctx->generation[a];
0262 gen_b = ctx->generation[b];
0263
0264 send_event(ctx, b, EVENT_MTX_ACQUIRE);
0265 send_event(ctx, a, EVENT_MTX_ACQUIRE);
0266
0267 rtems_test_assert(ctx->generation[a] == gen_a);
0268 rtems_test_assert(ctx->generation[b] == gen_b);
0269
0270 _Mutex_Release(mtx);
0271
0272 rtems_test_assert(ctx->generation[a] == gen_a + 1);
0273 rtems_test_assert(ctx->generation[b] == gen_b);
0274
0275 send_event(ctx, a, EVENT_MTX_RELEASE);
0276
0277 rtems_test_assert(ctx->generation[a] == gen_a + 1);
0278 rtems_test_assert(ctx->generation[b] == gen_b + 1);
0279
0280 send_event(ctx, b, EVENT_MTX_RELEASE);
0281 }
0282
0283 static void test_prio_inv_normal(test_context *ctx)
0284 {
0285 struct _Mutex_Control *mtx = &ctx->mtx;
0286 size_t idx = 0;
0287 int gen;
0288
0289 _Mutex_Acquire(mtx);
0290 gen = ctx->generation[idx];
0291 send_event(ctx, idx, EVENT_MTX_PRIO_INV);
0292 rtems_test_assert(ctx->generation[idx] == gen);
0293 _Mutex_Release(mtx);
0294 rtems_test_assert(ctx->generation[idx] == gen + 1);
0295 }
0296
0297 static void test_prio_inv_recursive(test_context *ctx)
0298 {
0299 struct _Mutex_recursive_Control *mtx = &ctx->rec_mtx;
0300 size_t idx = 0;
0301 int gen;
0302
0303 _Mutex_recursive_Acquire(mtx);
0304 gen = ctx->generation[idx];
0305 send_event(ctx, idx, EVENT_REC_MTX_PRIO_INV);
0306 rtems_test_assert(ctx->generation[idx] == gen);
0307 _Mutex_recursive_Release(mtx);
0308 rtems_test_assert(ctx->generation[idx] == gen + 1);
0309 }
0310
0311 static void test_mtx_timeout_normal(test_context *ctx)
0312 {
0313 struct _Mutex_Control *mtx = &ctx->mtx;
0314 size_t idx = 0;
0315 struct timespec to;
0316 int eno;
0317
0318 eno = _Mutex_Acquire_timed(mtx, NULL);
0319 rtems_test_assert(eno == 0);
0320 _Mutex_Release(mtx);
0321
0322 send_event(ctx, idx, EVENT_MTX_ACQUIRE);
0323
0324 memset(&to, 0x00, sizeof(to));
0325 eno = _Mutex_Acquire_timed(mtx, &to);
0326 rtems_test_assert(eno == ETIMEDOUT);
0327 memset(&to, 0xff, sizeof(to));
0328 eno = _Mutex_Acquire_timed(mtx, &to);
0329 rtems_test_assert(eno == EINVAL);
0330 get_abs_timeout(&to);
0331 eno = _Mutex_Acquire_timed(mtx, &to);
0332 rtems_test_assert(eno == ETIMEDOUT);
0333
0334 send_event(ctx, idx, EVENT_MTX_RELEASE);
0335 }
0336
0337 static void test_mtx_timeout_recursive(test_context *ctx)
0338 {
0339 struct _Mutex_recursive_Control *mtx = &ctx->rec_mtx;
0340 size_t idx = 0;
0341 struct timespec to;
0342 int eno;
0343
0344 eno = _Mutex_recursive_Acquire_timed(mtx, NULL);
0345 rtems_test_assert(eno == 0);
0346 eno = _Mutex_recursive_Acquire_timed(mtx, NULL);
0347 rtems_test_assert(eno == 0);
0348 _Mutex_recursive_Release(mtx);
0349 _Mutex_recursive_Release(mtx);
0350
0351 send_event(ctx, idx, EVENT_REC_MTX_ACQUIRE);
0352
0353 memset(&to, 0x00, sizeof(to));
0354 eno = _Mutex_recursive_Acquire_timed(mtx, &to);
0355 rtems_test_assert(eno == ETIMEDOUT);
0356 memset(&to, 0xff, sizeof(to));
0357 eno = _Mutex_recursive_Acquire_timed(mtx, &to);
0358 rtems_test_assert(eno == EINVAL);
0359 get_abs_timeout(&to);
0360 eno = _Mutex_recursive_Acquire_timed(mtx, &to);
0361 rtems_test_assert(eno == ETIMEDOUT);
0362
0363 send_event(ctx, idx, EVENT_REC_MTX_RELEASE);
0364 }
0365
0366 static void test_mtx_deadlock(test_context *ctx)
0367 {
0368 struct _Mutex_Control *mtx = &ctx->mtx;
0369
0370 _Mutex_Acquire(mtx);
0371
0372 if (setjmp(ctx->deadlock_return_context) == 0) {
0373 _Mutex_Acquire(mtx);
0374 }
0375
0376 _Mutex_Release(mtx);
0377 }
0378
0379 static void test_condition(test_context *ctx)
0380 {
0381 struct _Condition_Control *cond = &ctx->cond;
0382 size_t a = 0;
0383 size_t b = 1;
0384 int gen_a;
0385 int gen_b;
0386
0387 gen_a = ctx->generation[a];
0388 gen_b = ctx->generation[b];
0389
0390 _Condition_Signal(cond);
0391 _Condition_Broadcast(cond);
0392
0393 send_event(ctx, a, EVENT_CONDITION_WAIT);
0394 send_event(ctx, b, EVENT_CONDITION_WAIT_REC);
0395
0396 rtems_test_assert(ctx->generation[a] == gen_a + 1);
0397 rtems_test_assert(ctx->generation[b] == gen_b + 1);
0398
0399 _Condition_Signal(cond);
0400
0401 rtems_test_assert(ctx->generation[a] == gen_a + 2);
0402 rtems_test_assert(ctx->generation[b] == gen_b + 1);
0403
0404 _Condition_Signal(cond);
0405
0406 rtems_test_assert(ctx->generation[a] == gen_a + 2);
0407 rtems_test_assert(ctx->generation[b] == gen_b + 2);
0408
0409 send_event(ctx, a, EVENT_CONDITION_WAIT);
0410 send_event(ctx, b, EVENT_CONDITION_WAIT_REC);
0411
0412 rtems_test_assert(ctx->generation[a] == gen_a + 3);
0413 rtems_test_assert(ctx->generation[b] == gen_b + 3);
0414
0415 _Condition_Broadcast(cond);
0416
0417 rtems_test_assert(ctx->generation[a] == gen_a + 4);
0418 rtems_test_assert(ctx->generation[b] == gen_b + 4);
0419 }
0420
0421 static void test_condition_timeout(test_context *ctx)
0422 {
0423 struct timespec to;
0424 int eno;
0425
0426 _Mutex_Acquire(&ctx->mtx);
0427 memset(&to, 0x00, sizeof(to));
0428 eno = _Condition_Wait_timed(&ctx->cond, &ctx->mtx, &to);
0429 rtems_test_assert(eno == ETIMEDOUT);
0430 memset(&to, 0xff, sizeof(to));
0431 eno = _Condition_Wait_timed(&ctx->cond, &ctx->mtx, &to);
0432 rtems_test_assert(eno == EINVAL);
0433 get_abs_timeout(&to);
0434 eno = _Condition_Wait_timed(&ctx->cond, &ctx->mtx, &to);
0435 rtems_test_assert(eno == ETIMEDOUT);
0436 _Mutex_Release(&ctx->mtx);
0437
0438 _Mutex_recursive_Acquire(&ctx->rec_mtx);
0439 _Mutex_recursive_Acquire(&ctx->rec_mtx);
0440 memset(&to, 0x00, sizeof(to));
0441 eno = _Condition_Wait_recursive_timed(&ctx->cond, &ctx->rec_mtx, &to);
0442 rtems_test_assert(eno == ETIMEDOUT);
0443 memset(&to, 0xff, sizeof(to));
0444 eno = _Condition_Wait_recursive_timed(&ctx->cond, &ctx->rec_mtx, &to);
0445 rtems_test_assert(eno == EINVAL);
0446 get_abs_timeout(&to);
0447 eno = _Condition_Wait_recursive_timed(&ctx->cond, &ctx->rec_mtx, &to);
0448 rtems_test_assert(eno == ETIMEDOUT);
0449 _Mutex_recursive_Release(&ctx->rec_mtx);
0450 _Mutex_recursive_Release(&ctx->rec_mtx);
0451 }
0452
0453 static void test_sem(test_context *ctx)
0454 {
0455 struct _Semaphore_Control *sem = &ctx->sem;
0456 size_t idx = 0;
0457 int gen;
0458
0459 _Semaphore_Wait(sem);
0460 gen = ctx->generation[idx];
0461 send_event(ctx, idx, EVENT_SEM_WAIT);
0462 rtems_test_assert(ctx->generation[idx] == gen);
0463 _Semaphore_Post(sem);
0464 rtems_test_assert(ctx->generation[idx] == gen + 1);
0465 _Semaphore_Post(sem);
0466 }
0467
0468 static void test_sem_prio_wait_order(test_context *ctx)
0469 {
0470 struct _Semaphore_Control *sem = &ctx->sem;
0471 size_t a = 0;
0472 size_t b = 1;
0473 int gen_a;
0474 int gen_b;
0475
0476 _Semaphore_Wait(sem);
0477
0478 gen_a = ctx->generation[a];
0479 gen_b = ctx->generation[b];
0480
0481 send_event(ctx, b, EVENT_SEM_WAIT);
0482 send_event(ctx, a, EVENT_SEM_WAIT);
0483
0484 rtems_test_assert(ctx->generation[a] == gen_a);
0485 rtems_test_assert(ctx->generation[b] == gen_b);
0486
0487 _Semaphore_Post(sem);
0488
0489 rtems_test_assert(ctx->generation[a] == gen_a + 1);
0490 rtems_test_assert(ctx->generation[b] == gen_b);
0491
0492 _Semaphore_Post(sem);
0493
0494 rtems_test_assert(ctx->generation[a] == gen_a + 1);
0495 rtems_test_assert(ctx->generation[b] == gen_b + 1);
0496 }
0497
0498 static void test_futex(test_context *ctx)
0499 {
0500 struct _Futex_Control *futex = &ctx->futex;
0501 size_t a = 0;
0502 size_t b = 1;
0503 int eno;
0504 int woken;
0505
0506 eno = _Futex_Wait(futex, &ctx->val, 1);
0507 rtems_test_assert(eno == EWOULDBLOCK);
0508
0509 woken = _Futex_Wake(futex, 0);
0510 rtems_test_assert(woken == 0);
0511
0512 woken = _Futex_Wake(futex, 1);
0513 rtems_test_assert(woken == 0);
0514
0515 ctx->val = 1;
0516
0517 ctx->eno[a] = -1;
0518 send_event(ctx, a, EVENT_FUTEX_WAIT);
0519 rtems_test_assert(ctx->eno[a] == -1);
0520
0521 woken = _Futex_Wake(futex, INT_MAX);
0522 rtems_test_assert(woken == 1);
0523 rtems_test_assert(ctx->eno[a] == 0);
0524
0525 ctx->eno[a] = -1;
0526 ctx->eno[b] = -1;
0527 send_event(ctx, a, EVENT_FUTEX_WAIT);
0528 send_event(ctx, b, EVENT_FUTEX_WAIT);
0529 rtems_test_assert(ctx->eno[a] == -1);
0530 rtems_test_assert(ctx->eno[b] == -1);
0531
0532 woken = _Futex_Wake(futex, 1);
0533 rtems_test_assert(woken == 1);
0534 rtems_test_assert(ctx->eno[a] == 0);
0535 rtems_test_assert(ctx->eno[b] == -1);
0536
0537 woken = _Futex_Wake(futex, 1);
0538 rtems_test_assert(woken == 1);
0539 rtems_test_assert(ctx->eno[a] == 0);
0540 rtems_test_assert(ctx->eno[b] == 0);
0541
0542 ctx->eno[a] = -1;
0543 ctx->eno[b] = -1;
0544 send_event(ctx, a, EVENT_FUTEX_WAIT);
0545 send_event(ctx, b, EVENT_FUTEX_WAIT);
0546 rtems_test_assert(ctx->eno[a] == -1);
0547 rtems_test_assert(ctx->eno[b] == -1);
0548
0549 woken = _Futex_Wake(futex, 2);
0550 rtems_test_assert(woken == 2);
0551 rtems_test_assert(ctx->eno[a] == 0);
0552 rtems_test_assert(ctx->eno[b] == 0);
0553 }
0554
0555 static void test_sched(void)
0556 {
0557 rtems_test_assert(_Sched_Index() == 0);
0558 rtems_test_assert(_Sched_Name_to_index("", 0) == -1);
0559 rtems_test_assert(_Sched_Name_to_index("b", 1) == -1);
0560 rtems_test_assert(_Sched_Name_to_index("bl", 2) == -1);
0561 rtems_test_assert(_Sched_Name_to_index("blu", 3) == -1);
0562 rtems_test_assert(_Sched_Name_to_index("blue", 4) == 0);
0563 rtems_test_assert(_Sched_Name_to_index("blueX", 5) == 0);
0564 rtems_test_assert(_Sched_Processor_count(-1) == 0);
0565 rtems_test_assert(_Sched_Processor_count(0) == 1);
0566 rtems_test_assert(_Sched_Processor_count(1) == 0);
0567 }
0568
0569 static void mid_task(rtems_task_argument arg)
0570 {
0571 rtems_test_assert(0);
0572 }
0573
0574 static void high_task(rtems_task_argument idx)
0575 {
0576 test_context *ctx = &test_instance;
0577 rtems_status_code sc;
0578
0579 if (idx == 0) {
0580 sc = rtems_task_start(ctx->mid, mid_task, 0);
0581 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0582
0583 sc = rtems_task_suspend(ctx->mid);
0584 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0585 }
0586
0587 while (true) {
0588 rtems_event_set events;
0589
0590 sc = rtems_event_receive(
0591 RTEMS_ALL_EVENTS,
0592 RTEMS_EVENT_ANY | RTEMS_WAIT,
0593 RTEMS_NO_TIMEOUT,
0594 &events
0595 );
0596 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0597
0598 if ((events & EVENT_MTX_ACQUIRE) != 0) {
0599 _Mutex_Acquire(&ctx->mtx);
0600 ctx->generation[idx] = generation(ctx, idx);
0601 }
0602
0603 if ((events & EVENT_MTX_RELEASE) != 0) {
0604 _Mutex_Release(&ctx->mtx);
0605 }
0606
0607 if ((events & EVENT_MTX_PRIO_INV) != 0) {
0608 sc = rtems_task_resume(ctx->mid);
0609 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0610
0611 _Mutex_Acquire(&ctx->mtx);
0612 ctx->generation[idx] = generation(ctx, idx);
0613 _Mutex_Release(&ctx->mtx);
0614
0615 sc = rtems_task_suspend(ctx->mid);
0616 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0617 }
0618
0619 if ((events & EVENT_REC_MTX_ACQUIRE) != 0) {
0620 _Mutex_recursive_Acquire(&ctx->rec_mtx);
0621 }
0622
0623 if ((events & EVENT_REC_MTX_RELEASE) != 0) {
0624 _Mutex_recursive_Release(&ctx->rec_mtx);
0625 }
0626
0627 if ((events & EVENT_REC_MTX_PRIO_INV) != 0) {
0628 sc = rtems_task_resume(ctx->mid);
0629 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0630
0631 _Mutex_recursive_Acquire(&ctx->rec_mtx);
0632 ctx->generation[idx] = generation(ctx, idx);
0633 _Mutex_recursive_Release(&ctx->rec_mtx);
0634
0635 sc = rtems_task_suspend(ctx->mid);
0636 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0637 }
0638
0639 if ((events & EVENT_SEM_WAIT) != 0) {
0640 _Semaphore_Wait(&ctx->sem);
0641 ctx->generation[idx] = generation(ctx, idx);
0642 }
0643
0644 if ((events & EVENT_FUTEX_WAIT) != 0) {
0645 ctx->eno[idx] = _Futex_Wait(&ctx->futex, &ctx->val, 1);
0646 }
0647
0648 if ((events & EVENT_CONDITION_WAIT) != 0) {
0649 _Mutex_Acquire(&ctx->mtx);
0650 ctx->generation[idx] = generation(ctx, idx);
0651 _Condition_Wait(&ctx->cond, &ctx->mtx);
0652 ctx->generation[idx] = generation(ctx, idx);
0653 _Mutex_Release(&ctx->mtx);
0654 }
0655
0656 if ((events & EVENT_CONDITION_WAIT_REC) != 0) {
0657 _Mutex_recursive_Acquire(&ctx->rec_mtx);
0658 _Mutex_recursive_Acquire(&ctx->rec_mtx);
0659 ctx->generation[idx] = generation(ctx, idx);
0660 _Condition_Wait_recursive(&ctx->cond, &ctx->rec_mtx);
0661 ctx->generation[idx] = generation(ctx, idx);
0662 _Mutex_recursive_Release(&ctx->rec_mtx);
0663 _Mutex_recursive_Release(&ctx->rec_mtx);
0664 }
0665 }
0666 }
0667
0668 static void test(void)
0669 {
0670 test_context *ctx = &test_instance;
0671 rtems_status_code sc;
0672
0673 test_initialization(ctx);
0674
0675 ctx->low = rtems_task_self();
0676
0677 sc = rtems_task_create(
0678 rtems_build_name('M', 'I', 'D', ' '),
0679 3,
0680 RTEMS_MINIMUM_STACK_SIZE,
0681 RTEMS_DEFAULT_MODES,
0682 RTEMS_DEFAULT_ATTRIBUTES,
0683 &ctx->mid
0684 );
0685 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0686
0687 sc = rtems_task_create(
0688 rtems_build_name('H', 'I', 'G', '0'),
0689 1,
0690 RTEMS_MINIMUM_STACK_SIZE,
0691 RTEMS_DEFAULT_MODES,
0692 RTEMS_DEFAULT_ATTRIBUTES,
0693 &ctx->high[0]
0694 );
0695 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0696
0697 sc = rtems_task_start(ctx->high[0], high_task, 0);
0698 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0699
0700 sc = rtems_task_create(
0701 rtems_build_name('H', 'I', 'G', '1'),
0702 2,
0703 RTEMS_MINIMUM_STACK_SIZE,
0704 RTEMS_DEFAULT_MODES,
0705 RTEMS_DEFAULT_ATTRIBUTES,
0706 &ctx->high[1]
0707 );
0708 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0709
0710 sc = rtems_task_start(ctx->high[1], high_task, 1);
0711 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0712
0713 test_recursive_acquire_normal(ctx);
0714 test_recursive_acquire_recursive(ctx);
0715 test_prio_acquire_order(ctx);
0716 test_prio_inv_normal(ctx);
0717 test_prio_inv_recursive(ctx);
0718 test_mtx_timeout_normal(ctx);
0719 test_mtx_timeout_recursive(ctx);
0720 test_mtx_deadlock(ctx);
0721 test_condition(ctx);
0722 test_condition_timeout(ctx);
0723 test_sem(ctx);
0724 test_sem_prio_wait_order(ctx);
0725 test_futex(ctx);
0726 test_sched();
0727
0728 sc = rtems_task_delete(ctx->mid);
0729 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0730
0731 sc = rtems_task_delete(ctx->high[0]);
0732 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0733
0734 sc = rtems_task_delete(ctx->high[1]);
0735 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0736
0737 _Mutex_Destroy(&ctx->mtx);
0738 _Mutex_recursive_Destroy(&ctx->rec_mtx);
0739 _Condition_Destroy(&ctx->cond);
0740 _Semaphore_Destroy(&ctx->sem);
0741 _Futex_Destroy(&ctx->futex);
0742 }
0743
0744 static void Init(rtems_task_argument arg)
0745 {
0746 TEST_BEGIN();
0747
0748 test();
0749
0750 TEST_END();
0751 rtems_test_exit(0);
0752 }
0753
0754 static void fatal_extension(
0755 rtems_fatal_source source,
0756 bool always_set_to_false,
0757 rtems_fatal_code error
0758 )
0759 {
0760
0761 if (
0762 source == INTERNAL_ERROR_CORE
0763 && !always_set_to_false
0764 && error == INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK
0765 ) {
0766 test_context *ctx = &test_instance;
0767
0768 _ISR_Set_level(0);
0769 longjmp(ctx->deadlock_return_context, 1);
0770 }
0771 }
0772
0773 #define CONFIGURE_MICROSECONDS_PER_TICK US_PER_TICK
0774
0775 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0776 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0777
0778 #define CONFIGURE_MAXIMUM_TASKS 4
0779
0780 #define CONFIGURE_INITIAL_EXTENSIONS \
0781 { .fatal = fatal_extension }, \
0782 RTEMS_TEST_INITIAL_EXTENSION
0783
0784 #define CONFIGURE_INIT_TASK_PRIORITY 4
0785 #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
0786
0787 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0788
0789 #define CONFIGURE_SCHEDULER_NAME rtems_build_name('b', 'l', 'u', 'e')
0790
0791 #define CONFIGURE_INIT
0792
0793 #include <rtems/confdefs.h>