aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMatthew Dillon <dillon@FreeBSD.org>2002-06-24 00:14:36 +0000
committerMatthew Dillon <dillon@FreeBSD.org>2002-06-24 00:14:36 +0000
commit727300861d57d2cc710a090995dca89ea0b3fb4d (patch)
treed5a247cdba17dc7bf210233b286636c14c87a2bb /sys
parent99cfc2e2b28a224e5c1e3bafc64c8d5075881598 (diff)
downloadsrc-727300861d57d2cc710a090995dca89ea0b3fb4d.tar.gz
src-727300861d57d2cc710a090995dca89ea0b3fb4d.zip
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
Notes
Notes: svn path=/head/; revision=98714
Diffstat (limited to 'sys')
-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 9d959d22b706..6f9adaddc4db 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;
}
}
}