There is a bug in the msleep/endtsleep race workaround. Please test the patch
at http://www.FreeBSD.org/~jhb/patches/timeout.patch
Index: kern/kern_condvar.c
===
RCS file: /usr/cvs/src/sys/kern/kern_condvar.c,v
retrieving revision 1.11
diff -u -r1.11 kern_condvar.c
--- kern/kern_condvar.c 2001/07/06 01:16:42 1.11
+++ kern/kern_condvar.c 2001/08/21 17:57:08
@@ -345,8 +345,17 @@
if (p-p_sflag PS_TIMEOUT) {
p-p_sflag = ~PS_TIMEOUT;
rval = EWOULDBLOCK;
- } else
- callout_stop(p-p_slpcallout);
+ } else if (p-p_sflag PS_TIMOFAIL)
+ p-p_sflag = ~PS_TIMOFAIL;
+ } else if (callout_stop(p-p_slpcallout) == 0) {
+ /*
+* Work around race with cv_timedwait_end similar to that
+* between msleep and endtsleep.
+*/
+ p-p_sflag |= PS_TIMEOUT;
+ p-p_stats-p_ru.ru_nivcsw++;
+ mi_switch();
+ }
mtx_unlock_spin(sched_lock);
#ifdef KTRACE
@@ -407,8 +416,17 @@
if (p-p_sflag PS_TIMEOUT) {
p-p_sflag = ~PS_TIMEOUT;
rval = EWOULDBLOCK;
- } else
- callout_stop(p-p_slpcallout);
+ } else if (p-p_sflag PS_TIMOFAIL)
+ p-p_sflag = ~PS_TIMOFAIL;
+ } else if (callout_stop(p-p_slpcallout) == 0) {
+ /*
+* Work around race with cv_timedwait_end similar to that
+* between msleep and endtsleep.
+*/
+ p-p_sflag |= PS_TIMEOUT;
+ p-p_stats-p_ru.ru_nivcsw++;
+ mi_switch();
+ }
mtx_unlock_spin(sched_lock);
PICKUP_GIANT();
@@ -538,12 +556,16 @@
CTR3(KTR_PROC, cv_timedwait_end: proc %p (pid %d, %s), p, p-p_pid,
p-p_comm);
mtx_lock_spin(sched_lock);
- if (p-p_wchan != NULL) {
+ if (p-p_sflag PS_TIMEOUT) {
+ p-p_sflag = ~PS_TIMEOUT;
+ setrunqueue(p);
+ } else if (p-p_wchan != NULL) {
if (p-p_stat == SSLEEP)
setrunnable(p);
else
cv_waitq_remove(p);
p-p_sflag |= PS_TIMEOUT;
- }
+ } else
+ p-p_sflag |= PS_TIMOFAIL;
mtx_unlock_spin(sched_lock);
}
Index: kern/kern_synch.c
===
RCS file: /usr/cvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.155
diff -u -r1.155 kern_synch.c
--- kern/kern_synch.c 2001/08/10 22:53:28 1.155
+++ kern/kern_synch.c 2001/08/21 17:57:08
@@ -451,6 +455,8 @@
p-p_sflag = ~PS_TIMEOUT;
if (sig == 0)
rval = EWOULDBLOCK;
+ } else if (p-p_sflag PS_TIMOFAIL)
+ p-p_sflag = ~PS_TIMOFAIL;
} else if (timo callout_stop(p-p_slpcallout) == 0) {
/*
* This isn't supposed to be pretty. If we are here, then
@@ -524,7 +530,8 @@
else
unsleep(p);
p-p_sflag |= PS_TIMEOUT;
- }
+ } else
+ p-p_sflag |= PS_TIMOFAIL;
mtx_unlock_spin(sched_lock);
}
Index: sys/proc.h
===
RCS file: /usr/cvs/src/sys/sys/proc.h,v
retrieving revision 1.174
diff -u -r1.174 proc.h
--- sys/proc.h 2001/08/10 22:53:32 1.174
+++ sys/proc.h 2001/08/21 17:57:08
@@ -321,6 +321,7 @@
#definePS_SWAPPING 0x00200 /* Process is being swapped. */
#definePS_ASTPENDING 0x00400 /* Process has a pending ast. */
#definePS_NEEDRESCHED 0x00800 /* Process needs to yield. */
+#definePS_TIMOFAIL 0x01000 /* Timeout from sleep after we were
awake. */
#defineP_MAGIC 0xbeefface
--
John Baldwin [EMAIL PROTECTED] -- http://www.FreeBSD.org/~jhb/
PGP Key: http://www.baldwin.cx/~john/pgpkey.asc
Power Users Use the Power to Serve! - http://www.FreeBSD.org/
To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message