svn commit: r211230 - head/sys/kern
    Jung-uk Kim 
    jkim at FreeBSD.org
       
    Thu Aug 12 17:17:05 UTC 2010
    
    
  
Author: jkim
Date: Thu Aug 12 17:17:05 2010
New Revision: 211230
URL: http://svn.freebsd.org/changeset/base/211230
Log:
  Add the half of time-of-day clock resolution when we adjust system time from
  time-of-day clock or vice versa.  For x86 systems, RTC resolution is one
  second and we used to lose up to one second whenever we initialize system
  time from RTC or write system time back to RTC.  With this change, margin
  of error per conversion is roughly between -0.5 and +0.5 second rather
  than between -1 and 0 second.  Note that it does not take care of errors
  from getnanotime(9) (which is up to 1/hz second) or CLOCK_GETTIME() latency.
  These are just too expensive to correct and it is not worthy of the cost.
Modified:
  head/sys/kern/subr_rtc.c
Modified: head/sys/kern/subr_rtc.c
==============================================================================
--- head/sys/kern/subr_rtc.c	Thu Aug 12 16:54:43 2010	(r211229)
+++ head/sys/kern/subr_rtc.c	Thu Aug 12 17:17:05 2010	(r211230)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 
 static device_t clock_dev = NULL;
 static long clock_res;
+static struct timespec clock_adj;
 
 /* XXX: should be kern. now, it's no longer machdep.  */
 static int disable_rtc_set;
@@ -87,9 +88,12 @@ clock_register(device_t dev, long res)	/
 	}
 	clock_dev = dev;
 	clock_res = res;
+	clock_adj.tv_sec = res / 2 / 1000000;
+	clock_adj.tv_nsec = res / 2 % 1000000 * 1000;
 	if (bootverbose)
 		device_printf(dev, "registered as a time-of-day clock "
-		    "(resolution %ldus)\n", res);
+		    "(resolution %ldus, adjustment %jd.%09jds)\n", res,
+		    (intmax_t)clock_adj.tv_sec, (intmax_t)clock_adj.tv_nsec);
 }
 
 /*
@@ -127,6 +131,7 @@ inittodr(time_t base)
 	}
 
 	ts.tv_sec += utc_offset();
+	timespecadd(&ts, &clock_adj);
 	tc_setclock(&ts);
 	return;
 
@@ -151,6 +156,7 @@ resettodr(void)
 		return;
 
 	getnanotime(&ts);
+	timespecadd(&ts, &clock_adj);
 	ts.tv_sec -= utc_offset();
 	/* XXX: We should really set all registered RTCs */
 	if ((error = CLOCK_SETTIME(clock_dev, &ts)) != 0)
    
    
More information about the svn-src-head
mailing list