fix excessive/insufficient wakes in __vm_unlock
authorRich Felker <dalias@aerifal.cx>
Wed, 28 Sep 2011 23:45:37 +0000 (19:45 -0400)
committerRich Felker <dalias@aerifal.cx>
Wed, 28 Sep 2011 23:45:37 +0000 (19:45 -0400)
there is no need to send a wake when the lock count does not hit zero,
but when it does, all waiters must be woken (since all with the same
sign are eligible to obtain the lock).

src/thread/pthread_barrier_wait.c

index 71f7b5feebac79867b2fbbcd4cd1feac178194f7..6052925a819a5280f627572d8a6b6455dcfa0b71 100644 (file)
@@ -13,9 +13,9 @@ void __vm_lock(int inc)
 
 void __vm_unlock(void)
 {
-       if (vmlock[0]>0) a_dec(vmlock);
-       else a_inc(vmlock);
-       if (vmlock[1]) __wake(vmlock, 1, 1);
+       int inc = vmlock[0]>0 ? -1 : 1;
+       if (a_fetch_add(vmlock, inc)==-inc && vmlock[1])
+               __wake(vmlock, -1, 1);
 }
 
 static int pshared_barrier_wait(pthread_barrier_t *b)