From 079fb286c5d9bd1334cf74eb31f3467ccdd4fba7 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 26 Apr 2009 19:44:34 +0200 Subject: [PATCH] Fix lwp_rwlock_unlock() to wake up all readers It woke up just one. Bug couldn't bite, because the update never sleeps, and therefore no reader gets a chance to sleep. --- src/lib/lwp/rwlock.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/lib/lwp/rwlock.c b/src/lib/lwp/rwlock.c index aa0fa4fe..38c099bd 100644 --- a/src/lib/lwp/rwlock.c +++ b/src/lib/lwp/rwlock.c @@ -109,6 +109,7 @@ void lwp_rwlock_unlock(struct lwp_rwlock *rwlock) { struct lwpProc *p; + int maxpri; lwpStatus(LwpCurrent, "unlocking rwlock %s", rwlock->name); if (CANT_HAPPEN(rwlock->count == 0)) @@ -121,14 +122,19 @@ lwp_rwlock_unlock(struct lwp_rwlock *rwlock) if (rwlock->count == 0 && rwlock->wq.head) { p = lwpGetFirst(&rwlock->wq); lwpStatus(p, "wake up next writer of rwlock %s", rwlock->name); + maxpri = p->pri; + lwpReady(p); } else if (rwlock->count >= 0 && rwlock->rq.head && !rwlock->wq.head) { - p = lwpGetFirst(&rwlock->rq); - lwpStatus(p, "wake up next reader of rwlock %s", rwlock->name); + maxpri = 0; + while ((p = lwpGetFirst(&rwlock->rq))) { + lwpStatus(p, "wake up next reader of rwlock %s", rwlock->name); + maxpri = MAX(maxpri, p->pri); + lwpReady(p); + } } else return; - lwpReady(p); - if (LwpCurrent->pri < p->pri) { + if (LwpCurrent->pri < maxpri) { lwpStatus(LwpCurrent, "yielding to thread with higher priority"); lwpYield(); }