Do not roll a custom for-loop, use the appropriate TAILQ function. Also use unsleep() instead of coding the same functionality here again. There is only one place in the system that resets p_wchan now. And the unsleep-part has the same pattern like in endtsleep(). --- sys/kern/kern_synch.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 684624428db..154686e924b 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -436,15 +436,13 @@ unsleep(struct proc *p) void wakeup_n(const volatile void *ident, int n) { - struct slpque *qp; struct proc *p; - struct proc *pnext; int s; SCHED_LOCK(s); - qp = &slpque[LOOKUP(ident)]; - for (p = TAILQ_FIRST(qp); p != NULL && n != 0; p = pnext) { - pnext = TAILQ_NEXT(p, p_runq); + TAILQ_FOREACH(p, &slpque[LOOKUP(ident)], p_runq) { + if (n == 0) + break; #ifdef DIAGNOSTIC /* * If the rwlock passed to rwsleep() is contended, the @@ -460,10 +458,10 @@ wakeup_n(const volatile void *ident, int n) #endif if (p->p_wchan == ident) { --n; - p->p_wchan = 0; - TAILQ_REMOVE(qp, p, p_runq); if (p->p_stat == SSLEEP) setrunnable(p); + else + unsleep(p); } } SCHED_UNLOCK(s); -- 2.19.0