diff options
author | Matthew Dillon <dillon@FreeBSD.org> | 2002-06-24 00:14:36 +0000 |
---|---|---|
committer | Matthew Dillon <dillon@FreeBSD.org> | 2002-06-24 00:14:36 +0000 |
commit | 727300861d57d2cc710a090995dca89ea0b3fb4d (patch) | |
tree | d5a247cdba17dc7bf210233b286636c14c87a2bb /sys | |
parent | 99cfc2e2b28a224e5c1e3bafc64c8d5075881598 (diff) | |
download | src-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.c | 11 |
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; } } } |