diff --git a/src/call_once.cpp b/src/call_once.cpp index 5744347..2b981b6 100644 --- a/src/call_once.cpp +++ b/src/call_once.cpp @@ -28,7 +28,12 @@ static constinit __libcpp_mutex_t mut = _LIBCPP_MUTEX_INITIALIZER; static constinit __libcpp_condvar_t cv = _LIBCPP_CONDVAR_INITIALIZER; #endif -void __call_once(volatile once_flag::_State_type& flag, void* arg, void (*func)(void*)) { +#ifdef _LIBCPP_ABI_MICROSOFT +void __call_once(volatile std::atomic& flag, void* arg, void (*func)(void*)) +#else +void __call_once(volatile once_flag::_State_type& flag, void* arg, void (*func)(void*)) +#endif +{ #if defined(_LIBCPP_HAS_NO_THREADS) if (flag == once_flag::_Unset) { @@ -47,16 +52,28 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg, void (*func)( if (flag == once_flag::_Unset) { auto guard = std::__make_exception_guard([&flag] { __libcpp_mutex_lock(&mut); +# ifdef _LIBCPP_ABI_MICROSOFT + flag.store(once_flag::_Unset); +# else __libcpp_relaxed_store(&flag, once_flag::_Unset); +# endif __libcpp_mutex_unlock(&mut); __libcpp_condvar_broadcast(&cv); }); +# ifdef _LIBCPP_ABI_MICROSOFT + flag.store(once_flag::_Pending, memory_order_relaxed); +# else __libcpp_relaxed_store(&flag, once_flag::_Pending); +# endif __libcpp_mutex_unlock(&mut); func(arg); __libcpp_mutex_lock(&mut); +# ifdef _LIBCPP_ABI_MICROSOFT + flag.store(once_flag::_Complete, memory_order_release); +# else __libcpp_atomic_store(&flag, once_flag::_Complete, _AO_Release); +# endif __libcpp_mutex_unlock(&mut); __libcpp_condvar_broadcast(&cv); guard.__complete(); diff --git a/src/mutex.cpp b/src/mutex.cpp index 2f8504d..26b26b6 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -12,7 +12,9 @@ #include #include -#include "include/atomic_support.h" +#if !defined(_LIBCPP_ABI_MICROSOFT) +# include "include/atomic_support.h" +#endif #if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB) # pragma comment(lib, "pthread")