From: Alexander Lobakin <alobakin@pm.me>
To: Rich Felker <dalias@aerifal.cx>, musl@lists.openwall.com
Cc: Alexander Lobakin <alobakin@pm.me>
Subject: [musl] [PATCH 17/18] futex: prefer time64 variant if available
Date: Sun, 27 Dec 2020 18:42:47 +0000 [thread overview]
Message-ID: <20201227184032.22413-17-alobakin@pm.me> (raw)
In-Reply-To: <20201227184032.22413-1-alobakin@pm.me>
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 <alobakin@pm.me>
---
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 timespec *, int);
hidden int __timedwait_cp(volatile int *, int, clockid_t, const struct timespec *, int);
hidden void __wait(volatile int *, volatile int *, int, int);
+
+#ifdef SYS_futex_time64
+#define __futexcall(...) ({ \
+ int __r = __syscall(SYS_futex_time64, ##__VA_ARGS__); \
+ if (!(SYS_futex == SYS_futex_time64 || __r != -ENOSYS)) \
+ __r = __syscall(SYS_futex, ##__VA_ARGS__); \
+ __r; \
+})
+#else
+#define __futexcall(...) ({ \
+ __syscall(SYS_futex, ##__VA_ARGS__); \
+})
+#endif
+
static inline void __wake(volatile void *addr, int cnt, int priv)
{
if (priv) priv = FUTEX_PRIVATE;
if (cnt<0) cnt = INT_MAX;
- __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS ||
- __syscall(SYS_futex, addr, FUTEX_WAKE, cnt);
+ __futexcall(addr, FUTEX_WAKE|priv, cnt) != -ENOSYS ||
+ __futexcall(addr, FUTEX_WAKE, cnt);
}
static inline void __futexwait(volatile void *addr, int val, int priv)
{
if (priv) priv = FUTEX_PRIVATE;
- __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS ||
- __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);
+ __futexcall(addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS ||
+ __futexcall(addr, FUTEX_WAIT, val, 0);
}
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
time_t s = to ? to->tv_sec : 0;
long ns = to ? to->tv_nsec : 0;
- r = -ENOSYS;
- if (SYS_futex == SYS_futex_time64 || !IS32BIT(s))
- r = __syscall_cp(SYS_futex_time64, addr, op, val,
- to ? ((long long[]){s, ns}) : 0);
+ r = __syscall_cp(SYS_futex_time64, addr, op, val,
+ to ? ((long long[]){s, ns}) : 0);
if (SYS_futex == SYS_futex_time64 || r!=-ENOSYS) return r;
to = 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, int val, int priv)
}
if (waiters) a_inc(waiters);
while (*addr==val) {
- __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS
- || __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);
+ __futexcall(addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS
+ || __futexcall(addr, FUTEX_WAIT, val, 0);
}
if (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)
while ((v=b->_b_count))
__wait(&b->_b_count, &b->_b_waiters2, v, 0);
}
-
+
/* Perform a recursive unlock suitable for self-sync'd destruction */
do {
v = b->_b_lock;
@@ -84,8 +84,8 @@ int pthread_barrier_wait(pthread_barrier_t *b)
a_spin();
a_inc(&inst->finished);
while (inst->finished == 1)
- __syscall(SYS_futex,&inst->finished,FUTEX_WAIT|FUTEX_PRIVATE,1,0) != -ENOSYS
- || __syscall(SYS_futex,&inst->finished,FUTEX_WAIT,1,0);
+ __futexcall(&inst->finished,FUTEX_WAIT|FUTEX_PRIVATE,1,0) != -ENOSYS
+ || __futexcall(&inst->finished,FUTEX_WAIT,1,0);
return PTHREAD_BARRIER_SERIAL_THREAD;
}
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, volatile int *r, int w)
{
a_store(l, 0);
if (w) __wake(l, 1, 1);
- else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS
- || __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r);
+ else __futexcall(l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS
+ || __futexcall(l, FUTEX_REQUEUE, 0, 1, r);
}
enum {
@@ -121,12 +121,12 @@ int __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restri
* via the futex notify below. */
lock(&c->_c_lock);
-
+
if (c->_c_head == &node) c->_c_head = node.next;
else if (node.prev) node.prev->next = node.next;
if (c->_c_tail == &node) c->_c_tail = node.prev;
else if (node.next) node.next->prev = node.prev;
-
+
unlock(&c->_c_lock);
if (node.notify) {
@@ -156,7 +156,7 @@ relock:
if (val>0) a_cas(&m->_m_lock, val, val|0x80000000);
unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128));
} else if (!(m->_m_type & 8)) {
- a_dec(&m->_m_waiters);
+ a_dec(&m->_m_waiters);
}
/* Since a signal was consumed, cancellation is not permitted. */
diff --git a/src/thread/pthread_mutex_timedlock.c b/src/thread/pthread_mutex_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
time_t s = to ? to->tv_sec : 0;
long ns = to ? to->tv_nsec : 0;
- int r = -ENOSYS;
- if (SYS_futex == SYS_futex_time64 || !IS32BIT(s))
- r = __syscall(SYS_futex_time64, addr, op, val,
- to ? ((long long[]){s, ns}) : 0);
+ int r = __syscall(SYS_futex_time64, addr, op, val,
+ to ? ((long long[]){s, ns}) : 0);
if (SYS_futex == SYS_futex_time64 || r!=-ENOSYS) return r;
to = to ? (void *)(long[]){CLAMP(s), ns} : 0;
#endif
@@ -66,7 +64,7 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec
if (r != EBUSY) return r;
if (type&8) return pthread_mutex_timedlock_pi(m, at);
-
+
int spins = 100;
while (spins-- && m->_m_lock && !m->_m_waiters) a_spin();
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:
if ((type&8) && m->_m_waiters) {
int priv = (type & 128) ^ 128;
- __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv);
+ __futexcall(&m->_m_lock, FUTEX_UNLOCK_PI|priv);
self->robust_list.pending = 0;
return (type&4) ? ENOTRECOVERABLE : EBUSY;
}
diff --git a/src/thread/pthread_mutex_unlock.c b/src/thread/pthread_mutex_unlock.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)
if (type&8) {
if (old<0 || a_cas(&m->_m_lock, old, new)!=old) {
if (new) a_store(&m->_m_waiters, -1);
- __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv);
+ __futexcall(&m->_m_lock, FUTEX_UNLOCK_PI|priv);
}
cont = 0;
waiters = 0;
diff --git a/src/thread/pthread_mutexattr_setprotocol.c b/src/thread/pthread_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)
r = check_pi_result;
if (r < 0) {
volatile int lk = 0;
- r = -__syscall(SYS_futex, &lk, FUTEX_LOCK_PI, 0, 0);
+ r = -__futexcall(&lk, FUTEX_LOCK_PI, 0, 0);
a_store(&check_pi_result, r);
}
if (r) return r;
--
2.29.2
next prev parent reply other threads:[~2020-12-27 18:57 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-27 18:39 [musl] [PATCH 00/18] time64: always prefer time64 syscalls Alexander Lobakin
2020-12-27 18:40 ` [musl] [PATCH 01/18] clock_gettime: prefer time64 variant if available Alexander Lobakin
2020-12-27 18:40 ` [musl] [PATCH 02/18] clock_settime: " Alexander Lobakin
2020-12-27 18:41 ` [musl] [PATCH 03/18] clock_adjtime: try adjtimex at last Alexander Lobakin
2020-12-27 21:57 ` Rich Felker
2020-12-27 18:41 ` [musl] [PATCH 04/18] clock_getres: use time64 variant by default Alexander Lobakin
2020-12-27 18:41 ` [musl] [PATCH 05/18] clock_nanosleep: prefer time64 variant if available Alexander Lobakin
2020-12-27 18:41 ` [musl] [PATCH 06/18] timer_gettime: " Alexander Lobakin
2020-12-27 18:41 ` [musl] [PATCH 07/18] timer_settime: " Alexander Lobakin
2020-12-27 18:41 ` [musl] [PATCH 08/18] timerfd_gettime: " Alexander Lobakin
2020-12-27 18:41 ` [musl] [PATCH 09/18] timerfd_settime: " Alexander Lobakin
2020-12-27 18:41 ` [musl] [PATCH 10/18] utimensat: " Alexander Lobakin
2020-12-27 18:42 ` [musl] [PATCH 11/18] pselect, select: prefer time64 variant of pselect6 " Alexander Lobakin
2020-12-27 18:42 ` [musl] [PATCH 12/18] poll, ppoll: prefer time64 variant of ppoll " Alexander Lobakin
2020-12-27 18:42 ` [musl] [PATCH 13/18] mq_timedsend: prefer time64 variant " Alexander Lobakin
2020-12-27 18:42 ` [musl] [PATCH 14/18] mq_timedreceive: " Alexander Lobakin
2020-12-27 18:42 ` [musl] [PATCH 15/18] semtimedop: prefer time64 variant of semtimedop " Alexander Lobakin
2020-12-27 18:42 ` [musl] [PATCH 16/18] [rt_]sigtimedwait: prefer time64 variant " Alexander Lobakin
2020-12-27 18:42 ` Alexander Lobakin [this message]
2020-12-27 22:18 ` [musl] [PATCH 17/18] futex: " Rich Felker
2020-12-27 18:42 ` [musl] [PATCH 18/18] sched_rr_get_interval: use " Alexander Lobakin
2020-12-27 21:54 ` [musl] [PATCH 01/18] clock_gettime: prefer " Rich Felker
2020-12-27 21:52 ` [musl] [PATCH 00/18] time64: always prefer time64 syscalls Rich Felker
2020-12-28 11:11 ` Alexander Lobakin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201227184032.22413-17-alobakin@pm.me \
--to=alobakin@pm.me \
--cc=dalias@aerifal.cx \
--cc=musl@lists.openwall.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).