From patchwork Mon Feb 10 23:33:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 1236037 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-109432-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ens-lyon.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha1 header.s=default header.b=f53zN+n+; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48Gj0G159Hz9sP7 for ; Tue, 11 Feb 2020 10:33:49 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id :mime-version:content-transfer-encoding; q=dns; s=default; b=OPF w+inmFH/r3kmlASyH6HSeekPL5Axm1ti7+CKNQUodVtphonlffR/68U/r5bbSKmo M37cNlPZJTKr0U7edktyzDR2dC0IxrmWm/mPVAyR9t0cwAL48eqPdeJC79UzODlg nILDIzpwDAIbHyKOnYgxb+03tFSUeP2ihFJZtA3Y= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id :mime-version:content-transfer-encoding; s=default; bh=U0YKcHzvY hvwIEpB67aI4ByvEn8=; b=f53zN+n+/hDrYTlSN8+/lsrlu+TVmIDoMu4vYI+0g HG4063yiHsB7aa+ExdZQxpZV4D7zmV1hSiGEzpe3lVu+RRYNFfPhS2/GY7xP8aon B/5wTiKPZsKzR0nI615eDTXb3IE6ArGNH4cehLqa5pOVjfxX3MGxAF95PMPKrO/S 6o= Received: (qmail 80387 invoked by alias); 10 Feb 2020 23:33:43 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 80379 invoked by uid 89); 10 Feb 2020 23:33:43 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_NEUTRAL autolearn=ham version=3.3.1 spammy=wake, queued, acquired, fitting X-HELO: hera.aquilenet.fr From: Samuel Thibault To: libc-alpha@sourceware.org Cc: Samuel Thibault , commit-hurd@gnu.org Subject: [hurd,commited] hurd: Add __pthread_spin_wait and use it Date: Tue, 11 Feb 2020 00:33:34 +0100 Message-Id: <20200210233334.240975-1-samuel.thibault@ens-lyon.org> MIME-Version: 1.0 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. --- sysdeps/htl/pt-barrier-wait.c | 2 +- sysdeps/htl/pt-cond-brdcast.c | 4 ++-- sysdeps/htl/pt-cond-destroy.c | 2 +- sysdeps/htl/pt-cond-signal.c | 2 +- sysdeps/htl/pt-cond-timedwait.c | 6 +++--- sysdeps/htl/pt-once.c | 2 +- sysdeps/htl/pt-rwlock-timedrdlock.c | 4 ++-- sysdeps/htl/pt-rwlock-timedwrlock.c | 4 ++-- sysdeps/htl/pt-rwlock-tryrdlock.c | 2 +- sysdeps/htl/pt-rwlock-trywrlock.c | 2 +- sysdeps/htl/pt-rwlock-unlock.c | 2 +- sysdeps/htl/sem-getvalue.c | 2 +- sysdeps/htl/sem-post.c | 2 +- sysdeps/htl/sem-timedwait.c | 4 ++-- sysdeps/htl/sem-trywait.c | 2 +- sysdeps/mach/htl/bits/spin-lock-inline.h | 9 +++++++++ sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c | 6 +++--- 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