diff options
Diffstat (limited to 'libc/private/bionic_futex.h')
| -rw-r--r-- | libc/private/bionic_futex.h | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/libc/private/bionic_futex.h b/libc/private/bionic_futex.h index 11699ce..dd277ed 100644 --- a/libc/private/bionic_futex.h +++ b/libc/private/bionic_futex.h @@ -28,31 +28,42 @@ #ifndef _BIONIC_FUTEX_H #define _BIONIC_FUTEX_H +#include <errno.h> #include <linux/futex.h> -#include <sys/cdefs.h> #include <stdbool.h> #include <stddef.h> +#include <sys/cdefs.h> +#include <sys/syscall.h> __BEGIN_DECLS struct timespec; -extern int __futex_syscall4(volatile void* ftx, int op, int value, const struct timespec* timeout); +static inline int __futex(volatile void* ftx, int op, int value, const struct timespec* timeout) { + // Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to. + int saved_errno = errno; + if (syscall(__NR_futex, ftx, op, value, timeout) == 0) { + return 0; + } + int result = -errno; + errno = saved_errno; + return result; +} static inline int __futex_wake(volatile void* ftx, int count) { - return __futex_syscall4(ftx, FUTEX_WAKE, count, NULL); + return __futex(ftx, FUTEX_WAKE, count, NULL); } static inline int __futex_wake_ex(volatile void* ftx, bool shared, int count) { - return __futex_syscall4(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL); + return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL); } static inline int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) { - return __futex_syscall4(ftx, FUTEX_WAIT, value, timeout); + return __futex(ftx, FUTEX_WAIT, value, timeout); } static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value, const struct timespec* timeout) { - return __futex_syscall4(ftx, shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, value, timeout); + return __futex(ftx, shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, value, timeout); } __END_DECLS |
