aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2020-02-10 23:06:33 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2020-02-11 00:32:44 +0100
commit8ba6ad703cb38ec57cdb473650ac289e5f8496d5 (patch)
tree843104571af29b6872721b6477d3b2e2444a3e96
parentcd7965bd970b0a298e734acc9dafae0a5db5f712 (diff)
downloadglibc-8ba6ad703cb38ec57cdb473650ac289e5f8496d5.tar
glibc-8ba6ad703cb38ec57cdb473650ac289e5f8496d5.tar.gz
glibc-8ba6ad703cb38ec57cdb473650ac289e5f8496d5.tar.bz2
glibc-8ba6ad703cb38ec57cdb473650ac289e5f8496d5.zip
hurd: Add __pthread_spin_wait and use it
900778283ac3 ("htl: make pthread_spin_lock really spin") made pthread_spin_lock really spin and not block, but the current users of __pthread_spin_lock were assuming that it blocks, i.e. they use it as a lightweight mutex fitting in just one int. __pthread_spin_wait provides that support back.
-rw-r--r--sysdeps/htl/pt-barrier-wait.c2
-rw-r--r--sysdeps/htl/pt-cond-brdcast.c4
-rw-r--r--sysdeps/htl/pt-cond-destroy.c2
-rw-r--r--sysdeps/htl/pt-cond-signal.c2
-rw-r--r--sysdeps/htl/pt-cond-timedwait.c6
-rw-r--r--sysdeps/htl/pt-once.c2
-rw-r--r--sysdeps/htl/pt-rwlock-timedrdlock.c4
-rw-r--r--sysdeps/htl/pt-rwlock-timedwrlock.c4
-rw-r--r--sysdeps/htl/pt-rwlock-tryrdlock.c2
-rw-r--r--sysdeps/htl/pt-rwlock-trywrlock.c2
-rw-r--r--sysdeps/htl/pt-rwlock-unlock.c2
-rw-r--r--sysdeps/htl/sem-getvalue.c2
-rw-r--r--sysdeps/htl/sem-post.c2
-rw-r--r--sysdeps/htl/sem-timedwait.c4
-rw-r--r--sysdeps/htl/sem-trywait.c2
-rw-r--r--sysdeps/mach/htl/bits/spin-lock-inline.h9
-rw-r--r--sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c6
17 files changed, 33 insertions, 24 deletions
diff --git a/sysdeps/htl/pt-barrier-wait.c b/sysdeps/htl/pt-barrier-wait.c
index 146605abd8..46a36f7ca6 100644
--- a/sysdeps/htl/pt-barrier-wait.c
+++ b/sysdeps/htl/pt-barrier-wait.c
@@ -24,7 +24,7 @@
int
pthread_barrier_wait (pthread_barrier_t *barrier)
{
- __pthread_spin_lock (&barrier->__lock);
+ __pthread_spin_wait (&barrier->__lock);
if (--barrier->__pending == 0)
{
barrier->__pending = barrier->__count;
diff --git a/sysdeps/htl/pt-cond-brdcast.c b/sysdeps/htl/pt-cond-brdcast.c
index 37dec0a31b..816d183ab4 100644
--- a/sysdeps/htl/pt-cond-brdcast.c
+++ b/sysdeps/htl/pt-cond-brdcast.c
@@ -26,7 +26,7 @@ __pthread_cond_broadcast (pthread_cond_t *cond)
{
struct __pthread *wakeup;
- __pthread_spin_lock (&cond->__lock);
+ __pthread_spin_wait (&cond->__lock);
while ((wakeup = cond->__queue))
{
__pthread_dequeue (wakeup);
@@ -34,7 +34,7 @@ __pthread_cond_broadcast (pthread_cond_t *cond)
/* 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_wait (&cond->__lock);
}
__pthread_spin_unlock (&cond->__lock);
diff --git a/sysdeps/htl/pt-cond-destroy.c b/sysdeps/htl/pt-cond-destroy.c
index b28e7e1ada..57c2682484 100644
--- a/sysdeps/htl/pt-cond-destroy.c
+++ b/sysdeps/htl/pt-cond-destroy.c
@@ -24,7 +24,7 @@ __pthread_cond_destroy (pthread_cond_t *cond)
{
int ret = 0;
- __pthread_spin_lock (&cond->__lock);
+ __pthread_spin_wait (&cond->__lock);
if (cond->__queue)
ret = EBUSY;
__pthread_spin_unlock (&cond->__lock);
diff --git a/sysdeps/htl/pt-cond-signal.c b/sysdeps/htl/pt-cond-signal.c
index bbf23011e3..30f21cc6b5 100644
--- a/sysdeps/htl/pt-cond-signal.c
+++ b/sysdeps/htl/pt-cond-signal.c
@@ -27,7 +27,7 @@ __pthread_cond_signal (pthread_cond_t *cond)
{
struct __pthread *wakeup;
- __pthread_spin_lock (&cond->__lock);
+ __pthread_spin_wait (&cond->__lock);
wakeup = cond->__queue;
if (wakeup != NULL)
__pthread_dequeue (wakeup);
diff --git a/sysdeps/htl/pt-cond-timedwait.c b/sysdeps/htl/pt-cond-timedwait.c
index 3a11e016d7..b5ce2f023e 100644
--- a/sysdeps/htl/pt-cond-timedwait.c
+++ b/sysdeps/htl/pt-cond-timedwait.c
@@ -50,7 +50,7 @@ cancel_hook (void *arg)
pthread_cond_t *cond = ctx->cond;
int unblock;
- __pthread_spin_lock (&cond->__lock);
+ __pthread_spin_wait (&cond->__lock);
/* The thread only needs to be awaken if it's blocking or about to block.
If it was already unblocked, it's not queued any more. */
unblock = wakeup->prevp != NULL;
@@ -112,7 +112,7 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond,
the cancellation hook to simplify the cancellation procedure, i.e.
if the thread is queued, it can be cancelled, otherwise it is
already unblocked, progressing on the return path. */
- __pthread_spin_lock (&cond->__lock);
+ __pthread_spin_wait (&cond->__lock);
__pthread_enqueue (&cond->__queue, self);
if (cond->__attr != NULL)
clock_id = cond->__attr->__clock;
@@ -135,7 +135,7 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond,
__pthread_block (self);
}
- __pthread_spin_lock (&cond->__lock);
+ __pthread_spin_wait (&cond->__lock);
if (self->prevp == NULL)
{
/* Another thread removed us from the list of waiters, which means a
diff --git a/sysdeps/htl/pt-once.c b/sysdeps/htl/pt-once.c
index 7f86e28006..0104eebd3e 100644
--- a/sysdeps/htl/pt-once.c
+++ b/sysdeps/htl/pt-once.c
@@ -36,7 +36,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
atomic_full_barrier ();
if (once_control->__run == 0)
{
- __pthread_spin_lock (&once_control->__lock);
+ __pthread_spin_wait (&once_control->__lock);
if (once_control->__run == 0)
{
diff --git a/sysdeps/htl/pt-rwlock-timedrdlock.c b/sysdeps/htl/pt-rwlock-timedrdlock.c
index 9dab8deb77..c2827662fd 100644
--- a/sysdeps/htl/pt-rwlock-timedrdlock.c
+++ b/sysdeps/htl/pt-rwlock-timedrdlock.c
@@ -33,7 +33,7 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
int drain;
struct __pthread *self;
- __pthread_spin_lock (&rwlock->__lock);
+ __pthread_spin_wait (&rwlock->__lock);
if (__pthread_spin_trylock (&rwlock->__held) == 0)
/* Successfully acquired the lock. */
{
@@ -79,7 +79,7 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
__pthread_block (self);
}
- __pthread_spin_lock (&rwlock->__lock);
+ __pthread_spin_wait (&rwlock->__lock);
if (self->prevp == NULL)
/* Another thread removed us from the queue, which means a wakeup message
has been sent. It was either consumed while we were blocking, or
diff --git a/sysdeps/htl/pt-rwlock-timedwrlock.c b/sysdeps/htl/pt-rwlock-timedwrlock.c
index 57c46dccca..d0293c1e96 100644
--- a/sysdeps/htl/pt-rwlock-timedwrlock.c
+++ b/sysdeps/htl/pt-rwlock-timedwrlock.c
@@ -33,7 +33,7 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,
int drain;
struct __pthread *self;
- __pthread_spin_lock (&rwlock->__lock);
+ __pthread_spin_wait (&rwlock->__lock);
if (__pthread_spin_trylock (&rwlock->__held) == 0)
/* Successfully acquired the lock. */
{
@@ -65,7 +65,7 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,
__pthread_block (self);
}
- __pthread_spin_lock (&rwlock->__lock);
+ __pthread_spin_wait (&rwlock->__lock);
if (self->prevp == NULL)
/* Another thread removed us from the queue, which means a wakeup message
has been sent. It was either consumed while we were blocking, or
diff --git a/sysdeps/htl/pt-rwlock-tryrdlock.c b/sysdeps/htl/pt-rwlock-tryrdlock.c
index 7baef3cccb..897528f24c 100644
--- a/sysdeps/htl/pt-rwlock-tryrdlock.c
+++ b/sysdeps/htl/pt-rwlock-tryrdlock.c
@@ -25,7 +25,7 @@
int
pthread_rwlock_tryrdlock (struct __pthread_rwlock *rwlock)
{
- __pthread_spin_lock (&rwlock->__lock);
+ __pthread_spin_wait (&rwlock->__lock);
if (__pthread_spin_trylock (&rwlock->__held) == 0)
/* Successfully acquired the lock. */
{
diff --git a/sysdeps/htl/pt-rwlock-trywrlock.c b/sysdeps/htl/pt-rwlock-trywrlock.c
index 95593a97b9..423f7faf0f 100644
--- a/sysdeps/htl/pt-rwlock-trywrlock.c
+++ b/sysdeps/htl/pt-rwlock-trywrlock.c
@@ -25,7 +25,7 @@
int
pthread_rwlock_trywrlock (struct __pthread_rwlock *rwlock)
{
- __pthread_spin_lock (&rwlock->__lock);
+ __pthread_spin_wait (&rwlock->__lock);
if (__pthread_spin_trylock (&rwlock->__held) == 0)
/* Successfully acquired the lock. */
{
diff --git a/sysdeps/htl/pt-rwlock-unlock.c b/sysdeps/htl/pt-rwlock-unlock.c
index 49ed4ee511..5be6a9e678 100644
--- a/sysdeps/htl/pt-rwlock-unlock.c
+++ b/sysdeps/htl/pt-rwlock-unlock.c
@@ -28,7 +28,7 @@ __pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
{
struct __pthread *wakeup;
- __pthread_spin_lock (&rwlock->__lock);
+ __pthread_spin_wait (&rwlock->__lock);
assert (__pthread_spin_trylock (&rwlock->__held) == EBUSY);
diff --git a/sysdeps/htl/sem-getvalue.c b/sysdeps/htl/sem-getvalue.c
index 9c8188e866..2d72a63824 100644
--- a/sysdeps/htl/sem-getvalue.c
+++ b/sysdeps/htl/sem-getvalue.c
@@ -22,7 +22,7 @@
int
__sem_getvalue (sem_t *restrict sem, int *restrict value)
{
- __pthread_spin_lock (&sem->__lock);
+ __pthread_spin_wait (&sem->__lock);
*value = sem->__value;
__pthread_spin_unlock (&sem->__lock);
diff --git a/sysdeps/htl/sem-post.c b/sysdeps/htl/sem-post.c
index 2e0be8fc49..fd0c6338c6 100644
--- a/sysdeps/htl/sem-post.c
+++ b/sysdeps/htl/sem-post.c
@@ -26,7 +26,7 @@ __sem_post (sem_t *sem)
{
struct __pthread *wakeup;
- __pthread_spin_lock (&sem->__lock);
+ __pthread_spin_wait (&sem->__lock);
if (sem->__value > 0)
/* Do a quick up. */
{
diff --git a/sysdeps/htl/sem-timedwait.c b/sysdeps/htl/sem-timedwait.c
index a61acfd43f..2d8cf25328 100644
--- a/sysdeps/htl/sem-timedwait.c
+++ b/sysdeps/htl/sem-timedwait.c
@@ -32,7 +32,7 @@ __sem_timedwait_internal (sem_t *restrict sem,
struct __pthread *self;
clockid_t clock_id = CLOCK_REALTIME;
- __pthread_spin_lock (&sem->__lock);
+ __pthread_spin_wait (&sem->__lock);
if (sem->__value > 0)
/* Successful down. */
{
@@ -59,7 +59,7 @@ __sem_timedwait_internal (sem_t *restrict sem,
else
err = __pthread_block_intr (self);
- __pthread_spin_lock (&sem->__lock);
+ __pthread_spin_wait (&sem->__lock);
if (self->prevp == NULL)
/* Another thread removed us from the queue, which means a wakeup message
has been sent. It was either consumed while we were blocking, or
diff --git a/sysdeps/htl/sem-trywait.c b/sysdeps/htl/sem-trywait.c
index bf8cd6056e..6a0633bfef 100644
--- a/sysdeps/htl/sem-trywait.c
+++ b/sysdeps/htl/sem-trywait.c
@@ -24,7 +24,7 @@
int
__sem_trywait (sem_t *sem)
{
- __pthread_spin_lock (&sem->__lock);
+ __pthread_spin_wait (&sem->__lock);
if (sem->__value > 0)
/* Successful down. */
{
diff --git a/sysdeps/mach/htl/bits/spin-lock-inline.h b/sysdeps/mach/htl/bits/spin-lock-inline.h
index 556bdd4c28..006b6fd5f2 100644
--- a/sysdeps/mach/htl/bits/spin-lock-inline.h
+++ b/sysdeps/mach/htl/bits/spin-lock-inline.h
@@ -71,6 +71,15 @@ __pthread_spin_lock (__pthread_spinlock_t *__lock)
return 0;
}
+__PT_SPIN_INLINE int __pthread_spin_wait (__pthread_spinlock_t *__lock);
+
+__PT_SPIN_INLINE int
+__pthread_spin_wait (__pthread_spinlock_t *__lock)
+{
+ __spin_lock ((__spin_lock_t *) __lock);
+ return 0;
+}
+
__PT_SPIN_INLINE int __pthread_spin_unlock (__pthread_spinlock_t *__lock);
__PT_SPIN_INLINE int
diff --git a/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
index 12dd8634d4..939ed568ba 100644
--- a/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
+++ b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c
@@ -56,7 +56,7 @@ __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
{
int unblock;
- __pthread_spin_lock (&cond->__lock);
+ __pthread_spin_wait (&cond->__lock);
/* The thread only needs to be awaken if it's blocking or about to block.
If it was already unblocked, it's not queued any more. */
unblock = self->prevp != NULL;
@@ -81,7 +81,7 @@ __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
the condition variable's lock. */
__spin_lock (&ss->lock);
- __pthread_spin_lock (&cond->__lock);
+ __pthread_spin_wait (&cond->__lock);
cancel = ss->cancel;
if (cancel)
/* We were cancelled before doing anything. Don't block at all. */
@@ -123,7 +123,7 @@ __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond,
/* As it was done when enqueueing, prevent hurd_thread_cancel from
suspending us while the condition lock is held. */
__spin_lock (&ss->lock);
- __pthread_spin_lock (&cond->__lock);
+ __pthread_spin_wait (&cond->__lock);
if (self->prevp == NULL)
/* Another thread removed us from the list of waiters, which means
a wakeup message has been sent. It was either consumed while