void C64::synchronizeTiming() { const uint64_t earlyWakeup = 1500000; /* 1.5 milliseconds */ // Convert usec into kernel unit int64_t kernelTargetTime = nanos_to_abs(nanoTargetTime); // Check how long we're supposed to sleep int64_t timediff = kernelTargetTime - (int64_t)mach_absolute_time(); if (timediff > 200000000 /* 0.2 sec */) { // The emulator seems to be out of sync, so we better reset the synchronization timer debug(2, "Emulator lost synchronization (%lld). Restarting synchronization timer.\n", timediff); restartTimer(); // return; } // Sleep and update target timer // debug(2, "%p Sleeping for %lld\n", this, kernelTargetTime - mach_absolute_time()); int64_t jitter = sleepUntil(kernelTargetTime, earlyWakeup); nanoTargetTime += vic->getFrameDelay(); // debug(2, "Jitter = %d", jitter); if (jitter > 1000000000 /* 1 sec */) { // The emulator did not keep up with the real time clock. Instead of // running behind for a long time, we reset the synchronization timer debug(2, "Jitter exceeds limit (%lld). Restarting synchronization timer.\n", jitter); restartTimer(); } }
void C64::synchronizeTiming() { const uint64_t earlyWakeup = 1500000; /* 1.5 milliseconds */ const uint64_t maxJitter = 1000000000; /* 1 second */ // Convert usec into kernel unit and sleep uint64_t kernelTargetTime = nanos_to_abs(nanoTargetTime); int64_t jitter = sleepUntil(kernelTargetTime, earlyWakeup); // Update target time nanoTargetTime += vic->getFrameDelay(); // debug(2, "Jitter = %d", jitter); if (jitter > maxJitter) { // The emulator did not keep up with the real time clock. Instead of // running behind for a long time, we reset the synchronization timer debug(2, "Jitter exceeds limit. Restarting synchronization timer.\n"); restartTimer(); } #if 0 // Old sleep // determine how long we should wait uint64_t timeToSleep = targetTime - usec(); targetTime += vic->getFrameDelay() / 1000; // OLD if (timeToSleep > 0) { sleepMicrosec(timeToSleep); } else { restartTimer(); } #endif }