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 @@
#define PS_SWAPPING 0x00200 /* Process is being swapped. */
#define PS_ASTPENDING 0x00400 /* Process has a pending ast. */
#define PS_NEEDRESCHED 0x00800 /* Process needs to yield. */
+#define PS_TIMOFAIL 0x01000 /* Timeout from sleep after we were
awake. */
#define P_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