On 19/04/21 12:23 -0700, Thomas Rodgers wrote:
  namespace __detail
  {
-    using __platform_wait_t = int;
-
-    constexpr auto __atomic_spin_count_1 = 16;
-    constexpr auto __atomic_spin_count_2 = 12;
-
-    template<typename _Tp>
-      inline constexpr bool __platform_wait_uses_type
#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
-       = is_same_v<remove_cv_t<_Tp>, __platform_wait_t>;
+    using __platform_wait_t = int;
#else
-       = false;
+    using __platform_wait_t = uint64_t;
+#endif
+    static constexpr size_t __platform_wait_alignment
+                                     = alignof(__platform_wait_t);

The value of this constant can't be alignof(__platform_wait_t). As
discussed, a futex always needs 4-byte alignment, but on at least one
target that GCC supports, alignof(int) == 2.

+  } // namespace __detail
+
+  template<typename _Tp>
+    inline constexpr bool __platform_wait_uses_type
+#ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
+      = is_scalar_v<_Tp>
+       && ((sizeof(_Tp) == sizeof(__detail::__platform_wait_t))
+       && (alignof(_Tp*) >= alignof(__detail::__platform_wait_t)));

Now that we have the __platform_wait_alignment it should be used here
(so that when we fix the constant, this gets fixed too).

+#else
+      = false;
#endif

+  namespace __detail
+  {
#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
+#define _GLIBCXX_HAVE_PLATFORM_WAIT 1
    enum class __futex_wait_flags : int
    {
#ifdef _GLIBCXX_HAVE_LINUX_FUTEX_PRIVATE




+
+         static __waiter_type&
+         _S_for(const void* __addr)
+         {
+           static_assert(sizeof(__waiter_type) == sizeof(__waiter_pool_base));
+           auto& res = __waiter_pool_base::_S_for(__addr);
+           return reinterpret_cast<__waiter_type&>(res);
+         }

Nit: this is still indented as if it were a function template.

      : _M_a(__expected) { }
@@ -73,8 +73,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    _GLIBCXX_ALWAYS_INLINE void
    wait() const noexcept
    {
-      auto const __old = __atomic_impl::load(&_M_a, memory_order::acquire);
-      std::__atomic_wait(&_M_a, __old, [this] { return this->try_wait(); });
+      auto const __pred = [this] { return this->try_wait(); };
+      std::__atomic_wait_address(&_M_a, __pred);
    }

    _GLIBCXX_ALWAYS_INLINE void
@@ -85,7 +85,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    }

  private:
-    alignas(__alignof__(ptrdiff_t)) ptrdiff_t _M_a;
+    alignas(__alignof__(__detail::__platform_wait_t)) 
__detail::__platform_wait_t _M_a;

This should use the new constant too.



Reply via email to