Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<memory>: Fix atomic smart pointers array type interaction #1339

Merged
merged 12 commits into from
May 5, 2022
Merged
27 changes: 14 additions & 13 deletions stl/inc/memory
Original file line number Diff line number Diff line change
Expand Up @@ -3812,9 +3812,10 @@ class alignas(2 * sizeof(void*)) _Atomic_ptr_base {
protected:
constexpr _Atomic_ptr_base() noexcept = default;

_Atomic_ptr_base(_Ty* const _Px, _Ref_count_base* const _Ref) noexcept : _Ptr(_Px), _Repptr(_Ref) {}
_Atomic_ptr_base(remove_extent_t<_Ty>* const _Px, _Ref_count_base* const _Ref) noexcept
: _Ptr(_Px), _Repptr(_Ref) {}

void _Wait(_Ty* _Old, memory_order) const noexcept {
void _Wait(remove_extent_t<_Ty>* _Old, memory_order) const noexcept {
for (;;) {
auto _Rep = _Repptr._Lock_and_load();
bool _Equal = _Ptr.load(memory_order_relaxed) == _Old;
Expand All @@ -3834,7 +3835,7 @@ protected:
_Ptr.notify_all();
}

atomic<_Ty*> _Ptr{nullptr};
atomic<remove_extent_t<_Ty>*> _Ptr{nullptr};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No change requested: Regarding the ABI implications that @strega-nil-ms mentioned in #1339 (review) - while changing data members is always concerning from an ABI perspective, I agree that the actual bits being stored are the same. Additionally, the previous code would generally fail to compile for simple cases like store(), which indicates that we shouldn't have to worry about mismatch issues. (The one time we can make unrestricted changes to layout is when the code couldn't compile at all before - this is not quite "wouldn't compile at all" but close.)

mutable _Locked_pointer<_Ref_count_base> _Repptr;
};

Expand All @@ -3854,9 +3855,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->_Repptr._Lock_and_load();
_Ty* const _Tmp = _Value._Ptr;
_Value._Ptr = this->_Ptr.load(memory_order_relaxed);
const auto _Rep = this->_Repptr._Lock_and_load();
remove_extent_t<_Ty>* const _Tmp = _Value._Ptr;
_Value._Ptr = this->_Ptr.load(memory_order_relaxed);
this->_Ptr.store(_Tmp, memory_order_relaxed);
this->_Repptr._Store_and_unlock(_Value._Rep);
_Value._Rep = _Rep;
Expand Down Expand Up @@ -3909,8 +3910,8 @@ public:
_Check_memory_order(_Order);
auto _Rep = this->_Repptr._Lock_and_load();
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);
remove_extent_t<_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);
this->_Repptr._Store_and_unlock(_Rep);
Expand Down Expand Up @@ -3971,9 +3972,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->_Repptr._Lock_and_load();
_Ty* const _Tmp = _Value._Ptr;
_Value._Ptr = this->_Ptr.load(memory_order_relaxed);
const auto _Rep = this->_Repptr._Lock_and_load();
remove_extent_t<_Ty>* const _Tmp = _Value._Ptr;
_Value._Ptr = this->_Ptr.load(memory_order_relaxed);
this->_Ptr.store(_Tmp, memory_order_relaxed);
this->_Repptr._Store_and_unlock(_Value._Rep);
_Value._Rep = _Rep;
Expand Down Expand Up @@ -4026,8 +4027,8 @@ public:
_Check_memory_order(_Order);
auto _Rep = this->_Repptr._Lock_and_load();
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);
remove_extent_t<_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);
this->_Repptr._Store_and_unlock(_Rep);
Expand Down
Loading