From owner-freebsd-bugs@FreeBSD.ORG Tue Mar 8 12:40:09 2011 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C5E951065672 for ; Tue, 8 Mar 2011 12:40:09 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 8B3F68FC0A for ; Tue, 8 Mar 2011 12:40:09 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id p28Ce9gE000239 for ; Tue, 8 Mar 2011 12:40:09 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id p28Ce9Ds000238; Tue, 8 Mar 2011 12:40:09 GMT (envelope-from gnats) Resent-Date: Tue, 8 Mar 2011 12:40:09 GMT Resent-Message-Id: <201103081240.p28Ce9Ds000238@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Andy Farkas Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5B3DF1065678 for ; Tue, 8 Mar 2011 12:36:47 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22]) by mx1.freebsd.org (Postfix) with ESMTP id 3FB048FC1C for ; Tue, 8 Mar 2011 12:36:47 +0000 (UTC) Received: from red.freebsd.org (localhost [127.0.0.1]) by red.freebsd.org (8.14.4/8.14.4) with ESMTP id p28Cal7U092510 for ; Tue, 8 Mar 2011 12:36:47 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.4/8.14.4/Submit) id p28Cakfi092509; Tue, 8 Mar 2011 12:36:46 GMT (envelope-from nobody) Message-Id: <201103081236.p28Cakfi092509@red.freebsd.org> Date: Tue, 8 Mar 2011 12:36:46 GMT From: Andy Farkas To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: bin/155374: [patch] grdc(6) timing loop still broken X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Mar 2011 12:40:09 -0000 >Number: 155374 >Category: bin >Synopsis: [patch] grdc(6) timing loop still broken >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Mar 08 12:40:09 UTC 2011 >Closed-Date: >Last-Modified: >Originator: Andy Farkas >Release: 8.2-STABLE >Organization: >Environment: FreeBSD 8.2-STABLE #0: Mon Mar 7 07:46:31 EST 2011 >Description: After adding a small delay loop to the scrolling code of grdc(6) I noticed that it was not keeping time properly. This patch adds a delay during scrolling so that you can actually see it, and also corrects the timing calculations within the do() loop. The scrolling bit is trivial, see my followup to bin/151663. The main thrust of this patch is to finally fix the timing of the do() loop: 1/ at the start of the loop we get the current time (now). 2/ we diplay the time, which may take some time, especially if scrolling. 3/ after display we get the time again (delay). 4/ we then calculate the amount of time needed to wait until a whole second has passed (wait). >How-To-Repeat: Add a delay during scrolling and notice how the time is displayed wrong. >Fix: patch (including scrolling patch): %%% --- /usr/src/games/grdc/grdc.c 2010-08-28 13:04:04.000000000 +1000 +++ ./grdc.c 2011-03-08 22:04:00.000000000 +1000 @@ -26,7 +26,12 @@ #define XLENGTH 58 #define YDEPTH 7 -struct timespec now; +/* now: current time we start the loop + delay: current time we finish displaying the time + wait: amount of time we wait until next now second + scrold: amount of time between scrolling +*/ +struct timespec delay, now, wait, scrold; struct tm *tm; short disp[11] = { @@ -54,8 +59,6 @@ int main(int argc, char *argv[]) { - struct timespec delay; - time_t prev_sec; long t, a; int i, j, s, k; int n; @@ -69,6 +72,7 @@ switch (ch) { case 's': scrol = 1; + scrold.tv_nsec = 40000000; break; case 't': t12 = 1; @@ -138,9 +142,9 @@ attrset(COLOR_PAIR(2)); } - clock_gettime(CLOCK_REALTIME_FAST, &now); - prev_sec = now.tv_sec; + do { + clock_gettime(CLOCK_REALTIME_FAST, &now); mask = 0; tm = localtime(&now.tv_sec); set(tm->tm_sec%10, 0); @@ -191,25 +195,31 @@ } if(!s) { refresh(); + nanosleep(&scrold, NULL); } } } movto(6, 0); refresh(); - clock_gettime(CLOCK_REALTIME_FAST, &now); - if (now.tv_sec == prev_sec) { - if (delay.tv_nsec > 0) { - delay.tv_sec = 0; - delay.tv_nsec = 1000000000 - now.tv_nsec; - } else { - delay.tv_sec = 1; - delay.tv_nsec = 0; + + clock_gettime(CLOCK_REALTIME_FAST, &delay); + + if (delay.tv_sec == now.tv_sec) { + wait.tv_nsec = 1000000000 - (delay.tv_nsec - now.tv_nsec); + --n; + } + else { + if (delay.tv_nsec < now.tv_nsec) { + wait.tv_nsec = now.tv_nsec - delay.tv_nsec; + n -= delay.tv_sec - now.tv_sec; + } + else { + wait.tv_nsec = (1000000000 - delay.tv_nsec) + now.tv_nsec; + n -= (delay.tv_sec - now.tv_sec) + 1; } - nanosleep(&delay, NULL); - clock_gettime(CLOCK_REALTIME_FAST, &now); } - n -= now.tv_sec - prev_sec; - prev_sec = now.tv_sec; + nanosleep(&wait, NULL); + if (sigtermed) { standend(); clear(); >Release-Note: >Audit-Trail: >Unformatted: