[*] Linux: optimize futex wrappers

This commit is contained in:
Reece Wilson 2023-08-18 22:51:47 +01:00
parent 836edbabdd
commit ad5bbee6b2
3 changed files with 54 additions and 32 deletions

View File

@ -49,34 +49,24 @@ namespace Aurora
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3); 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) 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) 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) if (timeout)
{ {
@ -89,10 +79,37 @@ namespace Aurora
} }
int futex_wake(uint32_t *addr, uint32_t nthreads) 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); 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) int io_setup(unsigned nr, aio_context_t *ctxp)
{ {
return syscall(__NR_io_setup, nr, ctxp); return syscall(__NR_io_setup, nr, ctxp);

View File

@ -24,13 +24,6 @@ namespace Aurora
long set_robust_list(struct robust_list_head *head, size_t len); 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_wake(uint32_t *addr, uint32_t nthreads);
int futex_wait(uint32_t *addr, uint32_t expected, 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_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_submit(aio_context_t ctx, long nr, struct iocb **iocbpp);
int io_cancel(aio_context_t ctx_id, struct iocb *iocb, int io_cancel(aio_context_t ctx_id, struct iocb *iocb,

View File

@ -322,7 +322,7 @@ static bool LinuxLockFutex(AuUInt32 *futex, AuUInt32 timeout)
bContended = old != kFutexValueUnlocked; bContended = old != kFutexValueUnlocked;
if (bContended) 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 < 0)
{ {
if (res == ETIMEDOUT || errno == ETIMEDOUT) if (res == ETIMEDOUT || errno == ETIMEDOUT)
@ -375,7 +375,7 @@ static bool LinuxUnlockFutex(AuUInt32 *futex)
return false; return false;
} }
Aurora::futex_wake(futex, 1); Aurora::futex_wake_shared(futex, 1);
return true; return true;
} }