diff --git a/src/Thread.c b/src/Thread.c
index f4d43fb6f..f8b5279f7 100644
--- a/src/Thread.c
+++ b/src/Thread.c
@@ -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);
diff --git a/test/thread.c b/test/thread.c
index 9e6de963a..5f91cff37 100644
--- a/test/thread.c
+++ b/test/thread.c
@@ -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);