On Tue, Nov 25, 2025 at 1:17 PM Jonathan Wakely <[email protected]> wrote:
>
> This defines __platform_wait, __platform_notify, and
> __platform_wait_until for darwin, making use of the futex syscall.

small typo there. s/darwin/openbsd/ :).

Thanks,
Andrew

>
> libstdc++-v3/ChangeLog:
>
>         PR libstdc++/120527
>         * include/bits/atomic_wait.h [__OpenBSD__]: Reuse Linux
>         definitions of __platform_wait_t and __platform_wait_uses_type.
>         * src/c++20/atomic.cc [__OpenBSD__] (_GLIBCXX_HAVE_PLATFORM_WAIT)
>         (__platform_wait, __platform_notify, __platform_wait_until):
>         Define.
> ---
>
> Untested, so I don't plan to commit this.
>
>  libstdc++-v3/include/bits/atomic_wait.h |  3 +-
>  libstdc++-v3/src/c++20/atomic.cc        | 40 +++++++++++++++++++++++++
>  2 files changed, 42 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
> b/libstdc++-v3/include/bits/atomic_wait.h
> index af4b2ab46a04..22877ad46755 100644
> --- a/libstdc++-v3/include/bits/atomic_wait.h
> +++ b/libstdc++-v3/include/bits/atomic_wait.h
> @@ -55,7 +55,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>         = is_scalar_v<_Tp> && (sizeof(_Tp) <= sizeof(__UINT64_TYPE__));
>    }
>
> -#if defined _GLIBCXX_HAVE_LINUX_FUTEX || defined __DragonFly__
> +#if defined _GLIBCXX_HAVE_LINUX_FUTEX || defined __DragonFly__ \
> +  || defined __OpenBSD__
>    namespace __detail
>    {
>      // Use futex syscall on int objects.
> diff --git a/libstdc++-v3/src/c++20/atomic.cc 
> b/libstdc++-v3/src/c++20/atomic.cc
> index 87a1e24d8980..a788000fab7b 100644
> --- a/libstdc++-v3/src/c++20/atomic.cc
> +++ b/libstdc++-v3/src/c++20/atomic.cc
> @@ -56,6 +56,10 @@ __ulock_wake(uint32_t operation, void* addr, uint64_t 
> wake_value);
>  #elif defined __DragonFly__
>  # include <unistd.h>
>  # define _GLIBCXX_HAVE_PLATFORM_WAIT 1
> +#elif defined __OpenBSD__
> +# include <sys/time.h>
> +# include <sys/futex.h>
> +# define _GLIBCXX_HAVE_PLATFORM_WAIT 1
>  #endif
>
>  #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
> @@ -242,6 +246,42 @@ namespace
>        }
>      return true;
>    }
> +#elif defined __OpenBSD__
> +  void
> +  __platform_wait(const void* addr, uint64_t val, int /* obj_sz */) noexcept
> +  {
> +    if (futex(static_cast<uint32_t*>(const_cast<void*>(addr)), FUTEX_WAIT,
> +             (int)val, nullptr, nullptr))
> +      if (errno == EAGAIN || errno == EINTR || errno == ECANCELED)
> +       return;
> +    __throw_system_error(errno);
> +  }
> +
> +  void
> +  __platform_notify(const void* addr, bool all, int /* obj_sz */) noexcept
> +  {
> +    futex(static_cast<uint32_t*>(const_cast<void*>(addr)), FUTEX_WAKE,
> +         all ? INT_MAX : 1, nullptr, nullptr);
> +  }
> +
> +  // returns true if wait ended before timeout
> +  bool
> +  __platform_wait_until(const void* addr, uint64_t val,
> +                       const __wait_clock_t::time_point& atime,
> +                       int /* obj_sz */) noexcept
> +  {
> +    struct timespec timeout = chrono::__to_timeout_timespec(atime);
> +    if (futex(static_cast<uint32_t*>(const_cast<void*>(addr)), FUTEX_WAIT,
> +             (int)val, &timeout, nullptr))
> +      {
> +       if (errno == ETIMEDOUT)
> +         return false;
> +       if (errno == EAGAIN || errno == EINTR || errno == ECANCELED)
> +         return true;
> +       __throw_system_error(errno);
> +      }
> +    return true;
> +  }
>  #endif // HAVE_LINUX_FUTEX
>
>    // The state used by atomic waiting and notifying functions.
> --
> 2.51.1
>

Reply via email to