Fixed condition variable timed wait. Updated thread test for current implementation.

This commit is contained in:
fpagliughi 2025-01-13 09:43:49 -05:00
parent 2805ddedea
commit 05e6d71f6f
2 changed files with 27 additions and 20 deletions

View File

@ -51,6 +51,8 @@
#include "OsWrapper.h"
#define NSEC_PER_SEC 1000000000L
/**
* Start a new thread
* @param fn the function to run, must be of the correct signature
@ -443,12 +445,8 @@ int Thread_wait_cond(cond_type condvar, int timeout_ms)
{
int rc = 0;
struct timespec cond_timeout;
struct timespec interval;
FUNC_ENTRY;
interval.tv_sec = timeout_ms / 1000;
interval.tv_nsec = (timeout_ms % 1000) * 1000000L;
#if defined(__APPLE__) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200 /* for older versions of MacOS */
struct timeval cur_time;
gettimeofday(&cur_time, NULL);
@ -458,13 +456,20 @@ int Thread_wait_cond(cond_type condvar, int timeout_ms)
clock_gettime(CLOCK_REALTIME, &cond_timeout);
#endif
cond_timeout.tv_sec += interval.tv_sec;
cond_timeout.tv_nsec += (timeout_ms % 1000) * 1000000L;
if (timeout_ms > 0) {
struct timespec interval;
if (cond_timeout.tv_nsec >= 1000000000L)
{
cond_timeout.tv_sec++;
cond_timeout.tv_nsec += (cond_timeout.tv_nsec - 1000000000L);
interval.tv_sec = timeout_ms / 1000;
interval.tv_nsec = (timeout_ms % 1000) * 1000000L;
cond_timeout.tv_sec += interval.tv_sec;
cond_timeout.tv_nsec += interval.tv_nsec;
while (cond_timeout.tv_nsec >= NSEC_PER_SEC)
{
cond_timeout.tv_sec++;
cond_timeout.tv_nsec -= NSEC_PER_SEC;
}
}
pthread_mutex_lock(&condvar->mutex);

View File

@ -244,7 +244,7 @@ static thread_return_type WINAPI sem_secondary(void* n)
duration = elapsed(start);
assert("rc 0 from lock mutex", rc == 0, "rc was %d", rc);
MyLog(LOGA_INFO, "Lock duration was %ld", duration);
assert("duration is 2s", duration >= 2000L, "duration was %ld", duration);
assert("duration is 2s", duration >= 1999L && duration < 2050L, "duration was %ld", duration);
MyLog(LOGA_DEBUG, "Secondary thread ending");
return 0;
@ -288,10 +288,14 @@ int test_sem(struct Options options)
assert("rc 0 from post_sem", rc == 0, "rc was %d\n", rc);
}
rc = Thread_check_sem(sem);
assert("rc 1 from check_sem", rc == 1, "rc was %d", rc);
// Binary sem, so additional checks should be zero
for (i = 0; i < 10; ++i)
{
rc = Thread_check_sem(sem);
assert("rc 1 from check_sem", rc == 1, "rc was %d", rc);
assert("rc 0 from check_sem", rc == 0, "rc was %d", rc);
}
rc = Thread_check_sem(sem);
assert("rc 0 from check_sem", rc == 0, "rc was %d", rc);
@ -300,7 +304,7 @@ int test_sem(struct Options options)
start = start_clock();
rc = Thread_wait_sem(sem, 1500);
duration = elapsed(start);
assert("rc ETIMEDOUT from lock mutex", rc == ETIMEDOUT, "rc was %d", rc);
assert("rc ETIMEDOUT from lock mutex", rc == ETIMEDOUT || rc == EAGAIN, "rc was %d", rc);
MyLog(LOGA_INFO, "Lock duration was %ld", duration);
assert("duration is 2s", duration >= 1500L, "duration was %ld", duration);
@ -310,7 +314,7 @@ int test_sem(struct Options options)
mysleep(2);
MyLog(LOGA_DEBUG, "post secondary");
rc = Thread_post_sem(sem);
assert("rc 1 from post_sem", rc == 1, "rc was %d", rc);
assert("rc 0 from post_sem", rc == 0, "rc was %d", rc);
mysleep(1);
@ -333,10 +337,10 @@ thread_return_type cond_secondary(void* n)
MyLog(LOGA_DEBUG, "This will time out");
start = start_clock();
rc = Thread_wait_cond(cond, 1);
rc = Thread_wait_cond(cond, 1000);
duration = elapsed(start);
MyLog(LOGA_INFO, "Lock duration was %ld", duration);
assert("duration is about 1s", duration >= 1000L && duration <= 1050L, "duration was %ld", duration);
assert("duration is about 1s", duration >= 999L && duration <= 1050L, "duration was %ld", duration);
assert("rc non 0 from wait_cond", rc == ETIMEDOUT, "rc was %d", rc);
MyLog(LOGA_DEBUG, "This should hang around a few seconds");
@ -370,11 +374,11 @@ int test_cond(struct Options options)
MyLog(LOGA_DEBUG, "Check timeout");
start = start_clock();
rc = Thread_wait_cond(cond, 2);
rc = Thread_wait_cond(cond, 2000);
duration = elapsed(start);
assert("rc ETIMEDOUT from lock mutex", rc == ETIMEDOUT, "rc was %d", rc);
MyLog(LOGA_INFO, "Lock duration was %ld", duration);
assert("duration is 2s", duration >= 2000L, "duration was %ld", duration);
assert("duration is 2s", duration >= 1999L && duration < 2050L, "duration was %ld", duration);
/* multiple posts */
for (i = 0; i < 10; ++i)
@ -389,8 +393,6 @@ int test_cond(struct Options options)
rc = Thread_wait_cond(cond, 0);
assert("rc non-zero from wait_cond", rc == ETIMEDOUT, "rc was %d", rc);
}
rc = Thread_wait_cond(cond, 0);
assert("rc non-zero from wait_cond", rc == ETIMEDOUT, "rc was %d", rc);
MyLog(LOGA_DEBUG, "Post secondary but it will time out");
rc = Thread_signal_cond(cond);