summaryrefslogtreecommitdiff
path: root/tools.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools.c')
-rw-r--r--tools.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/tools.c b/tools.c
index ba7b0cf9..2f8e0789 100644
--- a/tools.c
+++ b/tools.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: tools.c 1.137 2007/11/03 15:34:07 kls Exp $
+ * $Id: tools.c 1.138 2007/12/27 15:57:49 kls Exp $
*/
#include "tools.h"
@@ -545,6 +545,41 @@ cTimeMs::cTimeMs(int Ms)
uint64_t cTimeMs::Now(void)
{
+#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
+#define MIN_RESOLUTION 5 // ms
+ static bool initialized = false;
+ static bool monotonic = false;
+ struct timespec tp;
+ if (!initialized) {
+ // check if monotonic timer is available and provides enough accurate resolution:
+ if (clock_getres(CLOCK_MONOTONIC, &tp) == 0) {
+ long Resolution = tp.tv_nsec;
+ // require a minimum resolution:
+ if (tp.tv_sec == 0 && tp.tv_nsec <= MIN_RESOLUTION * 1000000) {
+ if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
+ dsyslog("cTimeMs: using monotonic clock (resolution is %ld ns)", Resolution);
+ monotonic = true;
+ }
+ else
+ esyslog("cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
+ }
+ else
+ dsyslog("cTimeMs: not using monotonic clock - resolution is too bad (%ld s %ld ns)", tp.tv_sec, tp.tv_nsec);
+ }
+ else
+ esyslog("cTimeMs: clock_getres(CLOCK_MONOTONIC) failed");
+ initialized = true;
+ }
+ if (monotonic) {
+ if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
+ return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000;
+ esyslog("cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
+ monotonic = false;
+ // fall back to gettimeofday()
+ }
+#else
+# warning Posix monotonic clock not available
+#endif
struct timeval t;
if (gettimeofday(&t, NULL) == 0)
return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000;