summaryrefslogtreecommitdiffstats
path: root/games
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2010-02-10 18:20:20 +0000
committerdelphij <delphij@FreeBSD.org>2010-02-10 18:20:20 +0000
commit3e4cd4ab753b1d8760469efccd5719cad85c0ce0 (patch)
tree1a33eced7f53ad58600435ae67886c0c1b264f97 /games
parentd7d58009ce9217fa78d2992173e9c2d544c9ae62 (diff)
downloadFreeBSD-src-3e4cd4ab753b1d8760469efccd5719cad85c0ce0.zip
FreeBSD-src-3e4cd4ab753b1d8760469efccd5719cad85c0ce0.tar.gz
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
Diffstat (limited to 'games')
-rw-r--r--games/grdc/grdc.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/games/grdc/grdc.c b/games/grdc/grdc.c
index d27b10e..c467b53 100644
--- a/games/grdc/grdc.c
+++ b/games/grdc/grdc.c
@@ -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();
OpenPOWER on IntegriCloud