123 lines
2.9 KiB
C++
123 lines
2.9 KiB
C++
/**
|
|
* @file tests/semaphore.cpp
|
|
* @brief Semaphore tests
|
|
* @date Feb 10, 2016
|
|
* @author jjacobs
|
|
* @copyright 2016 Dual Inventive Technology Centre B.V.
|
|
*
|
|
* Semaphore tests
|
|
*/
|
|
#include <di/semaphore.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#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);
|
|
}
|