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

Conversation

xmas92
Copy link
Contributor

@xmas92 xmas92 commented Oct 2, 2020

Fixes #1332

Notes
Have not tested if it affects wait, notify_one and notify_all. Not that it should, but I am not well versed in the smart pointer implementations.

xmas92 added 2 commits October 1, 2020 12:51
Same tests as for the normal atomic smart pointer with non-array element.

The array pointers should behave exactly the same as the normal pointers.
Fix atomic smart pointers with array elements by making the internal type match that of [weak|shared]_ptr::element_type by removing the extent of the arrays.
@xmas92 xmas92 requested a review from a team as a code owner October 2, 2020 09:24
@ghost
Copy link

ghost commented Oct 2, 2020

CLA assistant check
All CLA requirements met.

@StephanTLavavej StephanTLavavej added the bug Something isn't working label Oct 2, 2020
@StephanTLavavej
Copy link
Member

Thanks! Should there be test coverage for multidimensional arrays? (This is the first thing I think of when I see remove_extent_t.) It doesn't have to be as thorough as the single-dimensional array coverage, just enough to indicate that this is the correct type trait to use.

xmas92 added 2 commits October 2, 2020 13:09
Add a test that checks that the atomic smart pointers with multidimensional arrays compiles.
@xmas92
Copy link
Contributor Author

xmas92 commented Oct 2, 2020

Added a compile test for multidimensional arrays (member and non-member functions). If you also want to test the functionality I think the best thing is to just repeat the original test for the different types. Could refactor it into template functions.

As originally noted the test do not touch the wait/notify mechanism. Not even if it compiles.
Is there some other test that test these and could be used to check that it still works for array types.

Otherwise I could not think of a simple way to test whether it compiles except writing some producer/consumer type of functions which use wait/notify.

@StephanTLavavej StephanTLavavej self-assigned this Oct 7, 2020
@cbezault

This comment has been minimized.

@azure-pipelines

This comment has been minimized.

@AlexGuteniev
Copy link
Contributor

STL/tests/std/tests/P1135R6_atomic_wait/test.cpp is where atomic wait is tested

Base automatically changed from master to main January 28, 2021 00:35
Update P1135R6_atomic_wait test to include smart pointers holding arrays.
…_ptr

Increase waiting_duration timing assumption for test_notify_all_notifies_all_ptr because it might have cause some flakiness for the test runners.
@xmas92
Copy link
Contributor Author

xmas92 commented Oct 17, 2021

I noticed that this issue[#1332] was still not fixed and had some time over so added test for smart pointer array types in tests/P1135R6_atomic_wait.

I used the already created, but unused, test_notify_all_notifies_all_ptr to test atomic shared pointers. But had to increase the timing assumption as the original seem to cause deadlocks in at least two test runners.

Maybe it should be a separate low priority issue to rewrite tests/P1135R6_atomic_wait so that deadlocks are impossible. The current implementation relies on a timing assumption of a data race to avoid deadlocks. Maybe someone have better statistics for the flakiness of these tests.

As for #1332, what is required to close this issue?

@strega-nil-ms strega-nil-ms self-assigned this May 3, 2022
Copy link
Contributor

@strega-nil-ms strega-nil-ms left a comment

Choose a reason for hiding this comment

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

Notes:

This in theory changes ABI of _Atomic_ptr_base; however, it only changes name manglings of non-public names, and changes the members of _Atomic_ptr_base<T[]> from:

{
    atomic<T(*)[]> _Ptr;
    _Locked_pointer<_Ref_count_base> _Repptr;
}

to

{
    atomic<T*> _Ptr;
    _Locked_pointer<_Ref_count_base> _Repptr;
}

which should not change ABI/layout at all.

Copy link
Contributor

@strega-nil-ms strega-nil-ms left a comment

Choose a reason for hiding this comment

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

_Seed should not be a template, since there's no reason for it to be a template. Additionally, an existing, correct, narrowing conversion now fails.

@strega-nil-ms strega-nil-ms dismissed their stale review May 4, 2022 17:42

Bug in VS code ended up making a comment meant for 2693 on this PR

Comment on lines +111 to +112
// increased waiting_duration because timing assumption might not hold for atomic smart pointers
test_notify_all_notifies_all_impl<std::atomic, UnderlyingType>(old_value, new_value, 3 * waiting_duration);
Copy link
Member

Choose a reason for hiding this comment

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

I'm slightly concerned about this change because the test suite should never contain timing assumptions that could lead to sporadic failures. That said, no change requested, because this is clearly a pre-existing issue.

Comment on lines +267 to +269
test_notify_all_notifies_all_ptr(std::make_shared<int>('a'), std::make_shared<int>('a'), waiting_duration);
test_notify_all_notifies_all_ptr(
std::weak_ptr{std::make_shared<int>('a')}, std::weak_ptr{std::make_shared<int>('a')}, waiting_duration);
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: Nice catch, test_notify_all_notifies_all_ptr() was defined but never used before.

@@ -3872,7 +3873,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.)

@@ -228,6 +229,21 @@ inline void test_atomic_wait() {
test_atomic_wait_func_ptr(std::make_shared<int>('a'), std::make_shared<int>('a'), waiting_duration);
test_atomic_wait_func_ptr(
std::weak_ptr{std::make_shared<int>('a')}, std::weak_ptr{std::make_shared<int>('a')}, waiting_duration);
test_atomic_wait_func_ptr(std::make_shared<int[]>(0), std::make_shared<int[]>(0), waiting_duration);
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: I note that the zero-runtime-length arrays being used in the test cases are unusual; however, I believe this is conforming, and the code also tests one-element arrays, so I have no objection to this (even if I would have used non-zero numbers for all).

Comment on lines +573 to +574
}
if (instance.compare_exchange_strong(loaded, constInstance)) {
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: We conventionally add newlines between non-chained if-statements. However, this was copied from pre-existing code immediately above, and it's not worth resetting testing by pushing a commit.

@StephanTLavavej StephanTLavavej removed their assignment May 5, 2022
@StephanTLavavej StephanTLavavej self-assigned this May 5, 2022
@StephanTLavavej
Copy link
Member

I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed.

@StephanTLavavej StephanTLavavej merged commit 24b899e into microsoft:main May 5, 2022
@StephanTLavavej
Copy link
Member

Thanks for fixing this bug, and congratulations on your first microsoft/STL commit! 🎉 😸 🚀

(And apologies for taking so long to review this! 🙀)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

<memory>: atomic smart pointers do not work with array elements
7 participants