From owner-svn-src-all@FreeBSD.ORG Wed Feb 10 18:20:20 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D56A31065670; Wed, 10 Feb 2010 18:20:20 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C4C028FC0A; Wed, 10 Feb 2010 18:20:20 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o1AIKKvW071568; Wed, 10 Feb 2010 18:20:20 GMT (envelope-from delphij@svn.freebsd.org) Received: (from delphij@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o1AIKKeR071566; Wed, 10 Feb 2010 18:20:20 GMT (envelope-from delphij@svn.freebsd.org) Message-Id: <201002101820.o1AIKKeR071566@svn.freebsd.org> From: Xin LI Date: Wed, 10 Feb 2010 18:20:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r203760 - head/games/grdc X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Feb 2010 18:20:20 -0000 Author: delphij Date: Wed Feb 10 18:20:20 2010 New Revision: 203760 URL: http://svn.freebsd.org/changeset/base/203760 Log: Improve time precision for grdc(6): Traditionally, grdc would obtain time through time(3) which in turn gets only the second part of clock (CLOCK_SECOND), and sleep for 1 second after each screen refresh. This approach would have two problems. First, we are not guaranteed to be waken up at the beginning of a whole second, which will typically exhibit as a "lag" on second number. Second, because we sleep for whole second, and the refresh process would take some time, the error would accumulate from time to time, making the lag variable. Make grdc(6) to use time(3) to get time only at the beginning, and sample time in CLOCK_REALTIME_FAST granularity after refreshing, and use the nanosecond part to caculate how much time we want to sleep. PR: bin/120813 MFC after: 1 month Modified: head/games/grdc/grdc.c Modified: head/games/grdc/grdc.c ============================================================================== --- head/games/grdc/grdc.c Wed Feb 10 17:02:06 2010 (r203759) +++ head/games/grdc/grdc.c Wed Feb 10 18:20:20 2010 (r203760) @@ -59,6 +59,7 @@ main(argc, argv) int argc; char **argv; { +struct timespec ts; long t, a; int i, j, s, k; int n; @@ -136,9 +137,9 @@ int t12; attrset(COLOR_PAIR(2)); } + time(&now); do { mask = 0; - time(&now); tm = localtime(&now); set(tm->tm_sec%10, 0); set(tm->tm_sec/10, 4); @@ -193,7 +194,19 @@ int t12; } movto(6, 0); refresh(); - sleep(1); + clock_gettime(CLOCK_REALTIME_FAST, &ts); + if (ts.tv_sec == now) { + if (ts.tv_nsec > 0) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000000 - ts.tv_nsec; + } else { + ts.tv_sec = 1; + ts.tv_nsec = 0; + } + nanosleep(&ts, NULL); + now = ts.tv_sec + 1; + } else + now = ts.tv_sec; if (sigtermed) { standend(); clear();