summaryrefslogtreecommitdiff
path: root/sysdeps/generic
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2014-11-02 02:32:07 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2014-11-02 02:32:07 +0100
commit3360034b7814d90503098700fc18bf07c47838c3 (patch)
treeb18eb13440c56a512f3bb69230181ebb6933155d /sysdeps/generic
parent58a36b39ff9968d203037db496cedd8acbb969c3 (diff)
Wake up queued threads without spin lock held
so that they may have a chance to actually preempt us. Otherwise they will merely immediately fail to acquire the spin lock, and thus preemption will have served no purpose. * sysdeps/generic/pt-cond-brdcast.c (__pthread_cond_broadcast): Unlock cond->__lock while waking the queued thread.
Diffstat (limited to 'sysdeps/generic')
-rw-r--r--sysdeps/generic/pt-cond-brdcast.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/sysdeps/generic/pt-cond-brdcast.c b/sysdeps/generic/pt-cond-brdcast.c
index ad44f83..f2a2987 100644
--- a/sysdeps/generic/pt-cond-brdcast.c
+++ b/sysdeps/generic/pt-cond-brdcast.c
@@ -28,10 +28,15 @@ __pthread_cond_broadcast (pthread_cond_t *cond)
struct __pthread *wakeup;
__pthread_spin_lock (&cond->__lock);
- __pthread_dequeuing_iterate (cond->__queue, wakeup)
- __pthread_wakeup (wakeup);
-
- cond->__queue = NULL;
+ while ((wakeup = cond->__queue))
+ {
+ __pthread_dequeue (wakeup);
+ __pthread_spin_unlock (&cond->__lock);
+ /* Wake it up without spin held, so it may have a chance to really
+ preempt us */
+ __pthread_wakeup (wakeup);
+ __pthread_spin_lock (&cond->__lock);
+ }
__pthread_spin_unlock (&cond->__lock);
return 0;