static void msg1_execute(void) { msg_t msg; /* * Testing the whole messages loop. */ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority() + 1, thread, chThdSelf()); chMsgRelease(msg = chMsgWait()); test_emit_token(msg); chMsgRelease(msg = chMsgWait()); test_emit_token(msg); chMsgRelease(msg = chMsgWait()); test_emit_token(msg); test_assert_sequence(1, "ABC"); /* * Testing message fetch using chMsgGet(). * Note, the following is valid because the sender has higher priority than * the receiver. */ msg = chMsgGet(); test_assert(1, msg != 0, "no message"); chMsgRelease(0); test_assert(2, msg == 'D', "wrong message"); /* * Must not have pending messages. */ msg = chMsgGet(); test_assert(3, msg == 0, "unknown message"); }
static void test_task_delete(void) { test_emit_token('A'); (void) OS_TaskInstallDeleteHandler(delete_handler); while (!OS_TaskDeleteCheck()) { (void) OS_TaskDelay(1); } test_emit_token('B'); }
static THD_FUNCTION(thread10, p) { chMtxLock(&m1); chCondWait(&c1); test_emit_token(*(char *)p); chMtxUnlock(&m1); }
static msg_t thread1(void *p) { chMtxLock(&m1); test_emit_token(*(char *)p); chMtxUnlock(); return 0; }
static void test_006_001_execute(void) { thread_t *tp; msg_t msg; /* [6.1.1] Starting the messenger thread.*/ test_set_step(1); { threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() + 1, msg_thread1, chThdGetSelfX()); } /* [6.1.2] Waiting for four messages then testing the receive order.*/ test_set_step(2); { unsigned i; for (i = 0; i < 4; i++) { tp = chMsgWait(); msg = chMsgGet(tp); chMsgRelease(tp, msg); test_emit_token(msg); } test_wait_threads(); test_assert_sequence("ABCD", "invalid sequence"); } }
/* High priority thread */ static THD_FUNCTION(thread3H, p) { (void)p; chThdSleepMilliseconds(40); test_cpu_pulse(20); test_emit_token('B'); }
/* Lowest priority thread */ static THD_FUNCTION(thread3LL, p) { (void)p; chMtxLock(&m1); test_cpu_pulse(30); chMtxUnlock(&m1); test_emit_token('E'); }
/* High priority thread */ static msg_t thread3H(void *p) { (void)p; chThdSleepMilliseconds(40); test_cpu_pulse(20); test_emit_token('B'); return 0; }
static THD_FUNCTION(thread1, p) { chSysLock(); chThdResumeI(&tr1, MSG_OK); chSchRescheduleS(); chSysUnlock(); test_emit_token(*(char *)p); }
static void queues1_execute(void) { unsigned i; size_t n; /* Initial empty state */ test_assert_lock(1, chIQIsEmptyI(&iq), "not empty"); /* Queue filling */ chSysLock(); for (i = 0; i < TEST_QUEUES_SIZE; i++) chIQPutI(&iq, 'A' + i); chSysUnlock(); test_assert_lock(2, chIQIsFullI(&iq), "still has space"); test_assert_lock(3, chIQPutI(&iq, 0) == Q_FULL, "failed to report Q_FULL"); /* Queue emptying */ for (i = 0; i < TEST_QUEUES_SIZE; i++) test_emit_token(chIQGet(&iq)); test_assert_lock(4, chIQIsEmptyI(&iq), "still full"); test_assert_sequence(5, "ABCD"); /* Queue filling again */ chSysLock(); for (i = 0; i < TEST_QUEUES_SIZE; i++) chIQPutI(&iq, 'A' + i); chSysUnlock(); /* Reading the whole thing */ n = chIQReadTimeout(&iq, wa[1], TEST_QUEUES_SIZE * 2, TIME_IMMEDIATE); test_assert(6, n == TEST_QUEUES_SIZE, "wrong returned size"); test_assert_lock(7, chIQIsEmptyI(&iq), "still full"); /* Queue filling again */ chSysLock(); for (i = 0; i < TEST_QUEUES_SIZE; i++) chIQPutI(&iq, 'A' + i); chSysUnlock(); /* Partial reads */ n = chIQReadTimeout(&iq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); test_assert(8, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); n = chIQReadTimeout(&iq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); test_assert(9, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); test_assert_lock(10, chIQIsEmptyI(&iq), "still full"); /* Testing reset */ chSysLock(); chIQPutI(&iq, 0); chIQResetI(&iq); chSysUnlock(); test_assert_lock(11, chIQGetFullI(&iq) == 0, "still full"); threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread1, NULL); test_assert_lock(12, chIQGetFullI(&iq) == 0, "not empty"); test_wait_threads(); /* Timeout */ test_assert(13, chIQGetTimeout(&iq, 10) == Q_TIMEOUT, "wrong timeout return"); }
/* Low priority thread */ static THD_FUNCTION(thread2L, p) { (void)p; chMtxLock(&m1); test_cpu_pulse(40); chMtxUnlock(&m1); test_cpu_pulse(10); test_emit_token('C'); }
/* Lowest priority thread */ static msg_t thread3LL(void *p) { (void)p; chMtxLock(&m1); test_cpu_pulse(30); chMtxUnlock(); test_emit_token('E'); return 0; }
/* Highest priority thread */ static THD_FUNCTION(thread3HH, p) { (void)p; chThdSleepMilliseconds(50); chMtxLock(&m2); test_cpu_pulse(10); chMtxUnlock(&m2); test_emit_token('A'); }
/* Highest priority thread */ static msg_t thread3HH(void *p) { (void)p; chThdSleepMilliseconds(50); chMtxLock(&m2); test_cpu_pulse(10); chMtxUnlock(); test_emit_token('A'); return 0; }
static void test_task_writer(void) { unsigned i; int32 err; for (i = 0; i < WRITER_NUM_MESSAGES; i++) { err = OS_QueuePut(qid, "Hello World", 12, 0); if (err != OS_SUCCESS) { test_emit_token('*'); } } }
static THD_FUNCTION(thread11, p) { chMtxLock(&m2); chMtxLock(&m1); #if CH_CFG_USE_CONDVARS_TIMEOUT || defined(__DOXYGEN__) chCondWaitTimeout(&c1, TIME_INFINITE); #else chCondWait(&c1); #endif test_emit_token(*(char *)p); chMtxUnlock(&m1); chMtxUnlock(&m2); }
static msg_t thread11(void *p) { chMtxLock(&m2); chMtxLock(&m1); #if CH_USE_CONDVARS_TIMEOUT || defined(__DOXYGEN__) chCondWaitTimeout(&c1, TIME_INFINITE); #else chCondWait(&c1); #endif test_emit_token(*(char *)p); chMtxUnlock(); chMtxUnlock(); return 0; }
static void msg1_execute(void) { thread_t *tp; msg_t msg; /* * Testing the whole messages loop. */ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() + 1, thread, chThdGetSelfX()); tp = chMsgWait(); msg = chMsgGet(tp); chMsgRelease(tp, msg); test_emit_token(msg); tp = chMsgWait(); msg = chMsgGet(tp); chMsgRelease(tp, msg); test_emit_token(msg); tp = chMsgWait(); msg = chMsgGet(tp); chMsgRelease(tp, msg); test_emit_token(msg); test_assert_sequence(1, "ABC"); }
static void queues2_execute(void) { unsigned i; size_t n; /* Initial empty state */ test_assert_lock(1, chOQIsEmptyI(&oq), "not empty"); /* Queue filling */ for (i = 0; i < TEST_QUEUES_SIZE; i++) chOQPut(&oq, 'A' + i); test_assert_lock(2, chOQIsFullI(&oq), "still has space"); /* Queue emptying */ for (i = 0; i < TEST_QUEUES_SIZE; i++) { char c; chSysLock(); c = chOQGetI(&oq); chSysUnlock(); test_emit_token(c); } test_assert_lock(3, chOQIsEmptyI(&oq), "still full"); test_assert_sequence(4, "ABCD"); test_assert_lock(5, chOQGetI(&oq) == Q_EMPTY, "failed to report Q_EMPTY"); /* Writing the whole thing */ n = chOQWriteTimeout(&oq, wa[1], TEST_QUEUES_SIZE * 2, TIME_IMMEDIATE); test_assert(6, n == TEST_QUEUES_SIZE, "wrong returned size"); test_assert_lock(7, chOQIsFullI(&oq), "not full"); threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread2, NULL); test_assert_lock(8, chOQGetFullI(&oq) == TEST_QUEUES_SIZE, "not empty"); test_wait_threads(); /* Testing reset */ chSysLock(); chOQResetI(&oq); chSysUnlock(); test_assert_lock(9, chOQGetFullI(&oq) == 0, "still full"); /* Partial writes */ n = chOQWriteTimeout(&oq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); test_assert(10, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); n = chOQWriteTimeout(&oq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); test_assert(11, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); test_assert_lock(12, chOQIsFullI(&oq), "not full"); /* Timeout */ test_assert(13, chOQPutTimeout(&oq, 0, 10) == Q_TIMEOUT, "wrong timeout return"); }
static void rt_test_005_003_execute(void) { unsigned i; systime_t target_time; msg_t msg; /* [5.3.1] Testing special case TIME_IMMEDIATE.*/ test_set_step(1); { msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE); test_assert(msg == MSG_TIMEOUT, "wrong wake-up message"); test_assert(queue_isempty(&sem1.queue), "queue not empty"); test_assert(sem1.cnt == 0, "counter not zero"); } /* [5.3.2] Testing non-timeout condition.*/ test_set_step(2); { threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1, thread2, 0); msg = chSemWaitTimeout(&sem1, TIME_MS2I(500)); test_wait_threads(); test_assert(msg == MSG_OK, "wrong wake-up message"); test_assert(queue_isempty(&sem1.queue), "queue not empty"); test_assert(sem1.cnt == 0, "counter not zero"); } /* [5.3.3] Testing timeout condition.*/ test_set_step(3); { target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(5 * 50)); for (i = 0; i < 5; i++) { test_emit_token('A' + i); msg = chSemWaitTimeout(&sem1, TIME_MS2I(50)); test_assert(msg == MSG_TIMEOUT, "wrong wake-up message"); test_assert(queue_isempty(&sem1.queue), "queue not empty"); test_assert(sem1.cnt == 0, "counter not zero"); } test_assert_sequence("ABCDE", "invalid sequence"); test_assert_time_window(target_time, chTimeAddX(target_time, ALLOWED_DELAY), "out of time window"); } }
static void sem2_execute(void) { int i; systime_t target_time; msg_t msg; /* * Testing special case TIME_IMMEDIATE. */ msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE); test_assert(1, msg == RDY_TIMEOUT, "wrong wake-up message"); test_assert(2, isempty(&sem1.s_queue), "queue not empty"); test_assert(3, sem1.s_cnt == 0, "counter not zero"); /* * Testing not timeout condition. */ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority() - 1, thread2, 0); msg = chSemWaitTimeout(&sem1, MS2ST(500)); test_wait_threads(); test_assert(4, msg == RDY_OK, "wrong wake-up message"); test_assert(5, isempty(&sem1.s_queue), "queue not empty"); test_assert(6, sem1.s_cnt == 0, "counter not zero"); /* * Testing timeout condition. */ test_wait_tick(); target_time = chTimeNow() + MS2ST(5 * 500); for (i = 0; i < 5; i++) { test_emit_token('A' + i); msg = chSemWaitTimeout(&sem1, MS2ST(500)); test_assert(7, msg == RDY_TIMEOUT, "wrong wake-up message"); test_assert(8, isempty(&sem1.s_queue), "queue not empty"); test_assert(9, sem1.s_cnt == 0, "counter not zero"); } test_assert_sequence(10, "ABCDE"); test_assert_time_window(11, target_time, target_time + ALLOWED_DELAY); }
static void h3(eventid_t id) {(void)id;test_emit_token('C');}
static void h2(eventid_t id) {(void)id;test_emit_token('B');}
static void h1(eventid_t id) {(void)id;test_emit_token('A');}
static THD_FUNCTION(thread1, p) { chSemWait(&sem1); test_emit_token(*(char *)p); }
static THD_FUNCTION(thread12, p) { chMtxLock(&m2); test_emit_token(*(char *)p); chMtxUnlock(&m2); }
static void mbox1_execute(void) { msg_t msg1, msg2; unsigned i; /* * Testing initial space. */ test_assert_lock(1, chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size"); /* * Testing enqueuing and backward circularity. */ for (i = 0; i < MB_SIZE - 1; i++) { msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE); test_assert(2, msg1 == MSG_OK, "wrong wake-up message"); } msg1 = chMBPostAhead(&mb1, 'A', TIME_INFINITE); test_assert(3, msg1 == MSG_OK, "wrong wake-up message"); /* * Testing post timeout. */ msg1 = chMBPost(&mb1, 'X', 1); test_assert(4, msg1 == MSG_TIMEOUT, "wrong wake-up message"); chSysLock(); msg1 = chMBPostI(&mb1, 'X'); chSysUnlock(); test_assert(5, msg1 == MSG_TIMEOUT, "wrong wake-up message"); msg1 = chMBPostAhead(&mb1, 'X', 1); test_assert(6, msg1 == MSG_TIMEOUT, "wrong wake-up message"); chSysLock(); msg1 = chMBPostAheadI(&mb1, 'X'); chSysUnlock(); test_assert(7, msg1 == MSG_TIMEOUT, "wrong wake-up message"); /* * Testing final conditions. */ test_assert_lock(8, chMBGetFreeCountI(&mb1) == 0, "still empty"); test_assert_lock(9, chMBGetUsedCountI(&mb1) == MB_SIZE, "not full"); test_assert_lock(10, mb1.rdptr == mb1.wrptr, "pointers not aligned"); /* * Testing dequeuing. */ for (i = 0; i < MB_SIZE; i++) { msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE); test_assert(11, msg1 == MSG_OK, "wrong wake-up message"); test_emit_token(msg2); } test_assert_sequence(12, "ABCDE"); /* * Testing buffer circularity. */ msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE); test_assert(13, msg1 == MSG_OK, "wrong wake-up message"); msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE); test_assert(14, msg1 == MSG_OK, "wrong wake-up message"); test_assert(15, mb1.buffer == mb1.wrptr, "write pointer not aligned to base"); test_assert(16, mb1.buffer == mb1.rdptr, "read pointer not aligned to base"); /* * Testing fetch timeout. */ msg1 = chMBFetch(&mb1, &msg2, 1); test_assert(17, msg1 == MSG_TIMEOUT, "wrong wake-up message"); chSysLock(); msg1 = chMBFetchI(&mb1, &msg2); chSysUnlock(); test_assert(18, msg1 == MSG_TIMEOUT, "wrong wake-up message"); /* * Testing final conditions. */ test_assert_lock(19, chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty"); test_assert_lock(20, chMBGetUsedCountI(&mb1) == 0, "still full"); test_assert_lock(21, mb1.rdptr == mb1.wrptr, "pointers not aligned"); /* * Testing I-Class. */ chSysLock(); msg1 = chMBPostI(&mb1, 'A'); test_assert(22, msg1 == MSG_OK, "wrong wake-up message"); msg1 = chMBPostI(&mb1, 'B'); test_assert(23, msg1 == MSG_OK, "wrong wake-up message"); msg1 = chMBPostI(&mb1, 'C'); test_assert(24, msg1 == MSG_OK, "wrong wake-up message"); msg1 = chMBPostI(&mb1, 'D'); test_assert(25, msg1 == MSG_OK, "wrong wake-up message"); msg1 = chMBPostI(&mb1, 'E'); chSysUnlock(); test_assert(26, msg1 == MSG_OK, "wrong wake-up message"); test_assert(27, mb1.rdptr == mb1.wrptr, "pointers not aligned"); for (i = 0; i < MB_SIZE; i++) { chSysLock(); msg1 = chMBFetchI(&mb1, &msg2); chSysUnlock(); test_assert(28, msg1 == MSG_OK, "wrong wake-up message"); test_emit_token(msg2); } test_assert_sequence(29, "ABCDE"); test_assert_lock(30, chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty"); test_assert_lock(31, chMBGetUsedCountI(&mb1) == 0, "still full"); test_assert(32, mb1.rdptr == mb1.wrptr, "pointers not aligned"); chSysLock(); msg1 = chMBPostAheadI(&mb1, 'E'); test_assert(33, msg1 == MSG_OK, "wrong wake-up message"); msg1 = chMBPostAheadI(&mb1, 'D'); test_assert(34, msg1 == MSG_OK, "wrong wake-up message"); msg1 = chMBPostAheadI(&mb1, 'C'); test_assert(35, msg1 == MSG_OK, "wrong wake-up message"); msg1 = chMBPostAheadI(&mb1, 'B'); test_assert(36, msg1 == MSG_OK, "wrong wake-up message"); msg1 = chMBPostAheadI(&mb1, 'A'); chSysUnlock(); test_assert(37, msg1 == MSG_OK, "wrong wake-up message"); test_assert(38, mb1.rdptr == mb1.wrptr, "pointers not aligned"); for (i = 0; i < MB_SIZE; i++) { chSysLock(); msg1 = chMBFetchI(&mb1, &msg2); chSysUnlock(); test_assert(39, msg1 == MSG_OK, "wrong wake-up message"); test_emit_token(msg2); } test_assert_sequence(40, "ABCDE"); test_assert_lock(41, chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty"); test_assert_lock(42, chMBGetUsedCountI(&mb1) == 0, "still full"); test_assert(43, mb1.rdptr == mb1.wrptr, "pointers not aligned"); /* * Testing reset. */ chMBReset(&mb1); /* * Re-testing final conditions. */ test_assert_lock(44, chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty"); test_assert_lock(45, chMBGetUsedCountI(&mb1) == 0, "still full"); test_assert_lock(46, mb1.buffer == mb1.wrptr, "write pointer not aligned to base"); test_assert_lock(47, mb1.buffer == mb1.rdptr, "read pointer not aligned to base"); }
static void delete_handler(void) { test_emit_token('C'); }
static msg_t thread(void *p) { test_emit_token(*(char *)p); return 0; }
static void test_008_001_execute(void) { msg_t msg1, msg2; unsigned i; /* [8.1.1] Testing the mailbox size.*/ test_set_step(1); { test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size"); } /* [8.1.2] Resetting the mailbox, conditions are checked, no errors expected.*/ test_set_step(2); { chMBReset(&mb1); test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty"); test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full"); test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base"); test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base"); } /* [8.1.3] Filling the mailbox using chMBPost() and chMBPostAhead() once, no errors expected.*/ test_set_step(3); { for (i = 0; i < MB_SIZE - 1; i++) { msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE); test_assert(msg1 == MSG_OK, "wrong wake-up message"); } msg1 = chMBPostAhead(&mb1, 'A', TIME_INFINITE); test_assert(msg1 == MSG_OK, "wrong wake-up message"); } /* [8.1.4] Testing intermediate conditions. Data pointers must be aligned, semaphore counters are checked.*/ test_set_step(4); { test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty"); test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full"); test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned"); } /* [8.1.5] Emptying the mailbox using chMBFetch(), no errors expected.*/ test_set_step(5); { for (i = 0; i < MB_SIZE; i++) { msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE); test_assert(msg1 == MSG_OK, "wrong wake-up message"); test_emit_token(msg2); } test_assert_sequence("ABCD", "wrong get sequence"); } /* [8.1.6] Posting and then fetching one more message, no errors expected.*/ test_set_step(6); { msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE); test_assert(msg1 == MSG_OK, "wrong wake-up message"); msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE); test_assert(msg1 == MSG_OK, "wrong wake-up message"); } /* [8.1.7] Testing final conditions. Data pointers must be aligned to buffer start, semaphore counters are checked.*/ test_set_step(7); { test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty"); test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full"); test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base"); test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base"); } }