https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120527
Bug ID: 120527 Summary: Native platform wait on darwin Product: gcc Version: 16.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org CC: iains at gcc dot gnu.org Target Milestone: --- Target: *-*-darwin* Darwin provides __ulock_wait and __ulock_wake which should be sufficient to implement the internals needed for efficient std::atomic::wait and std::atomic::notify. Unfortunately these aren't documented and are not really public. Libc++ uses them based on this version check: #if defined(__APPLE__) # if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) # if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500 # define _LIBCPP_USE_ULOCK # endif With these manual declarations (because there's no header that declares them): extern "C" int __ulock_wait( uint32_t operation, void* addr, uint64_t value, uint32_t timeout); /* timeout is specified in microseconds */ extern "C" int __ulock_wake(uint32_t operation, void* addr, uint64_t wake_value); // https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/ulock.h#L82 # define UL_COMPARE_AND_WAIT64 5 # define ULF_WAKE_ALL 0x00000100 So we would want something like: --- a/libstdc++-v3/include/bits/atomic_wait.h +++ b/libstdc++-v3/include/bits/atomic_wait.h @@ -51,6 +51,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define _GLIBCXX_HAVE_PLATFORM_WAIT 1 using __platform_wait_t = int; inline constexpr size_t __platform_wait_alignment = 4; +#elif defined _GLIBCXX_HAVE_DARWIN_ULOCK + using __platform_wait_t = uint64_t; + inline constexpr size_t __platform_wait_alignment = 8; #else // define _GLIBCX_HAVE_PLATFORM_WAIT and implement __platform_wait() // and __platform_notify() if there is a more efficient primitive supported and: --- a/libstdc++-v3/src/c++20/atomic.cc +++ b/libstdc++-v3/src/c++20/atomic.cc @@ -95,6 +95,8 @@ namespace static_cast<int>(__futex_wait_flags::__wake_private), __all ? INT_MAX : 1); } +#elif defined _GLIBCXX_HAVE_DARWIN_ULOCK + // TODO define __platform_wait and __platform_notify #endif // The state used by atomic waiting and notifying functions. @@ -371,6 +373,8 @@ __platform_wait_until(const __platform_wait_t* __addr, } return true; } +#elif defined _GLIBCXX_HAVE_DARWIN_ULOCK + // TODO define __platform_wait_until #endif // HAVE_LINUX_FUTEX #ifndef _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT