1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Futex2 library addons for futex tests 4 * 5 * Copyright 2021 Collabora Ltd. 6 */ 7 #include <linux/time_types.h> 8 #include <stdint.h> 9 10 #define u64_to_ptr(x) ((void *)(uintptr_t)(x)) 11 12 #ifndef __NR_futex_waitv 13 #define __NR_futex_waitv 449 14 struct futex_waitv { 15 __u64 val; 16 __u64 uaddr; 17 __u32 flags; 18 __u32 __reserved; 19 }; 20 #endif 21 22 #ifndef __NR_futex_wake 23 #define __NR_futex_wake 454 24 #endif 25 26 #ifndef __NR_futex_wait 27 #define __NR_futex_wait 455 28 #endif 29 30 #ifndef FUTEX2_SIZE_U32 31 #define FUTEX2_SIZE_U32 0x02 32 #endif 33 34 #ifndef FUTEX2_NUMA 35 #define FUTEX2_NUMA 0x04 36 #endif 37 38 #ifndef FUTEX2_MPOL 39 #define FUTEX2_MPOL 0x08 40 #endif 41 42 #ifndef FUTEX2_PRIVATE 43 #define FUTEX2_PRIVATE FUTEX_PRIVATE_FLAG 44 #endif 45 46 #ifndef FUTEX2_NO_NODE 47 #define FUTEX_NO_NODE (-1) 48 #endif 49 50 #ifndef FUTEX_32 51 #define FUTEX_32 FUTEX2_SIZE_U32 52 #endif 53 54 struct futex32_numa { 55 futex_t futex; 56 futex_t numa; 57 }; 58 59 /** 60 * futex_waitv - Wait at multiple futexes, wake on any 61 * @waiters: Array of waiters 62 * @nr_waiters: Length of waiters array 63 * @flags: Operation flags 64 * @timo: Optional timeout for operation 65 */ 66 static inline int futex_waitv(volatile struct futex_waitv *waiters, unsigned long nr_waiters, 67 unsigned long flags, struct timespec *timo, clockid_t clockid) 68 { 69 struct __kernel_timespec ts = { 70 .tv_sec = timo->tv_sec, 71 .tv_nsec = timo->tv_nsec, 72 }; 73 74 return syscall(__NR_futex_waitv, waiters, nr_waiters, flags, &ts, clockid); 75 } 76 77 /* 78 * futex_wait() - block on uaddr with optional timeout 79 * @val: Expected value 80 * @flags: FUTEX2 flags 81 * @timeout: Relative timeout 82 * @clockid: Clock id for the timeout 83 */ 84 static inline int futex2_wait(void *uaddr, long val, unsigned int flags, 85 struct timespec *timeout, clockid_t clockid) 86 { 87 return syscall(__NR_futex_wait, uaddr, val, ~0U, flags, timeout, clockid); 88 } 89 90 /* 91 * futex2_wake() - Wake a number of futexes 92 * @nr: Number of threads to wake at most 93 * @flags: FUTEX2 flags 94 */ 95 static inline int futex2_wake(void *uaddr, int nr, unsigned int flags) 96 { 97 return syscall(__NR_futex_wake, uaddr, ~0U, nr, flags); 98 } 99