37-mutex.patch 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. diff --git a/include/__mutex/once_flag.h b/include/__mutex/once_flag.h
  2. index 9d7baec..9cd3dff 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. @@ -63,7 +67,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. @@ -118,13 +126,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(std::forward<_Callable>(__func), std::forward<_Args>(__args)...);
  43. __call_once_param<_Gp> __p(__f);
  44. @@ -136,7 +152,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. @@ -144,7 +164,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. }