From c2cb7c641445a3501c92b883f5079293a3ed9706 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 20 Mar 2019 22:55:03 +0000 Subject: [PATCH] libc++/win: Make once_flag have the same size as a pointer. `unsigned long` is 32-bit on 32-bit systems and 64-bit on 64-bit systems on LP64 systems -- which most Unix systems are, but Windows isn't. Windows is LLP64, which means unsigned long is 32-bit even on 64-bit systems. pplwin.h contains static_assert(alignof(void *) == alignof(::std::once_flag), ...) which fails due to this problem. Instead of unsigned long, use uintptr_t, which consistently is 32-bit on 32-bit systems and 64-bit on 64-bit systems. No functional change except on 64-bit Windows. Differential Revision: https://reviews.llvm.org/D59607 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@356624 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/mutex | 19 ++++++++++++++----- src/mutex.cpp | 16 ++++++++-------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/include/mutex b/include/mutex index 98bd581eb..20c3ffc38 100644 --- a/include/mutex +++ b/include/mutex @@ -188,6 +188,7 @@ template #include <__config> #include <__mutex_base> +#include #include #include #ifndef _LIBCPP_CXX03_LANG @@ -575,11 +576,18 @@ struct _LIBCPP_TEMPLATE_VIS once_flag _LIBCPP_CONSTEXPR once_flag() _NOEXCEPT : __state_(0) {} +#if defined(_LIBCPP_ABI_MICROSOFT) + typedef uintptr_t _State_type; +#else + typedef unsigned long _State_type; +#endif + + private: once_flag(const once_flag&); // = delete; once_flag& operator=(const once_flag&); // = delete; - unsigned long __state_; + _State_type __state_; #ifndef _LIBCPP_CXX03_LANG template @@ -649,7 +657,8 @@ __call_once_proxy(void* __vp) (*__p)(); } -_LIBCPP_FUNC_VIS void __call_once(volatile unsigned long&, void*, void(*)(void*)); +_LIBCPP_FUNC_VIS void __call_once(volatile once_flag::_State_type&, void*, + void (*)(void*)); #ifndef _LIBCPP_CXX03_LANG @@ -658,7 +667,7 @@ inline _LIBCPP_INLINE_VISIBILITY void call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) { - if (__libcpp_acquire_load(&__flag.__state_) != ~0ul) + if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) { typedef tuple<_Callable&&, _Args&&...> _Gp; _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); @@ -674,7 +683,7 @@ inline _LIBCPP_INLINE_VISIBILITY void call_once(once_flag& __flag, _Callable& __func) { - if (__libcpp_acquire_load(&__flag.__state_) != ~0ul) + if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) { __call_once_param<_Callable> __p(__func); __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); @@ -686,7 +695,7 @@ inline _LIBCPP_INLINE_VISIBILITY void call_once(once_flag& __flag, const _Callable& __func) { - if (__libcpp_acquire_load(&__flag.__state_) != ~0ul) + if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) { __call_once_param __p(__func); __call_once(__flag.__state_, &__p, &__call_once_proxy); diff --git a/src/mutex.cpp b/src/mutex.cpp index a9ccc9aa9..6bb44e055 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -197,8 +197,8 @@ _LIBCPP_SAFE_STATIC static __libcpp_mutex_t mut = _LIBCPP_MUTEX_INITIALIZER; _LIBCPP_SAFE_STATIC static __libcpp_condvar_t cv = _LIBCPP_CONDVAR_INITIALIZER; #endif -void -__call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) +void __call_once(volatile once_flag::_State_type& flag, void* arg, + void (*func)(void*)) { #if defined(_LIBCPP_HAS_NO_THREADS) if (flag == 0) @@ -209,12 +209,12 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) #endif // _LIBCPP_NO_EXCEPTIONS flag = 1; func(arg); - flag = ~0ul; + flag = ~once_flag::_State_type(0); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - flag = 0ul; + flag = 0; throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -229,11 +229,12 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) try { #endif // _LIBCPP_NO_EXCEPTIONS - __libcpp_relaxed_store(&flag, 1ul); + __libcpp_relaxed_store(&flag, once_flag::_State_type(1)); __libcpp_mutex_unlock(&mut); func(arg); __libcpp_mutex_lock(&mut); - __libcpp_atomic_store(&flag, ~0ul, _AO_Release); + __libcpp_atomic_store(&flag, ~once_flag::_State_type(0), + _AO_Release); __libcpp_mutex_unlock(&mut); __libcpp_condvar_broadcast(&cv); #ifndef _LIBCPP_NO_EXCEPTIONS @@ -241,7 +242,7 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) catch (...) { __libcpp_mutex_lock(&mut); - __libcpp_relaxed_store(&flag, 0ul); + __libcpp_relaxed_store(&flag, once_flag::_State_type(0)); __libcpp_mutex_unlock(&mut); __libcpp_condvar_broadcast(&cv); throw; @@ -251,7 +252,6 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) else __libcpp_mutex_unlock(&mut); #endif // !_LIBCPP_HAS_NO_THREADS - } _LIBCPP_END_NAMESPACE_STD