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

Reply via email to