Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Change the contract for timer_settime() (the intern...
details: https://anonhg.NetBSD.org/src/rev/d3e7b75c41eb
branches: trunk
changeset: 544082:d3e7b75c41eb
user: nathanw <nathanw%NetBSD.org@localhost>
date: Mon Mar 10 21:49:56 2003 +0000
description:
Change the contract for timer_settime() (the internal routine, not the
syscall sys_timer_settime()) to take an absolute value for realtime
timers. This avoids a pair of gratiuitous conversions with the
possibility that the timer's intermediate value would be 0.0, which
would signal timer_settime() to cancel the timer.
Adjust callers of timer_settime() to compensate; catch the case where
sys_timer_settime() with an absolute time value of now and a virtual
timer would also be subtracted down to a timer-cancelling 0.0.
This should fix the bug seen in libpthread's nanosleep() where certain
applications, such as xmms, would wedge with unexpired userlevel
alarms.
diffstat:
sys/kern/kern_time.c | 45 ++++++++++++++++++++++++++++++++++-----------
1 files changed, 34 insertions(+), 11 deletions(-)
diffs (87 lines):
diff -r 726a8f7765d5 -r d3e7b75c41eb sys/kern/kern_time.c
--- a/sys/kern/kern_time.c Mon Mar 10 21:21:10 2003 +0000
+++ b/sys/kern/kern_time.c Mon Mar 10 21:49:56 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_time.c,v 1.66 2003/02/04 15:50:06 jdolecek Exp $ */
+/* $NetBSD: kern_time.c,v 1.67 2003/03/10 21:49:56 nathanw Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.66 2003/02/04 15:50:06 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.67 2003/03/10 21:49:56 nathanw Exp $");
#include "fs_nfs.h"
#include "opt_nfs.h"
@@ -630,8 +630,9 @@
}
/*
- * Set up the given timer. The value in pt->pt_time.it_value is taken to be
- * relative to now.
+ * Set up the given timer. The value in pt->pt_time.it_value is taken
+ * to be an absolute time for CLOCK_REALTIME timers and a relative
+ * time for virtual timers.
* Must be called at splclock().
*/
void
@@ -643,8 +644,6 @@
if (pt->pt_type == CLOCK_REALTIME) {
callout_stop(&pt->pt_ch);
if (timerisset(&pt->pt_time.it_value)) {
- timeradd(&pt->pt_time.it_value, &time,
- &pt->pt_time.it_value);
/*
* Don't need to check hzto() return value, here.
* callout_reset() does it for us.
@@ -763,11 +762,31 @@
pt->pt_time = val;
s = splclock();
- /* If we've been passed an absolute time, convert it to relative. */
- if (timerisset(&pt->pt_time.it_value) &&
- (SCARG(uap, flags) & TIMER_ABSTIME))
- timersub(&pt->pt_time.it_value, &time,
- &pt->pt_time.it_value);
+ /*
+ * If we've been passed a relative time for a realtime timer,
+ * convert it to absolute; if an absolute time for a virtual
+ * timer, convert it to relative and make sure we don't set it
+ * to zero, which would cancel the timer, or let it go
+ * negative, which would confuse the comparison tests.
+ */
+ if (timerisset(&pt->pt_time.it_value)) {
+ if (pt->pt_type == CLOCK_REALTIME) {
+ if ((SCARG(uap, flags) & TIMER_ABSTIME) == 0)
+ timeradd(&pt->pt_time.it_value, &time,
+ &pt->pt_time.it_value);
+ } else {
+ if ((SCARG(uap, flags) & TIMER_ABSTIME) != 0) {
+ timersub(&pt->pt_time.it_value, &time,
+ &pt->pt_time.it_value);
+ if (!timerisset(&pt->pt_time.it_value) ||
+ pt->pt_time.it_value.tv_sec < 0) {
+ pt->pt_time.it_value.tv_sec = 0;
+ pt->pt_time.it_value.tv_usec = 1;
+ }
+ }
+ }
+ }
+
timer_settime(pt);
splx(s);
@@ -1009,6 +1028,10 @@
p->p_timers->pts_timers[which] = pt;
s = splclock();
+ if ((which == ITIMER_REAL) && timerisset(&pt->pt_time.it_value)) {
+ /* Convert to absolute time */
+ timeradd(&pt->pt_time.it_value, &time, &pt->pt_time.it_value);
+ }
timer_settime(pt);
splx(s);
Home |
Main Index |
Thread Index |
Old Index