[macOS] Use native os_sync calls for futexes
This commit is contained in:
@@ -17,6 +17,8 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#elif __APPLE__
|
||||||
|
#include <os/os_sync_wait_on_address.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -76,6 +78,46 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t
|
|||||||
{
|
{
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
return syscall(SYS_futex, uaddr, futex_op, static_cast<int>(val), timeout, nullptr, static_cast<int>(mask));
|
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
|
#else
|
||||||
static struct futex_manager
|
static struct futex_manager
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user