Module Name: src
Committed By: christos
Date: Sun Dec 18 22:30:25 UTC 2011
Modified Files:
src/sys/kern: kern_time.c subr_time.c
src/sys/sys: timevar.h
Log Message:
Fix monotonic interval timers.
To generate a diff of this commit:
cvs rdiff -u -r1.170 -r1.171 src/sys/kern/kern_time.c
cvs rdiff -u -r1.8 -r1.9 src/sys/kern/subr_time.c
cvs rdiff -u -r1.29 -r1.30 src/sys/sys/timevar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/kern_time.c
diff -u src/sys/kern/kern_time.c:1.170 src/sys/kern/kern_time.c:1.171
--- src/sys/kern/kern_time.c:1.170 Thu Oct 27 12:12:52 2011
+++ src/sys/kern/kern_time.c Sun Dec 18 17:30:25 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_time.c,v 1.170 2011/10/27 16:12:52 christos Exp $ */
+/* $NetBSD: kern_time.c,v 1.171 2011/12/18 22:30:25 christos Exp $ */
/*-
* Copyright (c) 2000, 2004, 2005, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.170 2011/10/27 16:12:52 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.171 2011/12/18 22:30:25 christos Exp $");
#include <sys/param.h>
#include <sys/resourcevar.h>
@@ -674,7 +674,10 @@ timer_settime(struct ptimer *pt)
* Don't need to check tshzto() return value, here.
* callout_reset() does it for us.
*/
- callout_reset(&pt->pt_ch, tshzto(&pt->pt_time.it_value),
+ callout_reset(&pt->pt_ch,
+ pt->pt_type == CLOCK_MONOTONIC ?
+ tshztoup(&pt->pt_time.it_value) :
+ tshzto(&pt->pt_time.it_value),
realtimerexpire, pt);
}
} else {
@@ -1004,7 +1007,11 @@ realtimerexpire(void *arg)
return;
}
- getnanotime(&now);
+ if (pt->pt_type == CLOCK_MONOTONIC) {
+ getnanouptime(&now);
+ } else {
+ getnanotime(&now);
+ }
backwards = (timespeccmp(&pt->pt_time.it_value, &now, >));
timespecadd(&pt->pt_time.it_value, &pt->pt_time.it_interval, &next);
/* Handle the easy case of non-overflown timers first. */
@@ -1031,7 +1038,8 @@ realtimerexpire(void *arg)
* Don't need to check tshzto() return value, here.
* callout_reset() does it for us.
*/
- callout_reset(&pt->pt_ch, tshzto(&pt->pt_time.it_value),
+ callout_reset(&pt->pt_ch, pt->pt_type == CLOCK_MONOTONIC ?
+ tshztoup(&pt->pt_time.it_value) : tshzto(&pt->pt_time.it_value),
realtimerexpire, pt);
mutex_spin_exit(&timer_lock);
}
Index: src/sys/kern/subr_time.c
diff -u src/sys/kern/subr_time.c:1.8 src/sys/kern/subr_time.c:1.9
--- src/sys/kern/subr_time.c:1.8 Wed Jan 26 14:15:13 2011
+++ src/sys/kern/subr_time.c Sun Dec 18 17:30:25 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_time.c,v 1.8 2011/01/26 19:15:13 drochner Exp $ */
+/* $NetBSD: subr_time.c,v 1.9 2011/12/18 22:30:25 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.8 2011/01/26 19:15:13 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.9 2011/12/18 22:30:25 christos Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -129,6 +129,18 @@ tshzto(const struct timespec *tsp)
timespecsub(&ts, &now, &ts);
return tstohz(&ts);
}
+
+int
+tshztoup(const struct timespec *tsp)
+{
+ struct timespec now, ts;
+
+ ts = *tsp; /* Don't modify original tsp. */
+ getnanouptime(&now);
+ timespecsub(&ts, &now, &ts);
+ return tstohz(&ts);
+}
+
/*
* Compute number of ticks in the specified amount of time.
*/
Index: src/sys/sys/timevar.h
diff -u src/sys/sys/timevar.h:1.29 src/sys/sys/timevar.h:1.30
--- src/sys/sys/timevar.h:1.29 Thu Apr 8 07:51:13 2010
+++ src/sys/sys/timevar.h Sun Dec 18 17:30:25 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: timevar.h,v 1.29 2010/04/08 11:51:13 njoly Exp $ */
+/* $NetBSD: timevar.h,v 1.30 2011/12/18 22:30:25 christos Exp $ */
/*
* Copyright (c) 2005, 2008 The NetBSD Foundation.
@@ -156,6 +156,7 @@ int dotimer_gettime(int, struct proc *,
int dotimer_settime(int, struct itimerspec *, struct itimerspec *, int,
struct proc *);
int tshzto(const struct timespec *);
+int tshztoup(const struct timespec *);
int tvhzto(const struct timeval *);
void inittimecounter(void);
int itimerfix(struct timeval *);