summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_synch.c
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2002-06-24 00:14:36 +0000
committerdillon <dillon@FreeBSD.org>2002-06-24 00:14:36 +0000
commit3bb3ab3df2a24c65f5cdcedab4393b47234c4e79 (patch)
treed5a247cdba17dc7bf210233b286636c14c87a2bb /sys/kern/kern_synch.c
parent20a617c09d0233b4529f659b62dce87d38204593 (diff)
downloadFreeBSD-src-3bb3ab3df2a24c65f5cdcedab4393b47234c4e79.zip
FreeBSD-src-3bb3ab3df2a24c65f5cdcedab4393b47234c4e79.tar.gz
I Noticed a defect in the way wakeup() scans the tailq. Tor noticed an
even worse defect in wakeup_one(). This patch cleans up both. Submitted by: tegge MFC after: 3 days
Diffstat (limited to 'sys/kern/kern_synch.c')
-rw-r--r--sys/kern/kern_synch.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 9d959d2..6f9adad 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -606,12 +606,14 @@ wakeup(ident)
{
register struct slpquehead *qp;
register struct thread *td;
+ struct thread *ntd;
struct proc *p;
mtx_lock_spin(&sched_lock);
qp = &slpque[LOOKUP(ident)];
restart:
- TAILQ_FOREACH(td, qp, td_slpq) {
+ for (td = TAILQ_FIRST(qp); td != NULL; td = ntd) {
+ ntd = TAILQ_NEXT(td, td_slpq);
p = td->td_proc;
if (td->td_wchan == ident) {
TAILQ_REMOVE(qp, td, td_slpq);
@@ -652,11 +654,13 @@ wakeup_one(ident)
register struct slpquehead *qp;
register struct thread *td;
register struct proc *p;
+ struct thread *ntd;
mtx_lock_spin(&sched_lock);
qp = &slpque[LOOKUP(ident)];
-
- TAILQ_FOREACH(td, qp, td_slpq) {
+restart:
+ for (td = TAILQ_FIRST(qp); td != NULL; td = ntd) {
+ ntd = TAILQ_NEXT(td, td_slpq);
p = td->td_proc;
if (td->td_wchan == ident) {
TAILQ_REMOVE(qp, td, td_slpq);
@@ -679,6 +683,7 @@ wakeup_one(ident)
wakeup((caddr_t)&proc0);
}
/* END INLINE EXPANSION */
+ goto restart;
}
}
}
OpenPOWER on IntegriCloud