From 98e49dbd144f240b39c3b6c59cc348dc80e8db14 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Mon, 3 Aug 2020 21:33:58 +0300 Subject: [PATCH 1/9] P1644R0 wait/notify atomic>, #52 --- stl/inc/memory | 80 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 67b1cc410d3..650ff512e98 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3154,7 +3154,7 @@ protected: } } - _Ty* _Ptr = nullptr; + atomic<_Ty*> _Ptr{nullptr}; mutable atomic _Repptr{0}; }; @@ -3175,7 +3175,9 @@ public: void store(shared_ptr<_Ty> _Value, const memory_order _Order = memory_order::seq_cst) noexcept { _Check_store_memory_order(_Order); const auto _Rep = this->_Lock_and_load(); - _STD swap(this->_Ptr, _Value._Ptr); + const _Ty* _Tmp = _Value._Ptr; + _Value._Ptr = this->_Ptr.load(memory_order::relaxed); + this->_Ptr.store(_Tmp, memory_order::relaxed); this->_Store_and_unlock(_Value._Rep); _Value._Rep = _Rep; } @@ -3184,7 +3186,7 @@ public: _Check_load_memory_order(_Order); shared_ptr<_Ty> _Result; const auto _Rep = this->_Lock_and_load(); - _Result._Ptr = this->_Ptr; + _Result._Ptr = this->_Ptr.load(memory_order::relaxed); _Result._Rep = _Rep; _Result._Incref(); this->_Store_and_unlock(_Rep); @@ -3199,8 +3201,8 @@ public: _Check_memory_order(_Order); shared_ptr<_Ty> _Result; _Result._Rep = this->_Lock_and_load(); - _Result._Ptr = this->_Ptr; - this->_Ptr = _Value._Ptr; + _Result._Ptr = this->_Ptr.load(memory_order::relaxed); + this->_Ptr.store(_Value._Ptr, memory_order::relaxed); this->_Store_and_unlock(_Value._Rep); _Value._Ptr = nullptr; // ownership of _Value ref has been given to this, silence decrement _Value._Rep = nullptr; @@ -3226,14 +3228,16 @@ public: const memory_order _Order = memory_order::seq_cst) noexcept { _Check_memory_order(_Order); auto _Rep = this->_Lock_and_load(); - if (this->_Ptr == _Expected._Ptr && _Rep == _Expected._Rep) { - _STD swap(this->_Ptr, _Desired._Ptr); + if (this->_Ptr.load(memory_order::relaxed) == _Expected._Ptr && _Rep == _Expected._Rep) { + const _Ty* _Tmp = _Desired._Ptr; + _Desired._Ptr = this->_Ptr.load(memory_order::relaxed); + this->_Ptr.store(_Tmp, memory_order::relaxed); _STD swap(_Rep, _Desired._Rep); this->_Store_and_unlock(_Rep); return true; } _Ref_count_base* _Expected_rep = _Expected._Rep; - _Expected._Ptr = this->_Ptr; + _Expected._Ptr = this->_Ptr.load(memory_order::relaxed); _Expected._Rep = _Rep; _Expected._Incref(); this->_Store_and_unlock(_Rep); @@ -3243,6 +3247,27 @@ public: return false; } + void wait(shared_ptr<_Ty> _Old, memory_order = memory_order::seq_cst) const noexcept { + for (;;) { + auto _Rep = this->_Lock_and_load(); + bool _Equal = this->_Ptr.load(memory_order::relaxed) == _Old._Ptr; + this->_Store_and_unlock(_Rep); + if (!_Equal) { + break; + } + __std_atomic_wait_direct(&this->_Ptr, _Old._Ptr, sizeof(_Old._Ptr), _Atomic_wait_no_timeout); + } + } + + void notify_one() noexcept { + this->_Ptr.notify_one(); + } + + + void notify_all() noexcept { + this->_Ptr.notify_all(); + } + constexpr atomic() noexcept = default; atomic(const shared_ptr<_Ty> _Value) noexcept : _Base(_Value._Ptr, _Value._Rep) { @@ -3281,7 +3306,9 @@ public: void store(weak_ptr<_Ty> _Value, const memory_order _Order = memory_order::seq_cst) noexcept { _Check_store_memory_order(_Order); const auto _Rep = this->_Lock_and_load(); - _STD swap(this->_Ptr, _Value._Ptr); + const _Ty* _Tmp = _Value._Ptr; + _Value._Ptr = this->_Ptr.load(memory_order::relaxed); + this->_Ptr.store(_Tmp, memory_order::relaxed); this->_Store_and_unlock(_Value._Rep); _Value._Rep = _Rep; } @@ -3290,7 +3317,7 @@ public: _Check_load_memory_order(_Order); weak_ptr<_Ty> _Result; const auto _Rep = this->_Lock_and_load(); - _Result._Ptr = this->_Ptr; + _Result._Ptr = this->_Ptr.load(memory_order::relaxed); _Result._Rep = _Rep; _Result._Incwref(); this->_Store_and_unlock(_Rep); @@ -3305,8 +3332,8 @@ public: _Check_memory_order(_Order); weak_ptr<_Ty> _Result; _Result._Rep = this->_Lock_and_load(); - _Result._Ptr = this->_Ptr; - this->_Ptr = _Value._Ptr; + _Result._Ptr = this->_Ptr.load(memory_order::relaxed); + this->_Ptr.store(_Value._Ptr, memory_order::relaxed); this->_Store_and_unlock(_Value._Rep); _Value._Ptr = nullptr; // ownership of _Value ref has been given to this, silence decrement _Value._Rep = nullptr; @@ -3332,14 +3359,16 @@ public: weak_ptr<_Ty>& _Expected, weak_ptr<_Ty> _Desired, const memory_order _Order = memory_order::seq_cst) noexcept { _Check_memory_order(_Order); auto _Rep = this->_Lock_and_load(); - if (this->_Ptr == _Expected._Ptr && _Rep == _Expected._Rep) { - _STD swap(this->_Ptr, _Desired._Ptr); + if (this->_Ptr.load(memory_order::relaxed) == _Expected._Ptr && _Rep == _Expected._Rep) { + const _Ty* _Tmp = _Desired._Ptr; + _Desired._Ptr = this->_Ptr.load(memory_order::relaxed); + this->_Ptr.store(_Tmp, memory_order::relaxed); _STD swap(_Rep, _Desired._Rep); this->_Store_and_unlock(_Rep); return true; } const auto _Expected_rep = _Expected._Rep; - _Expected._Ptr = this->_Ptr; + _Expected._Ptr = this->_Ptr.load(memory_order::relaxed); _Expected._Rep = _Rep; _Expected._Incwref(); this->_Store_and_unlock(_Rep); @@ -3349,6 +3378,27 @@ public: return false; } + void wait(weak_ptr<_Ty> _Old, memory_order = memory_order::seq_cst) const noexcept { + for (;;) { + auto _Rep = this->_Lock_and_load(); + bool _Equal = this->_Ptr.load(memory_order::relaxed) == _Old._Ptr; + this->_Store_and_unlock(_Rep); + if (!_Equal) { + break; + } + __std_atomic_wait_direct(&this->_Ptr, _Old._Ptr, sizeof(_Old._Ptr), _Atomic_wait_no_timeout); + } + } + + void notify_one() noexcept { + this->_Ptr.notify_one(); + } + + + void notify_all() noexcept { + this->_Ptr.notify_all(); + } + constexpr atomic() noexcept = default; atomic(const weak_ptr<_Ty> _Value) noexcept : _Base(_Value._Ptr, _Value._Rep) { From b7f5b154bc9db480d287837b2178e5d333b97cab Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 4 Aug 2020 10:47:58 +0300 Subject: [PATCH 2/9] typos --- stl/inc/memory | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 650ff512e98..93b6f4ad59c 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3175,7 +3175,7 @@ public: void store(shared_ptr<_Ty> _Value, const memory_order _Order = memory_order::seq_cst) noexcept { _Check_store_memory_order(_Order); const auto _Rep = this->_Lock_and_load(); - const _Ty* _Tmp = _Value._Ptr; + _Ty* const _Tmp = _Value._Ptr; _Value._Ptr = this->_Ptr.load(memory_order::relaxed); this->_Ptr.store(_Tmp, memory_order::relaxed); this->_Store_and_unlock(_Value._Rep); @@ -3229,7 +3229,7 @@ public: _Check_memory_order(_Order); auto _Rep = this->_Lock_and_load(); if (this->_Ptr.load(memory_order::relaxed) == _Expected._Ptr && _Rep == _Expected._Rep) { - const _Ty* _Tmp = _Desired._Ptr; + _Ty* const _Tmp = _Desired._Ptr; _Desired._Ptr = this->_Ptr.load(memory_order::relaxed); this->_Ptr.store(_Tmp, memory_order::relaxed); _STD swap(_Rep, _Desired._Rep); @@ -3255,7 +3255,7 @@ public: if (!_Equal) { break; } - __std_atomic_wait_direct(&this->_Ptr, _Old._Ptr, sizeof(_Old._Ptr), _Atomic_wait_no_timeout); + __std_atomic_wait_direct(&this->_Ptr, &_Old._Ptr, sizeof(_Old._Ptr), _Atomic_wait_no_timeout); } } @@ -3306,7 +3306,7 @@ public: void store(weak_ptr<_Ty> _Value, const memory_order _Order = memory_order::seq_cst) noexcept { _Check_store_memory_order(_Order); const auto _Rep = this->_Lock_and_load(); - const _Ty* _Tmp = _Value._Ptr; + _Ty* const _Tmp = _Value._Ptr; _Value._Ptr = this->_Ptr.load(memory_order::relaxed); this->_Ptr.store(_Tmp, memory_order::relaxed); this->_Store_and_unlock(_Value._Rep); @@ -3360,7 +3360,7 @@ public: _Check_memory_order(_Order); auto _Rep = this->_Lock_and_load(); if (this->_Ptr.load(memory_order::relaxed) == _Expected._Ptr && _Rep == _Expected._Rep) { - const _Ty* _Tmp = _Desired._Ptr; + _Ty* const _Tmp = _Desired._Ptr; _Desired._Ptr = this->_Ptr.load(memory_order::relaxed); this->_Ptr.store(_Tmp, memory_order::relaxed); _STD swap(_Rep, _Desired._Rep); @@ -3386,7 +3386,7 @@ public: if (!_Equal) { break; } - __std_atomic_wait_direct(&this->_Ptr, _Old._Ptr, sizeof(_Old._Ptr), _Atomic_wait_no_timeout); + __std_atomic_wait_direct(&this->_Ptr, &_Old._Ptr, sizeof(_Old._Ptr), _Atomic_wait_no_timeout); } } From 0d66bf51097b251d276247c6cb93ded5c937df82 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 4 Aug 2020 21:05:07 +0300 Subject: [PATCH 3/9] test atomic_shared_ptr --- tests/std/include/test_atomic_wait.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/std/include/test_atomic_wait.hpp b/tests/std/include/test_atomic_wait.hpp index 248615cdf42..d797c5aa40b 100644 --- a/tests/std/include/test_atomic_wait.hpp +++ b/tests/std/include/test_atomic_wait.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -174,6 +175,10 @@ inline void test_atomic_wait() { test_atomic_wait_func(three_chars{1, 1, 3}, three_chars{1, 2, 3}, waiting_duration); test_atomic_wait_func(big_char_like{'a'}, big_char_like{'b'}, waiting_duration); + test_atomic_wait_func(std::make_shared('a'), std::make_shared('b'), waiting_duration); + test_atomic_wait_func( + std::weak_ptr(std::make_shared('a')), std::weak_ptr(std::make_shared('b')), waiting_duration); + test_notify_all_notifies_all(1, 2, waiting_duration); test_notify_all_notifies_all(1, 2, waiting_duration); test_notify_all_notifies_all(1, 2, waiting_duration); From 707046dd7ce5165d4e658d36ec5bce757a3ba213 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 5 Aug 2020 12:12:15 +0300 Subject: [PATCH 4/9] Update tests/std/include/test_atomic_wait.hpp Co-authored-by: Stephan T. Lavavej --- tests/std/include/test_atomic_wait.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/include/test_atomic_wait.hpp b/tests/std/include/test_atomic_wait.hpp index d797c5aa40b..ea02329624a 100644 --- a/tests/std/include/test_atomic_wait.hpp +++ b/tests/std/include/test_atomic_wait.hpp @@ -177,7 +177,7 @@ inline void test_atomic_wait() { test_atomic_wait_func(std::make_shared('a'), std::make_shared('b'), waiting_duration); test_atomic_wait_func( - std::weak_ptr(std::make_shared('a')), std::weak_ptr(std::make_shared('b')), waiting_duration); + std::weak_ptr{std::make_shared('a')}, std::weak_ptr{std::make_shared('b')}, waiting_duration); test_notify_all_notifies_all(1, 2, waiting_duration); test_notify_all_notifies_all(1, 2, waiting_duration); From 62c68c91bc4d56cf49de30603430cbfdb24f6f2b Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 5 Aug 2020 17:02:45 +0300 Subject: [PATCH 5/9] STL comments --- stl/inc/memory | 130 +++++++++++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 69 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 93b6f4ad59c..58c690d8fa7 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3116,7 +3116,7 @@ protected: : _Ptr(_Px), _Repptr(reinterpret_cast(_Ref)) {} _NODISCARD _Ref_count_base* _Lock_and_load() const noexcept { - uintptr_t _Rep = _Repptr.load(memory_order::relaxed); + uintptr_t _Rep = _Repptr.load(memory_order_relaxed); for (;;) { switch (_Rep & _Lock_mask) { case _Not_locked: // Can try to lock now @@ -3136,8 +3136,8 @@ protected: [[fallthrough]]; case _Locked_notify_needed: // "Notify needed" is already set, just wait - _Repptr.wait(_Rep, memory_order::relaxed); - _Rep = _Repptr.load(memory_order::relaxed); + _Repptr.wait(_Rep, memory_order_relaxed); + _Rep = _Repptr.load(memory_order_relaxed); break; default: // Unrecognized bit pattern @@ -3154,6 +3154,26 @@ protected: } } + void _Wait(_Ty* _Old, memory_order) const noexcept { + for (;;) { + auto _Rep = _Lock_and_load(); + bool _Equal = _Ptr.load(memory_order_relaxed) == _Old._Ptr; + _Store_and_unlock(_Rep); + if (!_Equal) { + break; + } + __std_atomic_wait_direct(&_Ptr, &_Old, sizeof(_Old), _Atomic_wait_no_timeout); + } + } + + void notify_one() noexcept { + _Ptr.notify_one(); + } + + void notify_all() noexcept { + _Ptr.notify_all(); + } + atomic<_Ty*> _Ptr{nullptr}; mutable atomic _Repptr{0}; }; @@ -3172,21 +3192,21 @@ public: return false; } - void store(shared_ptr<_Ty> _Value, const memory_order _Order = memory_order::seq_cst) noexcept { + void store(shared_ptr<_Ty> _Value, const memory_order _Order = memory_order_seq_cst) noexcept { _Check_store_memory_order(_Order); const auto _Rep = this->_Lock_and_load(); _Ty* const _Tmp = _Value._Ptr; - _Value._Ptr = this->_Ptr.load(memory_order::relaxed); - this->_Ptr.store(_Tmp, memory_order::relaxed); + _Value._Ptr = this->_Ptr.load(memory_order_relaxed); + this->_Ptr.store(_Tmp, memory_order_relaxed); this->_Store_and_unlock(_Value._Rep); _Value._Rep = _Rep; } - _NODISCARD shared_ptr<_Ty> load(const memory_order _Order = memory_order::seq_cst) const noexcept { + _NODISCARD shared_ptr<_Ty> load(const memory_order _Order = memory_order_seq_cst) const noexcept { _Check_load_memory_order(_Order); shared_ptr<_Ty> _Result; const auto _Rep = this->_Lock_and_load(); - _Result._Ptr = this->_Ptr.load(memory_order::relaxed); + _Result._Ptr = this->_Ptr.load(memory_order_relaxed); _Result._Rep = _Rep; _Result._Incref(); this->_Store_and_unlock(_Rep); @@ -3197,12 +3217,12 @@ public: return load(); } - shared_ptr<_Ty> exchange(shared_ptr<_Ty> _Value, const memory_order _Order = memory_order::seq_cst) noexcept { + shared_ptr<_Ty> exchange(shared_ptr<_Ty> _Value, const memory_order _Order = memory_order_seq_cst) noexcept { _Check_memory_order(_Order); shared_ptr<_Ty> _Result; _Result._Rep = this->_Lock_and_load(); - _Result._Ptr = this->_Ptr.load(memory_order::relaxed); - this->_Ptr.store(_Value._Ptr, memory_order::relaxed); + _Result._Ptr = this->_Ptr.load(memory_order_relaxed); + this->_Ptr.store(_Value._Ptr, memory_order_relaxed); this->_Store_and_unlock(_Value._Rep); _Value._Ptr = nullptr; // ownership of _Value ref has been given to this, silence decrement _Value._Rep = nullptr; @@ -3220,24 +3240,24 @@ public: } bool compare_exchange_weak(shared_ptr<_Ty>& _Expected, shared_ptr<_Ty> _Desired, - const memory_order _Order = memory_order::seq_cst) noexcept { + const memory_order _Order = memory_order_seq_cst) noexcept { return compare_exchange_strong(_Expected, _STD move(_Desired), _Order); } bool compare_exchange_strong(shared_ptr<_Ty>& _Expected, shared_ptr<_Ty> _Desired, - const memory_order _Order = memory_order::seq_cst) noexcept { + const memory_order _Order = memory_order_seq_cst) noexcept { _Check_memory_order(_Order); auto _Rep = this->_Lock_and_load(); - if (this->_Ptr.load(memory_order::relaxed) == _Expected._Ptr && _Rep == _Expected._Rep) { + if (this->_Ptr.load(memory_order_relaxed) == _Expected._Ptr && _Rep == _Expected._Rep) { _Ty* const _Tmp = _Desired._Ptr; - _Desired._Ptr = this->_Ptr.load(memory_order::relaxed); - this->_Ptr.store(_Tmp, memory_order::relaxed); + _Desired._Ptr = this->_Ptr.load(memory_order_relaxed); + this->_Ptr.store(_Tmp, memory_order_relaxed); _STD swap(_Rep, _Desired._Rep); this->_Store_and_unlock(_Rep); return true; } _Ref_count_base* _Expected_rep = _Expected._Rep; - _Expected._Ptr = this->_Ptr.load(memory_order::relaxed); + _Expected._Ptr = this->_Ptr.load(memory_order_relaxed); _Expected._Rep = _Rep; _Expected._Incref(); this->_Store_and_unlock(_Rep); @@ -3247,26 +3267,12 @@ public: return false; } - void wait(shared_ptr<_Ty> _Old, memory_order = memory_order::seq_cst) const noexcept { - for (;;) { - auto _Rep = this->_Lock_and_load(); - bool _Equal = this->_Ptr.load(memory_order::relaxed) == _Old._Ptr; - this->_Store_and_unlock(_Rep); - if (!_Equal) { - break; - } - __std_atomic_wait_direct(&this->_Ptr, &_Old._Ptr, sizeof(_Old._Ptr), _Atomic_wait_no_timeout); - } - } - - void notify_one() noexcept { - this->_Ptr.notify_one(); + void wait(weak_ptr<_Ty> _Old, memory_order = memory_order_seq_cst) const noexcept { + _Wait(_Old._Ptr, memory_order); } - - void notify_all() noexcept { - this->_Ptr.notify_all(); - } + using _Base::notify_one; + using _Base::notify_all; constexpr atomic() noexcept = default; @@ -3282,7 +3288,7 @@ public: } ~atomic() { - const auto _Rep = reinterpret_cast<_Ref_count_base*>(this->_Repptr.load(memory_order::relaxed)); + const auto _Rep = reinterpret_cast<_Ref_count_base*>(this->_Repptr.load(memory_order_relaxed)); if (_Rep) { _Rep->_Decref(); } @@ -3303,21 +3309,21 @@ public: return false; } - void store(weak_ptr<_Ty> _Value, const memory_order _Order = memory_order::seq_cst) noexcept { + void store(weak_ptr<_Ty> _Value, const memory_order _Order = memory_order_seq_cst) noexcept { _Check_store_memory_order(_Order); const auto _Rep = this->_Lock_and_load(); _Ty* const _Tmp = _Value._Ptr; - _Value._Ptr = this->_Ptr.load(memory_order::relaxed); - this->_Ptr.store(_Tmp, memory_order::relaxed); + _Value._Ptr = this->_Ptr.load(memory_order_relaxed); + this->_Ptr.store(_Tmp, memory_order_relaxed); this->_Store_and_unlock(_Value._Rep); _Value._Rep = _Rep; } - _NODISCARD weak_ptr<_Ty> load(const memory_order _Order = memory_order::seq_cst) const noexcept { + _NODISCARD weak_ptr<_Ty> load(const memory_order _Order = memory_order_seq_cst) const noexcept { _Check_load_memory_order(_Order); weak_ptr<_Ty> _Result; const auto _Rep = this->_Lock_and_load(); - _Result._Ptr = this->_Ptr.load(memory_order::relaxed); + _Result._Ptr = this->_Ptr.load(memory_order_relaxed); _Result._Rep = _Rep; _Result._Incwref(); this->_Store_and_unlock(_Rep); @@ -3328,12 +3334,12 @@ public: return load(); } - weak_ptr<_Ty> exchange(weak_ptr<_Ty> _Value, const memory_order _Order = memory_order::seq_cst) noexcept { + weak_ptr<_Ty> exchange(weak_ptr<_Ty> _Value, const memory_order _Order = memory_order_seq_cst) noexcept { _Check_memory_order(_Order); weak_ptr<_Ty> _Result; _Result._Rep = this->_Lock_and_load(); - _Result._Ptr = this->_Ptr.load(memory_order::relaxed); - this->_Ptr.store(_Value._Ptr, memory_order::relaxed); + _Result._Ptr = this->_Ptr.load(memory_order_relaxed); + this->_Ptr.store(_Value._Ptr, memory_order_relaxed); this->_Store_and_unlock(_Value._Rep); _Value._Ptr = nullptr; // ownership of _Value ref has been given to this, silence decrement _Value._Rep = nullptr; @@ -3351,24 +3357,24 @@ public: } bool compare_exchange_weak( - weak_ptr<_Ty>& _Expected, weak_ptr<_Ty> _Desired, const memory_order _Order = memory_order::seq_cst) noexcept { + weak_ptr<_Ty>& _Expected, weak_ptr<_Ty> _Desired, const memory_order _Order = memory_order_seq_cst) noexcept { return compare_exchange_strong(_Expected, _STD move(_Desired), _Order); } bool compare_exchange_strong( - weak_ptr<_Ty>& _Expected, weak_ptr<_Ty> _Desired, const memory_order _Order = memory_order::seq_cst) noexcept { + weak_ptr<_Ty>& _Expected, weak_ptr<_Ty> _Desired, const memory_order _Order = memory_order_seq_cst) noexcept { _Check_memory_order(_Order); auto _Rep = this->_Lock_and_load(); - if (this->_Ptr.load(memory_order::relaxed) == _Expected._Ptr && _Rep == _Expected._Rep) { + if (this->_Ptr.load(memory_order_relaxed) == _Expected._Ptr && _Rep == _Expected._Rep) { _Ty* const _Tmp = _Desired._Ptr; - _Desired._Ptr = this->_Ptr.load(memory_order::relaxed); - this->_Ptr.store(_Tmp, memory_order::relaxed); + _Desired._Ptr = this->_Ptr.load(memory_order_relaxed); + this->_Ptr.store(_Tmp, memory_order_relaxed); _STD swap(_Rep, _Desired._Rep); this->_Store_and_unlock(_Rep); return true; } const auto _Expected_rep = _Expected._Rep; - _Expected._Ptr = this->_Ptr.load(memory_order::relaxed); + _Expected._Ptr = this->_Ptr.load(memory_order_relaxed); _Expected._Rep = _Rep; _Expected._Incwref(); this->_Store_and_unlock(_Rep); @@ -3378,26 +3384,12 @@ public: return false; } - void wait(weak_ptr<_Ty> _Old, memory_order = memory_order::seq_cst) const noexcept { - for (;;) { - auto _Rep = this->_Lock_and_load(); - bool _Equal = this->_Ptr.load(memory_order::relaxed) == _Old._Ptr; - this->_Store_and_unlock(_Rep); - if (!_Equal) { - break; - } - __std_atomic_wait_direct(&this->_Ptr, &_Old._Ptr, sizeof(_Old._Ptr), _Atomic_wait_no_timeout); - } - } - - void notify_one() noexcept { - this->_Ptr.notify_one(); + void wait(weak_ptr<_Ty> _Old, memory_order = memory_order_seq_cst) const noexcept { + _Wait(_Old._Ptr, memory_order); } - - void notify_all() noexcept { - this->_Ptr.notify_all(); - } + using _Base::notify_all; + using _Base::notify_one; constexpr atomic() noexcept = default; @@ -3413,7 +3405,7 @@ public: } ~atomic() { - const auto _Rep = reinterpret_cast<_Ref_count_base*>(this->_Repptr.load(memory_order::relaxed)); + const auto _Rep = reinterpret_cast<_Ref_count_base*>(this->_Repptr.load(memory_order_relaxed)); if (_Rep) { _Rep->_Decwref(); } From 682ec984e84f9cb48effa237368948a814b993fc Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 5 Aug 2020 17:03:38 +0300 Subject: [PATCH 6/9] clang format wants wrong order --- stl/inc/memory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/memory b/stl/inc/memory index 58c690d8fa7..50f654ecc34 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3271,8 +3271,8 @@ public: _Wait(_Old._Ptr, memory_order); } - using _Base::notify_one; using _Base::notify_all; + using _Base::notify_one; constexpr atomic() noexcept = default; From 1a173d25c74d4596d4976e8570e501e2829145ed Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 5 Aug 2020 18:20:45 +0300 Subject: [PATCH 7/9] _Order --- stl/inc/memory | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 50f654ecc34..2759e55bc6f 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3267,8 +3267,8 @@ public: return false; } - void wait(weak_ptr<_Ty> _Old, memory_order = memory_order_seq_cst) const noexcept { - _Wait(_Old._Ptr, memory_order); + void wait(weak_ptr<_Ty> _Old, memory_order _Order = memory_order_seq_cst) const noexcept { + _Wait(_Old._Ptr, _Order); } using _Base::notify_all; @@ -3384,8 +3384,8 @@ public: return false; } - void wait(weak_ptr<_Ty> _Old, memory_order = memory_order_seq_cst) const noexcept { - _Wait(_Old._Ptr, memory_order); + void wait(weak_ptr<_Ty> _Old, memory_order _Order = memory_order_seq_cst) const noexcept { + _Wait(_Old._Ptr, _Order); } using _Base::notify_all; From 03bae8fcfd825be046bb748a8210a8e0aa355999 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 5 Aug 2020 19:08:36 +0300 Subject: [PATCH 8/9] Update stl/inc/memory Co-authored-by: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> --- stl/inc/memory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/memory b/stl/inc/memory index 2759e55bc6f..ef433045bb5 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3267,7 +3267,7 @@ public: return false; } - void wait(weak_ptr<_Ty> _Old, memory_order _Order = memory_order_seq_cst) const noexcept { + void wait(shared_ptr<_Ty> _Old, memory_order _Order = memory_order_seq_cst) const noexcept { _Wait(_Old._Ptr, _Order); } From d35fe92e7002126f89a3604b17f93c4a6330cf01 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 5 Aug 2020 19:36:32 +0300 Subject: [PATCH 9/9] this --- stl/inc/memory | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 2759e55bc6f..8d47f46596a 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3157,7 +3157,7 @@ protected: void _Wait(_Ty* _Old, memory_order) const noexcept { for (;;) { auto _Rep = _Lock_and_load(); - bool _Equal = _Ptr.load(memory_order_relaxed) == _Old._Ptr; + bool _Equal = _Ptr.load(memory_order_relaxed) == _Old; _Store_and_unlock(_Rep); if (!_Equal) { break; @@ -3268,7 +3268,7 @@ public: } void wait(weak_ptr<_Ty> _Old, memory_order _Order = memory_order_seq_cst) const noexcept { - _Wait(_Old._Ptr, _Order); + this->_Wait(_Old._Ptr, _Order); } using _Base::notify_all; @@ -3385,7 +3385,7 @@ public: } void wait(weak_ptr<_Ty> _Old, memory_order _Order = memory_order_seq_cst) const noexcept { - _Wait(_Old._Ptr, _Order); + this->_Wait(_Old._Ptr, _Order); } using _Base::notify_all;