Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upAtomics.wait/wake are weaker than underlying OS calls #1119
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment
Hide comment
syg
Mar 1, 2018
Member
@conrad-watt Would you like to draft a normative PR for adding the s-w additions you outlined? I will review and champion if needed.
|
@conrad-watt Would you like to draft a normative PR for adding the s-w additions you outlined? I will review and champion if needed. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment
Hide comment
|
Ok! I'll put something together. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment
Hide comment
|
fixed by ef0cf19 |
conrad-watt
closed this
Sep 14, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
conrad-watt commentedFeb 25, 2018
•
edited
Actions associated with Atomics.wake/wait are not tracked in the axiomatic memory model, other than the initial read by wake. This means that other reads and writes are permitted to be re-ordered around these instructions in surprising ways.
In particular, with the current semantics it is not guaranteed that thread 1 will read 1 in the second line (assuming tA is initially zeroed).
This is because if thread 1 waits before thread 2 reaches line 2, no ordering constraint is induced between them by either thread 2's atomic store (which is never read from) or thread 2's wake, which does not induce any abstract action in the axiomatic model. Therefore, thread 1's non-atomic read is free to take the initial value of tA[1].
This is far weaker than the underlying OS calls that I assume wait/wake must be implemented using. On linux at least, when thread 1 sleeps, it will issue a full barrier. If thread 2 successfully wakes 1 or more threads, it will issue a write barrier (https://www.kernel.org/doc/Documentation/memory-barriers.txt). In my example, this is sufficient to guarantee that thread 1 will read 1 in the second line.
It also seems intuitive that wake should be used to indicate work completed on the part of the waking thread, but with the current semantics it is not guaranteed that this work will be visible.
I've previously discussed this over email with @lars-t-hansen, @syg, and @rossberg, and there seems to be a broad consensus that the semantics should be stronger. I personally believe that the act of waking and being woken should introduce abstract actions into the [[EventList]] of each thread such that the wake of thread 2 synchronizes-with a "being woken" action in thread 1. Indeed, based on our discussions, this may have been the informal intention of the spec during an earlier draft. However this might require additional barriers in some weaker architectures, and discussions in other possible specification solutions are still ongoing.