summaryrefslogtreecommitdiff
path: root/lib/common/BoxTime.cpp
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2011-01-12 00:09:16 +0000
committerChris Wilson <chris+github@qwirx.com>2011-01-12 00:09:16 +0000
commitff316251a1b9f169dcb39227c0229c709f3be77d (patch)
tree7a8f81d803a89b2f83343e8a924617785589eb33 /lib/common/BoxTime.cpp
parentac658b0659c90ef72e937d5fb104d3e52f9aa634 (diff)
Move accurate sleep code from Test.cpp to BoxTime, allow requesting times
in microseconds with ShortSleep(), make safe_sleep() use it. Rename MILLI_SEC_IN_NANO_SEC to MILLI_SEC_IN_SEC which is what it actually is.
Diffstat (limited to 'lib/common/BoxTime.cpp')
-rw-r--r--lib/common/BoxTime.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/common/BoxTime.cpp b/lib/common/BoxTime.cpp
index d05c0a6c..298c3910 100644
--- a/lib/common/BoxTime.cpp
+++ b/lib/common/BoxTime.cpp
@@ -94,3 +94,53 @@ std::string FormatTime(box_time_t time, bool includeDate, bool showMicros)
return buf.str();
}
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: ShortSleep(box_time_t duration)
+// Purpose: Sleeps for the specified duration as accurately
+// and efficiently as possible.
+// Created: 2011/01/11
+//
+// --------------------------------------------------------------------------
+
+void ShortSleep(box_time_t duration, bool logDuration)
+{
+ if(logDuration)
+ {
+ BOX_TRACE("Sleeping for " << BoxTimeToMicroSeconds(duration) <<
+ " microseconds");
+ }
+
+#ifdef WIN32
+ Sleep(BoxTimeToMilliSeconds(duration));
+#else
+ struct timespec ts;
+ memset(&ts, 0, sizeof(ts));
+ ts.tv_sec = duration / MICRO_SEC_IN_SEC;
+ ts.tv_nsec = duration % MICRO_SEC_IN_SEC;
+
+ while (nanosleep(&ts, &ts) == -1 && errno == EINTR)
+ {
+ // FIXME evil hack for OSX, where ts.tv_sec contains
+ // a negative number interpreted as unsigned 32-bit
+ // when nanosleep() returns later than expected.
+
+ int32_t secs = (int32_t) ts.tv_sec;
+ int64_t remain_ns = (secs * 1000000000) + ts.tv_nsec;
+
+ if (remain_ns < 0)
+ {
+ BOX_WARNING("nanosleep interrupted " <<
+ ((float)(0 - remain_ns) / 1000000000) <<
+ " secs late");
+ return;
+ }
+
+ BOX_TRACE("nanosleep interrupted with " <<
+ (remain_ns / 1000000000) << " secs remaining, "
+ "sleeping again");
+ }
+#endif
+}
+