src.dualinventive.com/dinet/libdi/tests/semaphore.cpp

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);
}