Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Mar 2010 00:51:25 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r205057 - stable/7/games/grdc
Message-ID:  <201003120051.o2C0pP1W040809@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Fri Mar 12 00:51:25 2010
New Revision: 205057
URL: http://svn.freebsd.org/changeset/base/205057

Log:
  MFC r203760: 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

Modified:
  stable/7/games/grdc/grdc.c
Directory Properties:
  stable/7/games/grdc/   (props changed)

Modified: stable/7/games/grdc/grdc.c
==============================================================================
--- stable/7/games/grdc/grdc.c	Fri Mar 12 00:51:13 2010	(r205056)
+++ stable/7/games/grdc/grdc.c	Fri Mar 12 00:51:25 2010	(r205057)
@@ -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();



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003120051.o2C0pP1W040809>