[macOS] Use native os_sync calls for futexes

This commit is contained in:
schm1dtmac 2025-12-17 18:10:48 +00:00 committed by Elad
parent ddfa773675
commit 5507078bd8

View file

@ -17,6 +17,8 @@
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#elif __APPLE__
#include <os/os_sync_wait_on_address.h>
#endif
#ifdef _WIN32
@ -76,6 +78,46 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t
{
#ifdef __linux__
return syscall(SYS_futex, uaddr, futex_op, static_cast<int>(val), timeout, nullptr, static_cast<int>(mask));
#elif __APPLE__
switch (futex_op)
{
case FUTEX_WAIT_PRIVATE:
case FUTEX_WAIT_BITSET_PRIVATE:
{
if (timeout)
{
const uint64_t nsec = timeout->tv_nsec + timeout->tv_sec * 1000000000ull;
return os_sync_wait_on_address_with_timeout(const_cast<void*>(uaddr), static_cast<uint64_t>(val), sizeof(uint), OS_SYNC_WAIT_ON_ADDRESS_NONE, OS_CLOCK_MACH_ABSOLUTE_TIME, nsec);
}
else
{
return os_sync_wait_on_address(const_cast<void*>(uaddr), static_cast<uint64_t>(val), sizeof(uint), OS_SYNC_WAIT_ON_ADDRESS_NONE);
}
}
case FUTEX_WAKE_PRIVATE:
case FUTEX_WAKE_BITSET_PRIVATE:
{
for (;;)
{
int ret = 0;
if (val == INT32_MAX)
{
ret = os_sync_wake_by_address_all(const_cast<void*>(uaddr), sizeof(uint), OS_SYNC_WAKE_BY_ADDRESS_NONE);
}
else if (val-- >= 0)
{
ret = os_sync_wake_by_address_any(const_cast<void*>(uaddr), sizeof(uint), OS_SYNC_WAKE_BY_ADDRESS_NONE);
}
if (val <= 0 || val == INT32_MAX || (ret < 0 && errno == ENOENT))
{
return ret;
}
}
}
}
errno = EINVAL;
return -1;
#else
static struct futex_manager
{