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

[intro.races] Make reading atomic objects nondeterministic #6501

Merged

Conversation

languagelawyer
Copy link
Contributor

@languagelawyer languagelawyer commented Aug 22, 2023

[intro.abstract]/3:

Certain other aspects and operations of the abstract machine are described in this document as unspecified... These define the nondeterministic aspects of the abstract machine. An instance of the abstract machine can thus have more than one possible execution for a given program and a given input.

Without «unspecified» in [intro.race]/14

The value of an atomic object M, as determined by evaluation B, shall be the value stored by some side effect A that modifies M, where B does not happen before A.

reading atomic objects is not nondeterministic

Copy link
Member

@jensmaurer jensmaurer left a comment

Choose a reason for hiding this comment

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

I think this is an editorial clarification of what was already normatively specified; "some" meaning (in English) a (possibly random) pick.

@languagelawyer languagelawyer changed the title [intro.races] Make reading atomic object nondeterministic [intro.races] Make reading atomic objects nondeterministic Aug 22, 2023
@tkoeppe
Copy link
Contributor

tkoeppe commented Nov 8, 2023

I suppose this calls for a wider audit whether every instance of non-deterministic behaviour is marked by the presence of the term "unspecified".

@tkoeppe tkoeppe merged commit 21454c7 into cplusplus:main Nov 8, 2023
2 checks passed
@xmh0511
Copy link
Contributor

xmh0511 commented Nov 13, 2023

As the behavior is changed to "unspecified", does it mean the following example is unspecified?

std::atomic<int> v{0};
auto c = [](){v.store(1,std::memory_order::release); return 1;}();
auto c2 = [](){v.store(2,std::memory_order::release); return 2;}();

int main(){
   auto r = v.load(std::memory_order::acquire); // #1
}

Does it mean #1 can be 0, 1, or 2, which is unspecified?

@tkoeppe
Copy link
Contributor

tkoeppe commented Nov 13, 2023

@xmh0511: this edit wasn't meant to change anything, only to clarify.

I don't think the wording means "the value is free to be any of the previously assigned values"; rather, it bounds the set of possible values: the wording guarantees that the value that you read is one of the values that was previously written, as opposed to being any other, arbitrary value.

@xmh0511
Copy link
Contributor

xmh0511 commented Nov 13, 2023

@xmh0511: this edit wasn't meant to change anything, only to clarify.

I don't think the wording means "the value is free to be any of the previously assigned values"; rather, it bounds the set of possible values: the wording guarantees that the value that you read is one of the values that was previously written, as opposed to being any other, arbitrary value.

Well, I think the above example is based on I have correctly read the intent of the wording. So, I asked, Is the result either 0, 1, or 2? In the example, these numbers are all previously written to the modification order of the atomic object, and #1 does not happen before these side effects.

@tkoeppe
Copy link
Contributor

tkoeppe commented Nov 13, 2023

The value is 2.

@xmh0511
Copy link
Contributor

xmh0511 commented Nov 13, 2023

The value is 2.

Where is the rule that guarantees the result is 2?

@jwakely
Copy link
Member

jwakely commented Nov 13, 2023

The value is 2.

Where is the rule that guarantees the result is 2?

Immediately after the changed paragraph, in the coherence rules. In your example, c1 happens before c2, and c2 happens before the read.

If the modifications do not happen before the read, then which modification is visible is unspecified. That doesn't apply in your example though.

@xmh0511
Copy link
Contributor

xmh0511 commented Nov 13, 2023

The value is 2.

Where is the rule that guarantees the result is 2?

Immediately after the changed paragraph, in the coherence rules. In your example, c1 happens before c2, and c2 happens before the read.

If the modifications do not happen before the read, then which modification is visible is unspecified. That doesn't apply in your example though.

However, [basic.start.dynamic] says c1 is sequenced before c2, if we don't consider the initialization is deferred, that means, c2 is sequence before the first statement(#1) of main, since "sequenced before" is transitive, then c1 is sequenced before the #1, which can get the conclusion that: c1 happens before #1, c2 happens before #1, per

An evaluation A happens before an evaluation B (or, equivalently, B happens after A) if:

  • A is sequenced before B, or

Either reading the value of c1 or c2 at #1 does not violate other rules following the changed rule.

@tkoeppe
Copy link
Contributor

tkoeppe commented Nov 13, 2023

Either reading the value of c1 or c2 at #1 does not violate other rules following the changed rule.

The rule has not changed. It has just been clarified.

As @jwakely said, the value of r in your example is determined by other rules than the one whose wording has been changed in this commit. The present rule does not determine the value of the r; rather, it merely places some limit on what the value of r could possibly be. That does not preclude other rules from requiring a specific choice from among those limited values. Does that help?

@jwakely
Copy link
Member

jwakely commented Nov 13, 2023

The previous wording "some side effect" didn't say which one either. Because it's stated elsewhere, not in that sentence.

@xmh0511
Copy link
Contributor

xmh0511 commented Nov 13, 2023

The previous wording "some side effect" didn't say which one either. Because it's stated elsewhere, not in that sentence.

Well, I know p14 only places some limit on the value of r. However, [intro.races] p15, [intro.races] p16, [intro.races] p17, and [intro.races] p18 does not prevent r from reading the value written by c1. I don't find other rules that restrict the result of my example except those I listed here.

@xmh0511
Copy link
Contributor

xmh0511 commented Nov 13, 2023

@tkoeppe

That does not preclude other rules from requiring a specific choice from among those limited values. Does that help?

I have listed all relevant rules in the above comment, I think they do not prevent r from reading the value written by c1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants