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.