diff --git a/src/mutex.cpp b/src/mutex.cpp index b165b1b..e8637f9 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -12,7 +12,9 @@ #include #include +#if !defined(_LIBCPP_ABI_MICROSOFT) #include "include/atomic_support.h" +#endif #ifndef _LIBCPP_HAS_NO_THREADS # if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB) @@ -202,8 +204,13 @@ static constinit __libcpp_mutex_t mut = _LIBCPP_MUTEX_INITIALIZER; static constinit __libcpp_condvar_t cv = _LIBCPP_CONDVAR_INITIALIZER; #endif +#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) @@ -223,16 +230,28 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg, 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();