Specialize usleep for Win32

This commit is contained in:
Zach Pomerantz 2016-05-04 15:40:53 -07:00
parent 526143b097
commit 1553f532ba

View file

@ -456,24 +456,39 @@ void printVoxelCode(unsigned char* voxelCode) {
#ifdef _WIN32 #ifdef _WIN32
void usleep(int waitTime) { void usleep(int waitTime) {
quint64 sleepUntil = waitTime + usecTimestampNow(); // Use QueryPerformanceCounter for least overhead
LARGE_INTEGER now; // ticks
QueryPerformanceCounter(&now);
static int64_t ticksPerSec = 0;
if (ticksPerSec == 0) {
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
ticksPerSec = frequency.QuadPart;
}
// order ops to avoid loss in precision
int64_t waitTicks = (ticksPerSec * waitTime) / USECS_PER_SECOND;
int64_t sleepTicks = now.QuadPart + waitTicks;
// Busy wait with sleep/yield where possible // Busy wait with sleep/yield where possible
while (true) { while (true) {
quint64 now = usecTimestampNow(); QueryPerformanceCounter(&now);
if (now >= sleepUntil) { if (now.QuadPart >= sleepTicks) {
break; break;
} }
// Sleep if we have at least 1ms to spare // Sleep if we have at least 1ms to spare
const int MIN_SLEEP_USECS = 1000; const int64_t MIN_SLEEP_USECS = 1000;
// msleep is allowed to overshoot, so give it a 100us berth // msleep is allowed to overshoot, so give it a 100us berth
const int MIN_SLEEP_USECS_BERTH = 100; const int64_t MIN_SLEEP_USECS_BERTH = 100;
if (sleepUntil - now > (MIN_SLEEP_USECS + MIN_SLEEP_USECS_BERTH)) { // order ops to avoid loss in precision
unsigned long sleepFor = (sleepUntil - now - MIN_SLEEP_USECS_BERTH) / USECS_PER_MSEC; int64_t sleepFor = ((sleepTicks - now.QuadPart) * USECS_PER_SECOND) / ticksPerSec - MIN_SLEEP_USECS_BERTH;
QThread::msleep(sleepFor); if (sleepFor > MIN_SLEEP_USECS) {
Sleep((DWORD)(sleepFor / USECS_PER_MSEC));
// Yield otherwise // Yield otherwise
} else { } else {
// Use Qt to delegate, as SwitchToThread is only supported starting with XP
QThread::yieldCurrentThread(); QThread::yieldCurrentThread();
} }
} }