Skip to content

Commit 0fd00a5

Browse files
committed
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 llvm-svn: 356624
1 parent ce3d670 commit 0fd00a5

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

libcxx/include/mutex

+14-5
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ template<class Callable, class ...Args>
188188

189189
#include <__config>
190190
#include <__mutex_base>
191+
#include <cstdint>
191192
#include <functional>
192193
#include <memory>
193194
#ifndef _LIBCPP_CXX03_LANG
@@ -575,11 +576,18 @@ struct _LIBCPP_TEMPLATE_VIS once_flag
575576
_LIBCPP_CONSTEXPR
576577
once_flag() _NOEXCEPT : __state_(0) {}
577578

579+
#if defined(_LIBCPP_ABI_MICROSOFT)
580+
typedef uintptr_t _State_type;
581+
#else
582+
typedef unsigned long _State_type;
583+
#endif
584+
585+
578586
private:
579587
once_flag(const once_flag&); // = delete;
580588
once_flag& operator=(const once_flag&); // = delete;
581589

582-
unsigned long __state_;
590+
_State_type __state_;
583591

584592
#ifndef _LIBCPP_CXX03_LANG
585593
template<class _Callable, class... _Args>
@@ -649,7 +657,8 @@ __call_once_proxy(void* __vp)
649657
(*__p)();
650658
}
651659

652-
_LIBCPP_FUNC_VIS void __call_once(volatile unsigned long&, void*, void(*)(void*));
660+
_LIBCPP_FUNC_VIS void __call_once(volatile once_flag::_State_type&, void*,
661+
void (*)(void*));
653662

654663
#ifndef _LIBCPP_CXX03_LANG
655664

@@ -658,7 +667,7 @@ inline _LIBCPP_INLINE_VISIBILITY
658667
void
659668
call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
660669
{
661-
if (__libcpp_acquire_load(&__flag.__state_) != ~0ul)
670+
if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0))
662671
{
663672
typedef tuple<_Callable&&, _Args&&...> _Gp;
664673
_Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...);
@@ -674,7 +683,7 @@ inline _LIBCPP_INLINE_VISIBILITY
674683
void
675684
call_once(once_flag& __flag, _Callable& __func)
676685
{
677-
if (__libcpp_acquire_load(&__flag.__state_) != ~0ul)
686+
if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0))
678687
{
679688
__call_once_param<_Callable> __p(__func);
680689
__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);
@@ -686,7 +695,7 @@ inline _LIBCPP_INLINE_VISIBILITY
686695
void
687696
call_once(once_flag& __flag, const _Callable& __func)
688697
{
689-
if (__libcpp_acquire_load(&__flag.__state_) != ~0ul)
698+
if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0))
690699
{
691700
__call_once_param<const _Callable> __p(__func);
692701
__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);

libcxx/src/mutex.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ _LIBCPP_SAFE_STATIC static __libcpp_mutex_t mut = _LIBCPP_MUTEX_INITIALIZER;
197197
_LIBCPP_SAFE_STATIC static __libcpp_condvar_t cv = _LIBCPP_CONDVAR_INITIALIZER;
198198
#endif
199199

200-
void
201-
__call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
200+
void __call_once(volatile once_flag::_State_type& flag, void* arg,
201+
void (*func)(void*))
202202
{
203203
#if defined(_LIBCPP_HAS_NO_THREADS)
204204
if (flag == 0)
@@ -209,12 +209,12 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
209209
#endif // _LIBCPP_NO_EXCEPTIONS
210210
flag = 1;
211211
func(arg);
212-
flag = ~0ul;
212+
flag = ~once_flag::_State_type(0);
213213
#ifndef _LIBCPP_NO_EXCEPTIONS
214214
}
215215
catch (...)
216216
{
217-
flag = 0ul;
217+
flag = 0;
218218
throw;
219219
}
220220
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -229,19 +229,20 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
229229
try
230230
{
231231
#endif // _LIBCPP_NO_EXCEPTIONS
232-
__libcpp_relaxed_store(&flag, 1ul);
232+
__libcpp_relaxed_store(&flag, once_flag::_State_type(1));
233233
__libcpp_mutex_unlock(&mut);
234234
func(arg);
235235
__libcpp_mutex_lock(&mut);
236-
__libcpp_atomic_store(&flag, ~0ul, _AO_Release);
236+
__libcpp_atomic_store(&flag, ~once_flag::_State_type(0),
237+
_AO_Release);
237238
__libcpp_mutex_unlock(&mut);
238239
__libcpp_condvar_broadcast(&cv);
239240
#ifndef _LIBCPP_NO_EXCEPTIONS
240241
}
241242
catch (...)
242243
{
243244
__libcpp_mutex_lock(&mut);
244-
__libcpp_relaxed_store(&flag, 0ul);
245+
__libcpp_relaxed_store(&flag, once_flag::_State_type(0));
245246
__libcpp_mutex_unlock(&mut);
246247
__libcpp_condvar_broadcast(&cv);
247248
throw;
@@ -251,7 +252,6 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
251252
else
252253
__libcpp_mutex_unlock(&mut);
253254
#endif // !_LIBCPP_HAS_NO_THREADS
254-
255255
}
256256

257257
_LIBCPP_END_NAMESPACE_STD

0 commit comments

Comments
 (0)