mirror of
https://github.com/darlinghq/darling-libcxx.git
synced 2024-11-23 11:59:52 +00:00
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
This commit is contained in:
parent
080f06df54
commit
c2cb7c6414
@ -188,6 +188,7 @@ template<class Callable, class ...Args>
|
||||
|
||||
#include <__config>
|
||||
#include <__mutex_base>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#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<class _Callable, class... _Args>
|
||||
@ -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<const _Callable> __p(__func);
|
||||
__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user