37-mutex.patch 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. diff --git a/include/__mutex/once_flag.h b/include/__mutex/once_flag.h
  2. index 086f75c..d66bb87 100644
  3. --- a/include/__mutex/once_flag.h
  4. +++ b/include/__mutex/once_flag.h
  5. @@ -21,6 +21,10 @@
  6. # include <tuple>
  7. #endif
  8. +#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_CXX03_LANG)
  9. +#include <atomic>
  10. +#endif
  11. +
  12. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  13. # pragma GCC system_header
  14. #endif
  15. @@ -60,7 +64,11 @@ struct _LIBCPP_TEMPLATE_VIS once_flag {
  16. static const _State_type _Complete = ~_State_type(0);
  17. private:
  18. +#if defined(_LIBCPP_ABI_MICROSOFT)
  19. + atomic<_State_type> __state_;
  20. +#else
  21. _State_type __state_;
  22. +#endif
  23. #ifndef _LIBCPP_CXX03_LANG
  24. template <class _Callable, class... _Args>
  25. @@ -115,13 +123,21 @@ void _LIBCPP_HIDE_FROM_ABI __call_once_proxy(void* __vp) {
  26. (*__p)();
  27. }
  28. +#ifdef _LIBCPP_ABI_MICROSOFT
  29. +_LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile atomic<once_flag::_State_type>&, void*, void (*)(void*));
  30. +#else
  31. _LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*));
  32. +#endif
  33. #ifndef _LIBCPP_CXX03_LANG
  34. template <class _Callable, class... _Args>
  35. inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) {
  36. +#if defined(_LIBCPP_ABI_MICROSOFT)
  37. + if (__flag.__state_.load(memory_order_acquire) != ~once_flag::_State_type(0)) {
  38. +#else
  39. if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
  40. +#endif
  41. typedef tuple<_Callable&&, _Args&&...> _Gp;
  42. _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...);
  43. __call_once_param<_Gp> __p(__f);
  44. @@ -133,7 +149,11 @@ inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __fun
  45. template <class _Callable>
  46. inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func) {
  47. +#if defined(_LIBCPP_ABI_MICROSOFT)
  48. + if (__flag.__state_.load(memory_order_acquire) != ~once_flag::_State_type(0)) {
  49. +#else
  50. if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
  51. +#endif
  52. __call_once_param<_Callable> __p(__func);
  53. std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);
  54. }
  55. @@ -141,7 +161,11 @@ inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func
  56. template <class _Callable>
  57. inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, const _Callable& __func) {
  58. +#if defined(_LIBCPP_ABI_MICROSOFT)
  59. + if (__flag.__state_.load(memory_order_relaxed) != ~once_flag::_State_type(0)) {
  60. +#else
  61. if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
  62. +#endif
  63. __call_once_param<const _Callable> __p(__func);
  64. std::__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);
  65. }