// the timer tick) accuracy which is too bad to catch 60Hz...
bool SGTimeStamp::sleepUntil(const SGTimeStamp& abstime)
{
-#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS)
+ // FreeBSD is missing clock_nanosleep, see
+ // https://wiki.freebsd.org/FreeBSD_and_Standards
+#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS) && !defined(__FreeBSD__)
SGTimeStamp abstimeForSleep = abstime;
// Always undersleep by resolution of the clock
bool SGTimeStamp::sleepFor(const SGTimeStamp& reltime)
{
-#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS)
+ // see comment above regarding FreeBSD
+#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS) && !defined(__FreeBSD__)
struct timespec ts;
ts.tv_sec = reltime._sec;
ts.tv_nsec = reltime._nsec;
// Don't know, but may be win32 has something better today??
Sleep(static_cast<DWORD>(reltime.toMSecs()));
return true;
+#elif defined __APPLE__
+ // the generic version below behaves badly on Mac; use nanosleep directly,
+ // similar to the POSIX timers version
+ struct timespec ts;
+ ts.tv_sec = reltime._sec;
+ ts.tv_nsec = reltime._nsec;
+
+ for (;;) {
+ struct timespec rem;
+ int ret = nanosleep(&ts, &rem);
+ if (-1 == ret && errno != EINTR)
+ return false;
+ if (ret == 0)
+ break;
+ // Use the remainder for the next cycle.
+ ts = rem;
+ }
+ return true;
#else
SGTimeStamp abstime;
abstime.stamp();