On 06/09/07 21:40, Petri Hintukainen wrote: > On Sat, 2007-06-09 at 12:28 +0200, Udo Richter wrote: >> And, from the original post: >>> May 31 20:23:38 localhost vdr: [3413] System Time = Thu May 31 20:23:38 2007 (1180632218) >>> May 31 20:23:38 localhost vdr: [3413] Local Time = Thu May 31 20:19:37 2007 (1180631977) >>> May 31 20:21:01 localhost vdr: [3405] PANIC: watchdog timer expired - exiting! > > Turning clock is always very bad and dangerous thing to do. It can cause > lot of other problems too, just to mention incomplete builds, duplicate > cron jobs, destroyed logs and files, incomplete backups ... > >> The clock was set to 20:19:37, and the watchdog fires at 20:21:01 - 84 >> seconds later. There must be something different causing the watchdog to >> expire. > > It might be even some plugin. All timeouts (cTimeMs, cCondVar, > cCondWait) use current wall clock time to set the timeout. > Example: > cCondWait c; > c.Wait(100); > > If clock is turned 2 minutes back in middle of this, the code will wait > 120100 ms instead of 100ms ... Might cause some quite weird problems. > I belive there's no way to change pthread_..._timedwait functions, but > cTimeMs can be changed to use monotonic timers instead of gettimeofday > (patch attached). > ... I have (finally, sorry for the big delay) adopted this patch (in the attached form) to fix a problem with SVDRP connections when the system time is adjusted. While testing this, I found that on my system the monotonic clock only has a resolution of 4000250 ns (about 4 ms), which in your original patch would have caused VDR not to use the monotonic clock. Are there actually systems that have a 1 ms resolution? Or is there some parameter that needs to be adjusted to get a better resolution? Maybe we should set the limit to, say, 10 ms, so that systems like mine can also benefit from this. After all, the advantage of having a monotonous clock outweighs the courser resolution (typically such timeouts are not below 10 ms). Klaus
--- Makefile 2007/11/04 10:15:59 1.110 +++ Makefile 2007/12/02 11:29:22 @@ -20,7 +20,7 @@ MANDIR = $(PREFIX)/share/man BINDIR = $(PREFIX)/bin LOCDIR = ./locale -LIBS = -ljpeg -lpthread -ldl -lcap -lfreetype -lfontconfig +LIBS = -ljpeg -lpthread -ldl -lcap -lrt -lfreetype -lfontconfig INCLUDES = -I/usr/include/freetype2 PLUGINDIR= ./PLUGINS --- tools.c 2007/11/03 15:34:07 1.137 +++ tools.c 2007/12/02 11:52:31 @@ -545,6 +545,40 @@ uint64_t cTimeMs::Now(void) { +#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) + 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 at least 10 ms resolution: + if (tp.tv_sec == 0 && tp.tv_nsec <= 10000000) { + if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) { + dsyslog("cTimeMs: using monotonic clock (resolution is %ld ns)", Resolution); + monotonic = true; + } + else + esyslog("cTimeMs: clock_gettime(CLOCL_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;
_______________________________________________ vdr mailing list vdr@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr