/** * @file tests/semaphore.cpp * @brief Semaphore tests * @date Feb 10, 2016 * @author jjacobs * @copyright 2016 Dual Inventive Technology Centre B.V. * * Semaphore tests */ #include #include #define TEST_SEMAPHORE_TIMEOUT_MS 10 void timespec_diff(struct timespec *start, struct timespec *stop, struct timespec *result) { if (start->tv_nsec > stop->tv_nsec) { result->tv_sec = stop->tv_sec - start->tv_sec - 1; result->tv_nsec = start->tv_nsec - stop->tv_nsec; } else { result->tv_sec = stop->tv_sec - start->tv_sec; result->tv_nsec = stop->tv_nsec - start->tv_nsec; } } void timespec_now(struct timespec *now) { clock_gettime(CLOCK_MONOTONIC, now); } bool timespec_exceeded(struct timespec *start, unsigned int ms) { struct timespec stop; struct timespec diff; clock_gettime(CLOCK_MONOTONIC, &stop); timespec_diff(start, &stop, &diff); time_t sec = ms / 1000; long nsec = (ms % 1000) * 1000000; if (diff.tv_sec >= sec && diff.tv_nsec >= nsec) return true; // printf(" diff: %lld.%.9ld\n", (long long)diff.tv_sec, diff.tv_nsec); return false; } /** * Test if the di_bsem_wait_timeout return timeout */ TEST(semaphore, bsem_wait_timeout_locked) { struct timespec begin; di_bsem_t s; di_bsem_init_locked(&s); timespec_now(&begin); ASSERT_EQ(DNE_TIMEOUT, di_bsem_wait_timeout(&s, TEST_SEMAPHORE_TIMEOUT_MS)); ASSERT_TRUE(timespec_exceeded(&begin, TEST_SEMAPHORE_TIMEOUT_MS)); di_bsem_post(&s); ASSERT_EQ(DNOK, di_bsem_wait_timeout(&s, TEST_SEMAPHORE_TIMEOUT_MS)); timespec_now(&begin); ASSERT_EQ(DNE_TIMEOUT, di_bsem_wait_timeout(&s, TEST_SEMAPHORE_TIMEOUT_MS)); ASSERT_TRUE(timespec_exceeded(&begin, TEST_SEMAPHORE_TIMEOUT_MS)); } /** * Test if the di_bsem_wait_timeout return timeout */ TEST(semaphore, bsem_wait_timeout_unlocked) { struct timespec begin; di_bsem_t s; di_bsem_init_unlocked(&s); timespec_now(&begin); ASSERT_EQ(DNOK, di_bsem_wait_timeout(&s, TEST_SEMAPHORE_TIMEOUT_MS)); ASSERT_FALSE(timespec_exceeded(&begin, TEST_SEMAPHORE_TIMEOUT_MS)); timespec_now(&begin); ASSERT_EQ(DNE_TIMEOUT, di_bsem_wait_timeout(&s, TEST_SEMAPHORE_TIMEOUT_MS)); ASSERT_TRUE(timespec_exceeded(&begin, TEST_SEMAPHORE_TIMEOUT_MS)); } /** * Check if double posting on a binary semaphore will not result in two times DNOK * when di_bsem_wait_timeout is called. */ TEST(semaphore, bsem_wait_timeout_double_post) { struct timespec begin; di_bsem_t s; di_bsem_init_unlocked(&s); di_bsem_post(&s); di_bsem_post(&s); ASSERT_EQ(DNOK, di_bsem_wait_timeout(&s, TEST_SEMAPHORE_TIMEOUT_MS)); timespec_now(&begin); ASSERT_EQ(DNE_TIMEOUT, di_bsem_wait_timeout(&s, TEST_SEMAPHORE_TIMEOUT_MS)); ASSERT_TRUE(timespec_exceeded(&begin, TEST_SEMAPHORE_TIMEOUT_MS)); } TEST(semaphore, bsem_post_wait) { di_bsem_t s; di_bsem_init_unlocked(&s); di_bsem_post(&s); di_bsem_wait(&s); } TEST(semaphore, bsem_wait_post) { di_bsem_t s; di_bsem_init_locked(&s); di_bsem_post(&s); di_bsem_wait(&s); }