-
-
Notifications
You must be signed in to change notification settings - Fork 421
Fix issue 21578 - core.atomic.atomicFetchSub for pointers incorrectly… #3343
Conversation
Thanks for your pull request and interest in making D better, @rymrg! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "stable + druntime#3343" |
@rymrg thanks for following through, the commit message and target branch all look good now! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me overall, nice work!
I have one final suggestion regarding the array variables:
src/core/atomic.d
Outdated
@betterC pure nothrow @nogc unittest | ||
{ | ||
byte[] byteArray = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]; | ||
ulong[] ulongArray = [2, 4, 6, 8, 10, 12, 14, 16, 19, 20]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
core.atomic
is meant to work with shared
types. I think the functions that take non-shared
arguments are for backwards compatibility with old code. Can you make these array variables shared
, in order to be consistent with the general concept of this module?
ulong[] ulongArray = [2, 4, 6, 8, 10, 12, 14, 16, 19, 20]; | |
shared(ulong)[] ulongArray = [2, 4, 6, 8, 10, 12, 14, 16, 19, 20]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure. shared is still considered broken by some people. It also gets in the way of creating proper atomic variable like in C++.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure. shared is still considered broken by some people.
The latest state of shared
is that it's not broken, just incomplete. core.atomic
and core.sync.mutex
[1] work perfectly with shared
as far as I know.
It also gets in the way of creating proper atomic variable like in C++.
Do you have a bug report? As far as I can tell it works without issues based on a quick implementation I just wrote [2]
[1]: After my PR some time ago: #1728
[2]: https://gist.github.com/PetarKirov/8590707f5a21347dc4684b77d092cf60 /
https://run.dlang.io/gist/PetarKirov/8590707f5a21347dc4684b77d092cf60?compiler=dmd&args=-main%20-unittest%20-checkaction%3Dcontext / https://run.dlang.io/is/MsuNVh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. I encountered these atomic issues when trying to implement my full version. It seems my issue stemmed from not having the shared attribute over the functions. I cannot find documentation stating that shared should be used as function attribute.
So this is a documentation issue. Does shared have any documentation other than this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems my issue stemmed from not having the shared attribute over the functions.
Yes, analogous to C++ const
member functions, in D a member function func
must have the shared
qualifier, if you want to call it on a shared
object - shared(Obj) obj; obj.func()
.
I cannot find documentation stating that shared should be used as function attribute.
You can overload member functions on the type qualifier of this
, whether it is shared
, just like const
, immutable
and inout
. After searching, the only mention of that language feature in the spec that I could find is this one: https://dlang.org/spec/class.html#member-functions. In other words, you can treat shared
just like the other transitive D type qualifiers and as long as you match them on the function signatures things should work well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
core.atomic is meant to work with shared types
No, core.atomic
is supposed to support shared types. Unshared has nothing to do with backwards compatibility, it's just normal testing.
I think tests should not have shared
unless they are testing shared
specifically. If tests wanted to be comprehensive, it could be implemented as a test matrix or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So should I just remove the shared versions of the test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't make it a primary test, because it's obscuring the thing that's being tested. But it doesn't hurt to make sure shared is also covered in tests because it's one of the combinatorial things that is often overlooked in testing, definitely should to be supported, and shared
is tricky enough that it can not be assumed to work naturally without testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I removed the shared test in the recent commit. Seeing as testing both at the same time like earlier submission caused too much confusion. How do you suggest to add the shared test?
The error on CircleCI is:
On CirrusCI and BuildKite we have this log output:
which doesn't make much sense to me. |
No CircleCI has the same error:
Protip: Grep for |
@@ -196,7 +196,7 @@ T atomicFetchSub(MemoryOrder ms = MemoryOrder.seq, T)(ref T val, size_t mod) pur | |||
in (atomicValueIsProperlyAligned(val)) | |||
{ | |||
static if (is(T == U*, U)) | |||
return cast(T)core.internal.atomic.atomicFetchAdd!ms(cast(size_t*)&val, mod * U.sizeof); | |||
return cast(T)core.internal.atomic.atomicFetchSub!ms(cast(size_t*)&val, mod * U.sizeof); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wow... I'm sorry! That's an epic fail!
@rymrg Are you sure you have rebased on top of the latest stable branch? You could try: git checkout master
git pull
git checkout $Issue_21578
git rebase --onto origin/stable origin/master Most likely the failures are due to some mismatches between your local repo and upstream. |
Problem was forgetting tests are inside a nogc block |
… calls wrong function from core.internal.atomic
… calls wrong function from core.internal.atomic
I managed to break the previous pull request [/pull/3342] instead of fixing it. Sorry!
Updated the unit tests and targeted stable.
@PetarKirov Thanks for the input. See updates.
@kinke @ibuclaw