From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 717 invoked from network); 27 Dec 2020 18:57:25 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 27 Dec 2020 18:57:25 -0000 Received: (qmail 30532 invoked by uid 550); 27 Dec 2020 18:57:15 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 6139 invoked from network); 27 Dec 2020 18:43:06 -0000 Date: Sun, 27 Dec 2020 18:42:47 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail; t=1609094574; bh=Sv1BnF7OUMfuZaASpDcHsw+Lt6ovyu6Zn5hyZ5MTy+8=; h=Date:To:From:Cc:Reply-To:Subject:In-Reply-To:References:From; b=lkhM6qinAYVeQkjkJzEZIbalFYCKISnd724ihow9kb7upKzYiX8hzZndHEjUNj4PD ylO5DuX8r1obMOE2CiL/fDsvzxycJLvhkBtvOH9T/Mgwzjwk8k3jc/43iWZoDx3iUc aehb+36ESOFtcE2TPtMZpe/cDH3VK8trC7xwXoqRaiN/ytlc/hIcCySLe1xkOBEqD0 EBjuALLX/Bhii1fufr598HmgD+QE8sAimQUZ4RMb4sW3lH/rE/6iq05clZUeoUa0b3 o+YtvGmbxGVoUKbEKexmuv3QEwCDaqWVWrqiava3tURQZIl9doYhdH6gPRC6QkjqmA erlLmFo9OLriQ== To: Rich Felker , musl@lists.openwall.com From: Alexander Lobakin Cc: Alexander Lobakin Message-ID: <20201227184032.22413-17-alobakin@pm.me> In-Reply-To: <20201227184032.22413-1-alobakin@pm.me> References: <20201227183842.22030-1-alobakin@pm.me> <20201227184032.22413-1-alobakin@pm.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: [musl] [PATCH 17/18] futex: prefer time64 variant if available Instead of using time64 variant "only when needed", use it as a default and fallback to time32 only on -ENOSYS. This also introduces a new shorthand, __futexcall(), for futex calls without timespec argument. Signed-off-by: Alexander Lobakin --- src/internal/pthread_impl.h | 22 ++++++++++++++++++---- src/thread/__timedwait.c | 6 ++---- src/thread/__wait.c | 4 ++-- src/thread/pthread_barrier_wait.c | 6 +++--- src/thread/pthread_cond_timedwait.c | 10 +++++----- src/thread/pthread_mutex_timedlock.c | 8 +++----- src/thread/pthread_mutex_trylock.c | 2 +- src/thread/pthread_mutex_unlock.c | 2 +- src/thread/pthread_mutexattr_setprotocol.c | 2 +- 9 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index de2b9d8b477e..abb2a9a074a0 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -165,18 +165,32 @@ hidden void __unmapself(void *, size_t); hidden int __timedwait(volatile int *, int, clockid_t, const struct timesp= ec *, int); hidden int __timedwait_cp(volatile int *, int, clockid_t, const struct tim= espec *, int); hidden void __wait(volatile int *, volatile int *, int, int); + +#ifdef SYS_futex_time64 +#define __futexcall(...) ({=09=09=09=09=09\ +=09int __r =3D __syscall(SYS_futex_time64, ##__VA_ARGS__);=09\ +=09if (!(SYS_futex =3D=3D SYS_futex_time64 || __r !=3D -ENOSYS))=09\ +=09=09__r =3D __syscall(SYS_futex, ##__VA_ARGS__);=09\ +=09__r;=09=09=09=09=09=09=09\ +}) +#else +#define __futexcall(...) ({=09=09=09=09=09\ +=09__syscall(SYS_futex, ##__VA_ARGS__);=09=09=09\ +}) +#endif + static inline void __wake(volatile void *addr, int cnt, int priv) { =09if (priv) priv =3D FUTEX_PRIVATE; =09if (cnt<0) cnt =3D INT_MAX; -=09__syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) !=3D -ENOSYS || -=09__syscall(SYS_futex, addr, FUTEX_WAKE, cnt); +=09__futexcall(addr, FUTEX_WAKE|priv, cnt) !=3D -ENOSYS || +=09__futexcall(addr, FUTEX_WAKE, cnt); } static inline void __futexwait(volatile void *addr, int val, int priv) { =09if (priv) priv =3D FUTEX_PRIVATE; -=09__syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) !=3D -ENOSYS || -=09__syscall(SYS_futex, addr, FUTEX_WAIT, val, 0); +=09__futexcall(addr, FUTEX_WAIT|priv, val, 0) !=3D -ENOSYS || +=09__futexcall(addr, FUTEX_WAIT, val, 0); } =20 hidden void __acquire_ptc(void); diff --git a/src/thread/__timedwait.c b/src/thread/__timedwait.c index 666093be9851..38d326834c14 100644 --- a/src/thread/__timedwait.c +++ b/src/thread/__timedwait.c @@ -14,10 +14,8 @@ static int __futex4_cp(volatile void *addr, int op, int = val, const struct timesp #ifdef SYS_futex_time64 =09time_t s =3D to ? to->tv_sec : 0; =09long ns =3D to ? to->tv_nsec : 0; -=09r =3D -ENOSYS; -=09if (SYS_futex =3D=3D SYS_futex_time64 || !IS32BIT(s)) -=09=09r =3D __syscall_cp(SYS_futex_time64, addr, op, val, -=09=09=09to ? ((long long[]){s, ns}) : 0); +=09r =3D __syscall_cp(SYS_futex_time64, addr, op, val, +=09=09to ? ((long long[]){s, ns}) : 0); =09if (SYS_futex =3D=3D SYS_futex_time64 || r!=3D-ENOSYS) return r; =09to =3D to ? (void *)(long[]){CLAMP(s), ns} : 0; #endif diff --git a/src/thread/__wait.c b/src/thread/__wait.c index dc33c1a30992..ba6397207649 100644 --- a/src/thread/__wait.c +++ b/src/thread/__wait.c @@ -10,8 +10,8 @@ void __wait(volatile int *addr, volatile int *waiters, in= t val, int priv) =09} =09if (waiters) a_inc(waiters); =09while (*addr=3D=3Dval) { -=09=09__syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) !=3D -ENOSYS -=09=09|| __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0); +=09=09__futexcall(addr, FUTEX_WAIT|priv, val, 0) !=3D -ENOSYS +=09=09|| __futexcall(addr, FUTEX_WAIT, val, 0); =09} =09if (waiters) a_dec(waiters); } diff --git a/src/thread/pthread_barrier_wait.c b/src/thread/pthread_barrier= _wait.c index cc2a8bbf58a9..7e0b8cc9cbe2 100644 --- a/src/thread/pthread_barrier_wait.c +++ b/src/thread/pthread_barrier_wait.c @@ -33,7 +33,7 @@ static int pshared_barrier_wait(pthread_barrier_t *b) =09=09while ((v=3Db->_b_count)) =09=09=09__wait(&b->_b_count, &b->_b_waiters2, v, 0); =09} -=09 + =09/* Perform a recursive unlock suitable for self-sync'd destruction */ =09do { =09=09v =3D b->_b_lock; @@ -84,8 +84,8 @@ int pthread_barrier_wait(pthread_barrier_t *b) =09=09=09a_spin(); =09=09a_inc(&inst->finished); =09=09while (inst->finished =3D=3D 1) -=09=09=09__syscall(SYS_futex,&inst->finished,FUTEX_WAIT|FUTEX_PRIVATE,1,0)= !=3D -ENOSYS -=09=09=09|| __syscall(SYS_futex,&inst->finished,FUTEX_WAIT,1,0); +=09=09=09__futexcall(&inst->finished,FUTEX_WAIT|FUTEX_PRIVATE,1,0) !=3D -E= NOSYS +=09=09=09|| __futexcall(&inst->finished,FUTEX_WAIT,1,0); =09=09return PTHREAD_BARRIER_SERIAL_THREAD; =09} =20 diff --git a/src/thread/pthread_cond_timedwait.c b/src/thread/pthread_cond_= timedwait.c index 6b761455c47f..a4386761479b 100644 --- a/src/thread/pthread_cond_timedwait.c +++ b/src/thread/pthread_cond_timedwait.c @@ -49,8 +49,8 @@ static inline void unlock_requeue(volatile int *l, volati= le int *r, int w) { =09a_store(l, 0); =09if (w) __wake(l, 1, 1); -=09else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) !=3D= -ENOSYS -=09=09|| __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r); +=09else __futexcall(l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) !=3D -ENOSYS +=09=09|| __futexcall(l, FUTEX_REQUEUE, 0, 1, r); } =20 enum { @@ -121,12 +121,12 @@ int __pthread_cond_timedwait(pthread_cond_t *restrict= c, pthread_mutex_t *restri =09=09 * via the futex notify below. */ =20 =09=09lock(&c->_c_lock); -=09=09 + =09=09if (c->_c_head =3D=3D &node) c->_c_head =3D node.next; =09=09else if (node.prev) node.prev->next =3D node.next; =09=09if (c->_c_tail =3D=3D &node) c->_c_tail =3D node.prev; =09=09else if (node.next) node.next->prev =3D node.prev; -=09=09 + =09=09unlock(&c->_c_lock); =20 =09=09if (node.notify) { @@ -156,7 +156,7 @@ relock: =09=09if (val>0) a_cas(&m->_m_lock, val, val|0x80000000); =09=09unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128= )); =09} else if (!(m->_m_type & 8)) { -=09=09a_dec(&m->_m_waiters);=09=09 +=09=09a_dec(&m->_m_waiters); =09} =20 =09/* Since a signal was consumed, cancellation is not permitted. */ diff --git a/src/thread/pthread_mutex_timedlock.c b/src/thread/pthread_mute= x_timedlock.c index 9279fc54308a..1f2f1d862c69 100644 --- a/src/thread/pthread_mutex_timedlock.c +++ b/src/thread/pthread_mutex_timedlock.c @@ -8,10 +8,8 @@ static int __futex4(volatile void *addr, int op, int val, = const struct timespec #ifdef SYS_futex_time64 =09time_t s =3D to ? to->tv_sec : 0; =09long ns =3D to ? to->tv_nsec : 0; -=09int r =3D -ENOSYS; -=09if (SYS_futex =3D=3D SYS_futex_time64 || !IS32BIT(s)) -=09=09r =3D __syscall(SYS_futex_time64, addr, op, val, -=09=09=09to ? ((long long[]){s, ns}) : 0); +=09int r =3D __syscall(SYS_futex_time64, addr, op, val, +=09=09to ? ((long long[]){s, ns}) : 0); =09if (SYS_futex =3D=3D SYS_futex_time64 || r!=3D-ENOSYS) return r; =09to =3D to ? (void *)(long[]){CLAMP(s), ns} : 0; #endif @@ -66,7 +64,7 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m= , const struct timespec =09if (r !=3D EBUSY) return r; =20 =09if (type&8) return pthread_mutex_timedlock_pi(m, at); -=09 + =09int spins =3D 100; =09while (spins-- && m->_m_lock && !m->_m_waiters) a_spin(); =20 diff --git a/src/thread/pthread_mutex_trylock.c b/src/thread/pthread_mutex_= trylock.c index a24e7c58ac39..d2a92601b6d3 100644 --- a/src/thread/pthread_mutex_trylock.c +++ b/src/thread/pthread_mutex_trylock.c @@ -43,7 +43,7 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) success: =09if ((type&8) && m->_m_waiters) { =09=09int priv =3D (type & 128) ^ 128; -=09=09__syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv); +=09=09__futexcall(&m->_m_lock, FUTEX_UNLOCK_PI|priv); =09=09self->robust_list.pending =3D 0; =09=09return (type&4) ? ENOTRECOVERABLE : EBUSY; =09} diff --git a/src/thread/pthread_mutex_unlock.c b/src/thread/pthread_mutex_u= nlock.c index b66423e6c34f..0b7da563c516 100644 --- a/src/thread/pthread_mutex_unlock.c +++ b/src/thread/pthread_mutex_unlock.c @@ -33,7 +33,7 @@ int __pthread_mutex_unlock(pthread_mutex_t *m) =09if (type&8) { =09=09if (old<0 || a_cas(&m->_m_lock, old, new)!=3Dold) { =09=09=09if (new) a_store(&m->_m_waiters, -1); -=09=09=09__syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv); +=09=09=09__futexcall(&m->_m_lock, FUTEX_UNLOCK_PI|priv); =09=09} =09=09cont =3D 0; =09=09waiters =3D 0; diff --git a/src/thread/pthread_mutexattr_setprotocol.c b/src/thread/pthrea= d_mutexattr_setprotocol.c index 8b80c1ce9b14..456fb9f48d2e 100644 --- a/src/thread/pthread_mutexattr_setprotocol.c +++ b/src/thread/pthread_mutexattr_setprotocol.c @@ -14,7 +14,7 @@ int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a,= int protocol) =09=09r =3D check_pi_result; =09=09if (r < 0) { =09=09=09volatile int lk =3D 0; -=09=09=09r =3D -__syscall(SYS_futex, &lk, FUTEX_LOCK_PI, 0, 0); +=09=09=09r =3D -__futexcall(&lk, FUTEX_LOCK_PI, 0, 0); =09=09=09a_store(&check_pi_result, r); =09=09} =09=09if (r) return r; --=20 2.29.2