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

Reply via email to