https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120527
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #0) > 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; Oh and also: #define _GLIBCXX_HAVE_PLATFORM_WAIT 1 so that the new definitions would actually get used! > #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