Commit 68111323b363ac89333feb742e4372aa02db0f30

Luke Dashjr 2012-07-12T18:01:14

Bugfix: Make our Windows nanosleep/sleep replacements standards-compliant (which fixes nmsleep) and include compat.h for bitforce (for sleep)

diff --git a/compat.h b/compat.h
index 453c9ae..c6e38d8 100644
--- a/compat.h
+++ b/compat.h
@@ -2,18 +2,55 @@
 #define __COMPAT_H__
 
 #ifdef WIN32
+#include <errno.h>
 #include <time.h>
 #include <pthread.h>
+#include <sys/time.h>
 
 #include <windows.h>
 
-static inline void nanosleep(struct timespec *rgtp, void *__unused)
+#include "miner.h"  // for timersub
+
+static inline int nanosleep(const struct timespec *req, struct timespec *rem)
 {
-	Sleep(rgtp->tv_nsec / 1000000);
+	struct timeval tstart;
+	DWORD msecs;
+
+	gettimeofday(&tstart, NULL);
+	msecs = (req->tv_sec * 1000) + ((999999 + req->tv_nsec) / 1000000);
+
+	if (SleepEx(msecs, true) == WAIT_IO_COMPLETION) {
+		if (rem) {
+			struct timeval tdone, tnow, tleft;
+			tdone.tv_sec = tstart.tv_sec + req->tv_sec;
+			tdone.tv_usec = tstart.tv_usec + ((999 + req->tv_nsec) / 1000);
+			if (tdone.tv_usec > 1000000) {
+				tdone.tv_usec -= 1000000;
+				++tdone.tv_sec;
+			}
+
+			gettimeofday(&tnow, NULL);
+			if (timercmp(&tnow, &tdone, >))
+				return 0;
+			timersub(&tdone, &tnow, &tleft);
+
+			rem->tv_sec = tleft.tv_sec;
+			rem->tv_nsec = tleft.tv_usec * 1000;
+		}
+		errno = EINTR;
+		return -1;
+	}
+	return 0;
 }
-static inline void sleep(unsigned int secs)
+
+static inline int sleep(unsigned int secs)
 {
-	Sleep(secs * 1000);
+	struct timespec req, rem;
+	req.tv_sec = secs;
+	req.tv_nsec = 0;
+	if (!nanosleep(&req, &rem))
+		return 0;
+	return rem.tv_sec + (rem.tv_nsec ? 1 : 0);
 }
 
 enum {
diff --git a/driver-bitforce.c b/driver-bitforce.c
index c45b250..c291367 100644
--- a/driver-bitforce.c
+++ b/driver-bitforce.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include "compat.h"
 #include "fpgautils.h"
 #include "miner.h"