For the atomic_compare-exchange family, e.g.
_Bool atomic_compare_exchange_strong(volatile A *object, C *expected, C desired);
the description states "Atomically, compares the contents of the memory pointed to by object for equality with that pointed to by expected, and
if true, replaces the contents of the memory pointed to by object with desired, and if false, updates the contents of the memory pointed to by expected with that pointed to by object."
This reads to me as if the write to *expected is also part of the atomic operation. This doesn't map well to compare-and-swap hardware
instructions, where the content of *object would be written to a
register, and later stored into *expected by a separate instruction.
Of course, this difference only matters if it is observable. I think it
is observable if just after the compare-and swap, a second thread writes *object, while the first thread has already done the comparison, but not
yet updated *expected.
Then e.g. a thread thread could read the new value from *object, but the
old one from *expected, which is not possible if atomic_compare_exchange_strong is fully atomic (i.e. also wrt. *expected).
Is my understanding here correct (I'm not an expert on atomics)?
For the atomic_compare-exchange family, e.g.
_Bool atomic_compare_exchange_strong(volatile A *object,
C *expected, C desired);
the description states "Atomically, compares the contents of the
memory pointed to by object for equality with that pointed to by
expected, and if true, replaces the contents of the memory pointed
to by object with desired, and if false, updates the contents of the
memory pointed to by expected with that pointed to by object."
This reads to me as if the write to *expected is also part of the
atomic operation.
This doesn't map well to compare-and-swap hardware instructions,
where the content of *object would be written to a register, and
later stored into *expected by a separate instruction.
Of course, this difference only matters if it is observable. I
think it is observable if just after the compare-and swap, a second
thread writes *object, while the first thread has already done the comparison, but not yet updated *expected.
Then e.g. a thread thread could read the new value from
*object, but the old one from *expected, which is not possible
if atomic_compare_exchange_strong is fully atomic (i.e. also
wrt. *expected).
Is my understanding here correct (I'm not an expert on atomics)?
On Tue, 5 Oct 2021 12:46:13 +0200 Philipp Klaus Krause <pkk@spth.de>
wrote:
For the atomic_compare-exchange family, e.g.
_Bool atomic_compare_exchange_strong(volatile A *object, C *expected, C
desired);
the description states "Atomically, compares the contents of the memory
pointed to by object for equality with that pointed to by expected, and
if true, replaces the contents of the memory pointed to by object with
desired, and if false, updates the contents of the memory pointed to by
expected with that pointed to by object."
This reads to me as if the write to *expected is also part of the atomic
operation. This doesn't map well to compare-and-swap hardware
instructions, where the content of *object would be written to a
register, and later stored into *expected by a separate instruction.
Of course, this difference only matters if it is observable. I think it
is observable if just after the compare-and swap, a second thread writes
*object, while the first thread has already done the comparison, but not
yet updated *expected.
Then e.g. a thread thread could read the new value from *object, but the
old one from *expected, which is not possible if
atomic_compare_exchange_strong is fully atomic (i.e. also wrt. *expected). >>
Is my understanding here correct (I'm not an expert on atomics)?
*expected has type C, so it's not atomic, but even if it was, the compare-and-swap, reading of *object, and reading of *expected are three different operations and anything can happen in between them.
* Coosemans:
On Tue, 5 Oct 2021 12:46:13 +0200 Philipp Klaus Krause <pkk@spth.de>
wrote:
For the atomic_compare-exchange family, e.g.
_Bool atomic_compare_exchange_strong(volatile A *object, C *expected, C
desired);
the description states "Atomically, compares the contents of the
memory pointed to by object for equality with that pointed to by
expected, and if true, replaces the contents of the memory pointed
to by object with desired, and if false, updates the contents of
the memory pointed to by expected with that pointed to by object."
This reads to me as if the write to *expected is also part of the
atomic operation. This doesn't map well to compare-and-swap
hardware instructions, where the content of *object would be
written to a register, and later stored into *expected by a
separate instruction.
Of course, this difference only matters if it is observable. I
think it is observable if just after the compare-and swap, a
second thread writes *object, while the first thread has already
done the comparison, but not yet updated *expected.
Then e.g. a thread thread could read the new value from *object,
but the old one from *expected, which is not possible if
atomic_compare_exchange_strong is fully atomic (i.e. also
wrt. *expected).
Is my understanding here correct (I'm not an expert on atomics)?
*expected has type C, so it's not atomic, but even if it was, the
compare-and-swap, reading of *object, and reading of *expected are
three different operations and anything can happen in between them.
And there are very few CPUs which can actually implement an
atomic updated of *expected as well. Since the intent is that atomic_compare_exchange maps to a typical CAS instruction,
it's apparent hat an atomic update of *expected can't be the
intended meaning.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 379 |
Nodes: | 16 (2 / 14) |
Uptime: | 84:47:37 |
Calls: | 8,091 |
Files: | 13,069 |
Messages: | 5,851,128 |