[PATCH 1/2] perf bench futex: Use a 64-bit time_t
Alistair Francis
alistair.francis at opensource.wdc.com
Wed Oct 13 22:55:26 PDT 2021
From: Alistair Francis <alistair.francis at wdc.com>
Convert tools/perf to only use a 64-bit time_t. On 64-bit architectures
this isn't a functional change. On 32-bit architectures we now only
perform 64-bit time_t syscalls (__NR_futex_time64) and use a struct
timespec64.
This won't work on kernels before 5.1, but as perf is tied to the kernel
that's ok.
This allows us to build perf for 32-bit architectures with 64-bit time_t
like RISC-V 32-bit.
Signed-off-by: Alistair Francis <alistair.francis at wdc.com>
---
tools/perf/bench/futex.h | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/tools/perf/bench/futex.h b/tools/perf/bench/futex.h
index b3853aac3021c..c1ca75657c32e 100644
--- a/tools/perf/bench/futex.h
+++ b/tools/perf/bench/futex.h
@@ -27,12 +27,17 @@ struct bench_futex_parameters {
unsigned int nrequeue;
};
+struct timespec64 {
+ long long tv_sec; /* seconds */
+ long long tv_nsec; /* nanoseconds */
+};
+
/**
* futex() - SYS_futex syscall wrapper
* @uaddr: address of first futex
* @op: futex op code
* @val: typically expected value of uaddr, but varies by op
- * @timeout: typically an absolute struct timespec (except where noted
+ * @timeout: typically an absolute struct timespec64 (except where noted
* otherwise). Overloaded by some ops
* @uaddr2: address of second futex for some ops
* @val3: varies by op
@@ -47,15 +52,26 @@ struct bench_futex_parameters {
* These argument descriptions are the defaults for all
* like-named arguments in the following wrappers except where noted below.
*/
-#define futex(uaddr, op, val, timeout, uaddr2, val3, opflags) \
- syscall(SYS_futex, uaddr, op | opflags, val, timeout, uaddr2, val3)
+/**
+ * We only support 64-bit time_t for the timeout.
+ * On 64-bit architectures we can use __NR_futex
+ * On 32-bit architectures we use __NR_futex_time64. This only works on kernel
+ * versions 5.1+.
+ */
+#if __BITS_PER_LONG == 64 || defined(__i386__)
+# define futex(uaddr, op, val, timeout, uaddr2, val3, opflags) \
+ syscall(__NR_futex, uaddr, op | opflags, val, timeout, uaddr2, val3)
+#else
+# define futex(uaddr, op, val, timeout, uaddr2, val3, opflags) \
+ syscall(__NR_futex_time64, uaddr, op | opflags, val, timeout, uaddr2, val3)
+#endif
/**
* futex_wait() - block on uaddr with optional timeout
* @timeout: relative timeout
*/
static inline int
-futex_wait(u_int32_t *uaddr, u_int32_t val, struct timespec *timeout, int opflags)
+futex_wait(u_int32_t *uaddr, u_int32_t val, struct timespec64 *timeout, int opflags)
{
return futex(uaddr, FUTEX_WAIT, val, timeout, NULL, 0, opflags);
}
@@ -74,7 +90,7 @@ futex_wake(u_int32_t *uaddr, int nr_wake, int opflags)
* futex_lock_pi() - block on uaddr as a PI mutex
*/
static inline int
-futex_lock_pi(u_int32_t *uaddr, struct timespec *timeout, int opflags)
+futex_lock_pi(u_int32_t *uaddr, struct timespec64 *timeout, int opflags)
{
return futex(uaddr, FUTEX_LOCK_PI, 0, timeout, NULL, 0, opflags);
}
@@ -111,7 +127,7 @@ futex_cmp_requeue(u_int32_t *uaddr, u_int32_t val, u_int32_t *uaddr2, int nr_wak
*/
static inline int
futex_wait_requeue_pi(u_int32_t *uaddr, u_int32_t val, u_int32_t *uaddr2,
- struct timespec *timeout, int opflags)
+ struct timespec64 *timeout, int opflags)
{
return futex(uaddr, FUTEX_WAIT_REQUEUE_PI, val, timeout, uaddr2, 0,
opflags);
--
2.31.1
More information about the linux-riscv
mailing list