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 *);