-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Strengthen Atomics critical section to imply synchronizes-with #1692
Conversation
@syg do you think this is something that can have test262 test coverage? |
@ljharb Unfortunately not. :( |
spec.html
Outdated
1. Let _leaverEventList_ be the [[EventList]] field of the element in _execution_.[[EventRecords]] whose [[AgentSignifier]] is _L_. | ||
1. Let _enterEvent_ and _leaveEvent_ be new Synchronize events. | ||
1. Append _enterEvent_ to _entererEventList_. | ||
1. Append _leaveEvent_ to _leaverEventList_. |
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.
Morally, this will create a synchronization in the wrong place.
The leaver's (unpaired) synchronization event should be inserted into the event list at the moment of leaving the critical section, with the subsequent entry into the critical section creating the paired synchronization event. Otherwise, you allow executions where the leaver's synchronization event shows up in the agent-order after other events which it is programmatically before (i.e. the notifying thread could have continued execution before the notified waiter gets a chance to re-enter the critical section). This is potentially un-observable, but it's un-intuitive and might cause inconsistencies later on if other features which expose operational interleavings are added.
I'm also a little iffy about the prose identification of the "immediately preceding" agent. This seems like the sort of thing that should be explicitly tracked as state in a semantic object.
The minimum patch would be to make the WaiterList keep a record of the last exiting synchronization event, updated with every LeaveCriticalSection, and synchronized on with every EnterCriticalSection.
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.
Thank you as always, @conrad-watt. These are all good suggestions, and I will try to incorporate them.
spec.html
Outdated
@@ -36144,15 +36154,6 @@ <h1>NotifyWaiter ( _WL_, _W_ )</h1> | |||
<emu-alg> | |||
1. Assert: The calling agent is in the critical section for _WL_. | |||
1. Assert: _W_ is on the list of waiters in _WL_. | |||
1. Let _execution_ be the [[CandidateExecution]] field of the surrounding agent's Agent Record. |
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.
Deleting these lines has an interesting interaction with the current Atomics.waitAsync proposal. Not something that should interfere overly with this PR though.
Currently, Atomics.wait will re-enter the critical section after being notified. This provides synchronization from the critical section exit of the previous Atomics.notify, and makes these lines redundant. However, if I'm reading the proposed spec correctly, Atomics.waitAsync does not enter the critical section after being notified, so deleting this section loses a synchronization edge that should probably be present, and will need to be added somewhere else in the proposal.
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.
Yes, I realized this when writing this. Since it'll most likely fall on me to fix that spec text, I figured it's easiest to do the minimum delta for the current version of the spec so as to not raise "why is this here?" kind of questions, and fix it up in the waitAsync proposal.
Awaiting more code before reviewing, but really inclined to simply accept the judgement of @conrad-watt on this patch. |
8ff6cb7
to
92a1604
Compare
@conrad-watt Is this more or less what you had in mind? |
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.
LGTM!
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.
Rubber stamp, for all practical purposes.
spec.html
Outdated
@@ -36057,9 +36057,10 @@ <h1>ValidateAtomicAccess ( _typedArray_, _requestIndex_ )</h1> | |||
|
|||
<emu-clause id="sec-getwaiterlist" aoid="GetWaiterList"> | |||
<h1>GetWaiterList ( _block_, _i_ )</h1> | |||
<p>A <dfn>WaiterList</dfn> is a semantic object that contains an ordered list of those agents that are waiting on a location (_block_, _i_) in shared memory; _block_ is a Shared Data Block and _i_ a byte offset into the memory of _block_.</p> | |||
<p>A <dfn>WaiterList</dfn> is a semantic object that contains an ordered list of those agents that are waiting on a location (_block_, _i_) in shared memory; _block_ is a Shared Data Block and _i_ a byte offset into the memory of _block_. A WaiterList object also optionally contains a Synchronize event denoting the previous leaving of its critical section.</p> |
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 see the term "critical section" already in use, but there seems to be no definition of it in the spec. That doesn't have to block this PR, but it'd probably be good to define it in a separate PR, if not this one :-)
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'll do a separate editorial PR.
spec.html
Outdated
1. Let _leaverEventList_ be _eventsRecord_.[[EventList]]. | ||
1. Let _leaveEvent_ be a new Synchronize event. | ||
1. Append _leaveEvent_ to _leaverEventList_. | ||
1. Set the Synchronize event in _WL_ to _leaveEvent_. |
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.
Should this be an internal slot, instead of a vague concept of being "in" a WaiterList?
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 don't recall exactly the history of why WaiterList is a "semantic object" instead of being a Record with fields. Perhaps it was to distinguish it as a special spec object that can be touched by different agents and needs to be locked by the critical section to be used? That way we can keep thinking of Records as objects that are intra-agent and don't need any extra care for use.
This also affects how I write the Atomics.waitAsync
spec, since that extends the WaiterList to include more information that are accessed from multiple agents.
My preference is to keep it as a semantic object for this PR. I'm open to having some specialization of Record to distinguish WaiterList from other Records -- any thoughts there?
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 more confused by the whole concept of "semantic object" - the spec doesn't have anything else like that afaik.
It's fine to leave as-is, for the reasons you stated, but it seems like it'd be clearer to me in the future to have it be a proper Record; or to define some kind of more explicit syntax for interacting with "semantic objects" besides prose.
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.
LGTM.
Would be great to pursue additional PRs to define "critical section", and to more explicitly specify "semantic objects" and things being "in" them.
92a1604
to
9d4e9d0
Compare
Rebased. |
9d4e9d0
to
d764223
Compare
PR tc39#1692 removed the element-id 'sec-synchronizeeventset'. Reinstate it as an 'oldid'.
PR tc39#1692 removed the element-id 'sec-synchronizeeventset'. Reinstate it as an 'oldid'.
- Add a subscript R: Since _intValue_ is to be treated as a mathematical value, we should be comparing it to a mathematical zero. - Reinstate 'sec-static-semantics-elisionwidth' as an oldid; tc39#1124 removed the element-id 'sec-static-semantics-elisionwidth' - Reinstate 'sec-synchronizeeventset' as an oldid; tc39#1692 removed the element-id 'sec-synchronizeeventset'. - Reference 'ExportFromClause' from Annex A; tc39#1174 introduced the nonterminal 'ExportFromClause', but didn't reference it from Annex A. - Put asterisks around 'true' (from tc39#1716) - Fix typo "_eventRecords_" -> "_eventsRecord_" (from tc39#1692)
@conrad-watt @lars-t-hansen
Fixes #1680.