mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
ntdll: Implement futex_wait() and futex_wake_one() on macOS.
This commit is contained in:
parent
410790a4f3
commit
2fb62cf9a5
Notes:
Alexandre Julliard
2024-07-10 23:39:27 +02:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/wine/-/merge_requests/5237
2 changed files with 66 additions and 2 deletions
|
@ -46,7 +46,7 @@ To compile and run Wine, you must have one of the following:
|
|||
- FreeBSD 12.4 or later
|
||||
- Solaris x86 9 or later
|
||||
- NetBSD-current
|
||||
- Mac OS X 10.8 or later
|
||||
- Mac OS X 10.12 or later
|
||||
|
||||
As Wine requires kernel-level thread support to run, only the operating
|
||||
systems mentioned above are supported. Other operating systems which
|
||||
|
|
|
@ -130,7 +130,71 @@ static inline int futex_wake_one( const LONG *addr )
|
|||
return syscall( __NR_futex, addr, FUTEX_WAKE_PRIVATE, 1, NULL, 0, 0 );
|
||||
}
|
||||
|
||||
#endif /* __linux__ */
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#define USE_FUTEX
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#ifdef MAC_OS_VERSION_14_4
|
||||
#include <os/os_sync_wait_on_address.h>
|
||||
#endif
|
||||
|
||||
#define UL_COMPARE_AND_WAIT 1
|
||||
|
||||
extern int __ulock_wait( uint32_t operation, void *addr, uint64_t value, uint32_t timeout );
|
||||
|
||||
extern int __ulock_wake( uint32_t operation, void *addr, uint64_t wake_value );
|
||||
|
||||
static inline int futex_wait( const LONG *addr, int val, struct timespec *timeout )
|
||||
{
|
||||
#ifdef MAC_OS_VERSION_14_4
|
||||
if (__builtin_available( macOS 14.4, * ))
|
||||
{
|
||||
/* 18446744073 seconds could overflow a uint64_t in nanoseconds */
|
||||
if (timeout && timeout->tv_sec < 18446744073)
|
||||
{
|
||||
uint64_t ns_timeout = (timeout->tv_sec * 1000000000) + timeout->tv_nsec;
|
||||
|
||||
if (!ns_timeout)
|
||||
{
|
||||
errno = ETIMEDOUT;
|
||||
return -1;
|
||||
}
|
||||
return os_sync_wait_on_address_with_timeout( (void *)addr, (uint64_t)val, 4, OS_SYNC_WAIT_ON_ADDRESS_NONE,
|
||||
OS_CLOCK_MACH_ABSOLUTE_TIME, ns_timeout );
|
||||
}
|
||||
|
||||
return os_sync_wait_on_address( (void *)addr, (uint64_t)val, 4, OS_SYNC_WAIT_ON_ADDRESS_NONE );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 4294 seconds could overflow a uint32_t in microseconds */
|
||||
if (timeout && timeout->tv_sec < 4294)
|
||||
{
|
||||
uint32_t us_timeout = ((uint32_t)timeout->tv_sec * 1000000) + ((uint32_t)timeout->tv_nsec / 1000);
|
||||
|
||||
if (!us_timeout)
|
||||
{
|
||||
errno = ETIMEDOUT;
|
||||
return -1;
|
||||
}
|
||||
return __ulock_wait( UL_COMPARE_AND_WAIT, (void *)addr, (uint64_t)val, us_timeout );
|
||||
}
|
||||
|
||||
return __ulock_wait( UL_COMPARE_AND_WAIT, (void *)addr, (uint64_t)val, 0 );
|
||||
}
|
||||
|
||||
static inline int futex_wake_one( const LONG *addr )
|
||||
{
|
||||
#ifdef MAC_OS_VERSION_14_4
|
||||
if (__builtin_available( macOS 14.4, * ))
|
||||
return os_sync_wake_by_address_any( (void *)addr, 4, OS_SYNC_WAKE_BY_ADDRESS_NONE );
|
||||
#endif
|
||||
return __ulock_wake( UL_COMPARE_AND_WAIT, (void *)addr, 0 );
|
||||
}
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
/* create a struct security_descriptor and contained information in one contiguous piece of memory */
|
||||
unsigned int alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,
|
||||
|
|
Loading…
Reference in a new issue