Date: Wed, 20 Jul 2022 19:13:33 -0400
On Wed, Jul 20, 2022 at 4:52 PM zwhconst via Std-Discussion
<std-discussion_at_[hidden]> wrote:
>
> I'm the person that asked the original StackOverflow question.
> After seeing the answers on StackOverflow and the discussions in the
> mailing list, I still have several questions.
>
> Question 1:
> Does the "eligible to be unblocked" property/attribute have "time"
> constraint?
> Being "eligible to be unblocked by a particular atomic notifying
> operation" is a property of an atomic waiting operation.
> The wording in the standard text:
> > A call to an atomic waiting operation on an atomic object M is
> eligible to be unblocked by a call to an atomic notifying operation on M
> if there exist side effects X and Y on M such that:
> > (4.1) — the atomic waiting operation has blocked after observing the
> result of X,
> > (4.2) — X precedes Y in the modification order of M, and
> > (4.3) — Y happens before the call to the atomic notifying operation.
> What does the (4.1) clause mean? I see two different interpretations:
> - A: "the atomic waiting operation IS blockING after observing the
> result of X". i.e. this property holds only in a particular time span
> (after it enters blocking state, before it exits blocking state).
> - B: "the atomic waiting operation has ONCE EVER blocked after observing
> the result of X". i.e. it is a fixed property of the atomic waiting
> operation; if it is, it always is.
> Which one is the correct interpretation, A or B?
It actually doesn't matter.
If modification Y is a modification that will terminate the atomic
waiting operation, then whether it is technically blocked at the time
is irrelevant. Either it will be unblocked, or it has been unblocked
already (due to spurious wakeup) and is about to atomically load the
value of Y. This means that, notification or not, it is about to cease
being an "atomic waiting operation" (because it will have returned
from `wait`). So the most that interpretation B will mean is that
`notify_one` might in theory not unblock an atomic waiting operation
that was actually blocking in its atomic wait.
That being said, I rather suspect that the phrase should be "is
blocking". But this is editorial at best, as it would have no visible
effect on behavior (as spurious wakeup already ensures that atomic
waiting operations can wake up without notification).
> Question 2:
> Does the selection of atomic waiting operation to unblock have "time"
> constraint?
> The wording in the standard text:
> > void notify_one() volatile noexcept;
> > void notify_one() noexcept;
> > Effects: Unblocks the execution of at least one atomic waiting
> operation that is eligible to be unblocked (31.6) by this call, if any
> such atomic waiting operations exist.
> the phrase "if any such atomic waiting operations exist" also has two
> possible interpretations:
> - P: "if any such atomic waiting operations exist AT THE TIME of
> execution of notify_one()"
> - Q: "if any such atomic waiting operations EVER exist"
> Which one is the correct interpretation, P or Q?
>
> Question 3: What does an atomic notifying operation unblocks?
> - X: it unblocks the whole atomic waiting operation. Once the (selected)
> atomic waiting operation is unblocked, it is always unblocked.
> - Y: it unblocks only one round of blocking of the atomic waiting
> operation. If the atomic waiting operation wakes up and blocks again, it
> needs another atomic notifying operation to unblock.
> Which one is correct, X or Y?
These last two questions feel a lot like asking if doing `a = b + 3;`
means that, if you later change `b` to 4 whether that will update the
value in `a` so that it becomes 7? Of course not; the behavior of `+`
and `=` happens at the time they get executed. It doesn't travel
forwards in time to take into account subsequent changes to the value
of `b`.
The standard does not need to spell out that conditions are checked at
the time the function is called, nor does it need to say that the call
has no effect on conditions that happen after it does its thing.
<std-discussion_at_[hidden]> wrote:
>
> I'm the person that asked the original StackOverflow question.
> After seeing the answers on StackOverflow and the discussions in the
> mailing list, I still have several questions.
>
> Question 1:
> Does the "eligible to be unblocked" property/attribute have "time"
> constraint?
> Being "eligible to be unblocked by a particular atomic notifying
> operation" is a property of an atomic waiting operation.
> The wording in the standard text:
> > A call to an atomic waiting operation on an atomic object M is
> eligible to be unblocked by a call to an atomic notifying operation on M
> if there exist side effects X and Y on M such that:
> > (4.1) — the atomic waiting operation has blocked after observing the
> result of X,
> > (4.2) — X precedes Y in the modification order of M, and
> > (4.3) — Y happens before the call to the atomic notifying operation.
> What does the (4.1) clause mean? I see two different interpretations:
> - A: "the atomic waiting operation IS blockING after observing the
> result of X". i.e. this property holds only in a particular time span
> (after it enters blocking state, before it exits blocking state).
> - B: "the atomic waiting operation has ONCE EVER blocked after observing
> the result of X". i.e. it is a fixed property of the atomic waiting
> operation; if it is, it always is.
> Which one is the correct interpretation, A or B?
It actually doesn't matter.
If modification Y is a modification that will terminate the atomic
waiting operation, then whether it is technically blocked at the time
is irrelevant. Either it will be unblocked, or it has been unblocked
already (due to spurious wakeup) and is about to atomically load the
value of Y. This means that, notification or not, it is about to cease
being an "atomic waiting operation" (because it will have returned
from `wait`). So the most that interpretation B will mean is that
`notify_one` might in theory not unblock an atomic waiting operation
that was actually blocking in its atomic wait.
That being said, I rather suspect that the phrase should be "is
blocking". But this is editorial at best, as it would have no visible
effect on behavior (as spurious wakeup already ensures that atomic
waiting operations can wake up without notification).
> Question 2:
> Does the selection of atomic waiting operation to unblock have "time"
> constraint?
> The wording in the standard text:
> > void notify_one() volatile noexcept;
> > void notify_one() noexcept;
> > Effects: Unblocks the execution of at least one atomic waiting
> operation that is eligible to be unblocked (31.6) by this call, if any
> such atomic waiting operations exist.
> the phrase "if any such atomic waiting operations exist" also has two
> possible interpretations:
> - P: "if any such atomic waiting operations exist AT THE TIME of
> execution of notify_one()"
> - Q: "if any such atomic waiting operations EVER exist"
> Which one is the correct interpretation, P or Q?
>
> Question 3: What does an atomic notifying operation unblocks?
> - X: it unblocks the whole atomic waiting operation. Once the (selected)
> atomic waiting operation is unblocked, it is always unblocked.
> - Y: it unblocks only one round of blocking of the atomic waiting
> operation. If the atomic waiting operation wakes up and blocks again, it
> needs another atomic notifying operation to unblock.
> Which one is correct, X or Y?
These last two questions feel a lot like asking if doing `a = b + 3;`
means that, if you later change `b` to 4 whether that will update the
value in `a` so that it becomes 7? Of course not; the behavior of `+`
and `=` happens at the time they get executed. It doesn't travel
forwards in time to take into account subsequent changes to the value
of `b`.
The standard does not need to spell out that conditions are checked at
the time the function is called, nor does it need to say that the call
has no effect on conditions that happen after it does its thing.
Received on 2022-07-20 23:16:06