From ad5bbee6b2c63c0718263f3929180f93b646d77c Mon Sep 17 00:00:00 2001 From: J Reece Wilson Date: Fri, 18 Aug 2023 22:51:47 +0100 Subject: [PATCH] [*] Linux: optimize futex wrappers --- Source/AuProcAddresses.Linux.cpp | 63 ++++++++++++++++--------- Source/AuProcAddresses.Linux.hpp | 19 +++++--- Source/IO/IPC/AuIPCMutexFutex.Linux.cpp | 4 +- 3 files changed, 54 insertions(+), 32 deletions(-) diff --git a/Source/AuProcAddresses.Linux.cpp b/Source/AuProcAddresses.Linux.cpp index ef17f951..a2e0a969 100644 --- a/Source/AuProcAddresses.Linux.cpp +++ b/Source/AuProcAddresses.Linux.cpp @@ -49,34 +49,24 @@ namespace Aurora return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3); } - int futex_wait(volatile uint32_t *addr, uint32_t expected) - { - return futex((uint32_t *)addr, FUTEX_WAIT, expected, 0, 0, 0); - } - - int futex_wait(volatile uint32_t *addr, uint32_t expected, const struct timespec *timeout) - { - if (timeout) - { - return futex((uint32_t *)addr, FUTEX_WAIT_BITSET, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY); - } - else - { - return futex((uint32_t *)addr, FUTEX_WAIT, expected, timeout, 0, 0); - } - } - - int futex_wake(volatile uint32_t *addr, uint32_t nthreads) - { - return futex((uint32_t *)addr, FUTEX_WAKE, nthreads, 0, 0, 0); - } - int futex_wait(uint32_t *addr, uint32_t expected) { - return futex(addr, FUTEX_WAIT, expected, 0, 0, 0); + return futex(addr, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, expected, 0, 0, 0); } int futex_wait(uint32_t *addr, uint32_t expected, const struct timespec *timeout) + { + if (timeout) + { + return futex(addr, FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY); + } + else + { + return futex(addr, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, expected, timeout, 0, 0); + } + } + + int futex_wait_shared(uint32_t *addr, uint32_t expected, const struct timespec *timeout) { if (timeout) { @@ -89,10 +79,37 @@ namespace Aurora } int futex_wake(uint32_t *addr, uint32_t nthreads) + { + return futex(addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, nthreads, 0, 0, 0); + } + + int futex_wake_shared(uint32_t *addr, uint32_t nthreads) { return futex(addr, FUTEX_WAKE, nthreads, 0, 0, 0); } + int futex_wait(volatile uint32_t *addr, uint32_t expected) + { + return futex((uint32_t *)addr, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, expected, 0, 0, 0); + } + + int futex_wait(volatile uint32_t *addr, uint32_t expected, const struct timespec *timeout) + { + if (timeout) + { + return futex((uint32_t *)addr, FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG, expected, timeout, 0, FUTEX_BITSET_MATCH_ANY); + } + else + { + return futex((uint32_t *)addr, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, expected, timeout, 0, 0); + } + } + + int futex_wake(volatile uint32_t *addr, uint32_t nthreads) + { + return futex((uint32_t *)addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, nthreads, 0, 0, 0); + } + int io_setup(unsigned nr, aio_context_t *ctxp) { return syscall(__NR_io_setup, nr, ctxp); diff --git a/Source/AuProcAddresses.Linux.hpp b/Source/AuProcAddresses.Linux.hpp index e47f6ffa..420571db 100644 --- a/Source/AuProcAddresses.Linux.hpp +++ b/Source/AuProcAddresses.Linux.hpp @@ -24,13 +24,6 @@ namespace Aurora long set_robust_list(struct robust_list_head *head, size_t len); - int futex_wake(volatile uint32_t *addr, uint32_t nthreads); - - int futex_wait(volatile uint32_t *addr, uint32_t expected, - const struct timespec *timeout); - - int futex_wait(volatile uint32_t *addr, uint32_t expected); - int futex_wake(uint32_t *addr, uint32_t nthreads); int futex_wait(uint32_t *addr, uint32_t expected, @@ -38,6 +31,18 @@ namespace Aurora int futex_wait(uint32_t *addr, uint32_t expected); + int futex_wake_shared(uint32_t *addr, uint32_t nthreads); + + int futex_wait_shared(uint32_t *addr, uint32_t expected, + const struct timespec *timeout); + + int futex_wake(volatile uint32_t *addr, uint32_t nthreads); + + int futex_wait(volatile uint32_t *addr, uint32_t expected, + const struct timespec *timeout); + + int futex_wait(volatile uint32_t *addr, uint32_t expected); + int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp); int io_cancel(aio_context_t ctx_id, struct iocb *iocb, diff --git a/Source/IO/IPC/AuIPCMutexFutex.Linux.cpp b/Source/IO/IPC/AuIPCMutexFutex.Linux.cpp index 69aac763..0be2a5ce 100644 --- a/Source/IO/IPC/AuIPCMutexFutex.Linux.cpp +++ b/Source/IO/IPC/AuIPCMutexFutex.Linux.cpp @@ -322,7 +322,7 @@ static bool LinuxLockFutex(AuUInt32 *futex, AuUInt32 timeout) bContended = old != kFutexValueUnlocked; if (bContended) { - int res = Aurora::futex_wait(futex, old, timeout ? &tspec : nullptr); + int res = Aurora::futex_wait_shared(futex, old, timeout ? &tspec : nullptr); if (res < 0) { if (res == ETIMEDOUT || errno == ETIMEDOUT) @@ -375,7 +375,7 @@ static bool LinuxUnlockFutex(AuUInt32 *futex) return false; } - Aurora::futex_wake(futex, 1); + Aurora::futex_wake_shared(futex, 1); return true; }