From patchwork Sun Dec 2 12:08:11 2007 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Klaus Schmidinger X-Patchwork-Id: 12553 Received: from raven.cadsoft.de ([217.7.101.211]) by www.linuxtv.org with esmtp (Exim 4.63) (envelope-from ) id 1IyncL-0005vl-Ik for vdr@linuxtv.org; Sun, 02 Dec 2007 13:08:13 +0100 Received: from [192.168.100.10] (hawk.cadsoft.de [192.168.100.10]) by raven.cadsoft.de (8.13.3/8.13.3) with ESMTP id lB2C8C2p018530 for ; Sun, 2 Dec 2007 13:08:12 +0100 Message-ID: <4752A02B.60504@cadsoft.de> Date: Sun, 02 Dec 2007 13:08:11 +0100 From: Klaus Schmidinger Organization: CadSoft Computer GmbH User-Agent: Thunderbird 1.5.0.12 (X11/20060911) MIME-Version: 1.0 To: vdr@linuxtv.org References: <466A80E5.40502@gmx.de> <1181418045.7288.143.camel@core> In-Reply-To: <1181418045.7288.143.camel@core> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.0 (raven.cadsoft.de [192.168.1.1]); Sun, 02 Dec 2007 13:08:12 +0100 (CET) Subject: Re: [vdr] PANIC: watchdog timer expired - exiting X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.9 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 02 Dec 2007 12:08:13 -0000 Status: O X-Status: X-Keywords: X-UID: 14775 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;