Do not roll our own for-loop, use the proper TAILQ function.
Also use unsleep() instead of unrolling the same functionality here again.
Now there is only one place that resets p_wchan. And the unsleep-part has
the same pattern like in endtsleep().
---
v2:
- TAILQ_FOREACH -> TAILQ_FOREACH_SAFE, since TAILQ_REMOVE might be
called. Silly me.
sys/kern/kern_synch.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 684624428db..a1689765ff9 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -436,15 +436,14 @@ 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_SAFE(p, &slpque[LOOKUP(ident)], p_runq, pnext) {
+ if (n == 0)
+ break;
#ifdef DIAGNOSTIC
/*
* If the rwlock passed to rwsleep() is contended, the
@@ -460,10 +459,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.1