/*! A more reliable high precision sleep \param amt amount to sleep \param units units that sleep value is in \return 0 on success */ inline int hypersleep (unsigned amt, hyperunits_t units) { enum { Div, Mul, Operation }; static const unsigned hv[h_count][Operation] { { 1, billion }, // Seconds { thousand, million }, // Milliseconds { million, thousand }, // Microseconds { billion, 1 }, // Nanoseconds }; #if defined FIX8_HAVE_CLOCK_NANOSLEEP timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); ts.tv_sec += (amt / hv[units][Div]); // calculate time to sleep in secs ts.tv_nsec += (hv[units][Mul] * (amt % hv[units][Div])); // calculate time to sleep in nsecs return execute_clock_nanosleep(ts); #elif defined _MSC_VER Sleep(amt); // milliseconds return 0; #else const timespec tspec { amt / hv[units][Div], hv[units][Mul] * (amt % hv[units][Div]) }; return nanosleep(&tspec, 0); #endif }
inline int hypersleep<h_seconds>(unsigned amt) { #if defined FIX8_HAVE_CLOCK_NANOSLEEP timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); ts.tv_sec += amt; ts.tv_nsec += (amt % (billion)); return execute_clock_nanosleep(ts); #elif defined _MSC_VER Sleep(amt * thousand); return 0; #else const timespec tspec { amt, amt % billion }; return nanosleep(&tspec, 0); #endif }
inline int hypersleep<h_microseconds>(unsigned amt) { #if defined HAVE_CLOCK_NANOSLEEP timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); ts.tv_sec += (amt / million); ts.tv_nsec += (thousand * (amt % million)); return execute_clock_nanosleep(ts); #elif defined _MSC_VER Sleep(amt / million * thousand); return 0; #else const timespec tspec { amt / million, thousand * (amt % million) }; return nanosleep(&tspec, 0); #endif }