Skip to content

Commit 6844810

Browse files
authored
Merge 2018-06 CWG Motion 9
Fixes #2121
2 parents 9ac27f7 + 2dc7620 commit 6844810

File tree

1 file changed

+54
-11
lines changed

1 file changed

+54
-11
lines changed

source/atomics.tex

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -849,10 +849,11 @@
849849
\tcode{memory_order::acq_rel}.
850850

851851
\pnum
852-
\effects Retrieves the value in \tcode{expected}. It then atomically
853-
compares the contents of the memory pointed to by \tcode{this}
852+
\effects
853+
Retrieves the value in \tcode{expected}. It then atomically
854+
compares the value representation of the value pointed to by \tcode{this}
854855
for equality with that previously retrieved from \tcode{expected},
855-
and if true, replaces the contents of the memory pointed to
856+
and if true, replaces the value pointed to
856857
by \tcode{this} with that in \tcode{desired}.
857858
If and only if the comparison is true, memory is affected according to the
858859
value of \tcode{success}, and if the comparison is false, memory is affected according
@@ -863,8 +864,8 @@
863864
\tcode{memory_order::release} shall be replaced by the value
864865
\tcode{memory_order::relaxed}.
865866
If and only if the comparison is false then, after the atomic operation,
866-
the contents of the memory in \tcode{expected} are replaced by the value
867-
read from the memory pointed to by \tcode{this} during the atomic comparison.
867+
the value in \tcode{expected} is replaced by the value
868+
pointed to by \tcode{this} during the atomic comparison.
868869
If the operation returns \tcode{true}, these
869870
operations are atomic read-modify-write
870871
operations\iref{intro.multithread} on the memory
@@ -875,8 +876,10 @@
875876
\returns The result of the comparison.
876877

877878
\pnum
878-
\begin{note} For example, the effect of
879-
\tcode{compare_exchange_strong} is
879+
\begin{note}
880+
For example, the effect of
881+
\tcode{compare_exchange_strong}
882+
on objects without padding bits\iref{basic.types} is
880883
\begin{codeblock}
881884
if (memcmp(this, &expected, sizeof(*this)) == 0)
882885
memcpy(this, &desired, sizeof(*this));
@@ -928,14 +931,54 @@
928931
\end{note}
929932

930933
\pnum
931-
\begin{note} The \tcode{memcpy} and \tcode{memcmp} semantics of the compare-and-exchange
932-
operations may result in failed comparisons for values that compare equal with
933-
\tcode{operator==} if the underlying type has padding bits, trap bits, or alternate
934+
\begin{note}
935+
Under cases where the \tcode{memcpy} and \tcode{memcmp} semantics of the compare-and-exchange
936+
operations apply, the outcome might be failed comparisons for values that compare equal with
937+
\tcode{operator==} if the underlying type has trap bits or alternate
934938
representations of the same value. Notably, on implementations conforming to
935939
ISO/IEC/IEEE 60559, floating-point \tcode{-0.0} and \tcode{+0.0}
936940
will not compare equal with \tcode{memcmp} but will compare equal with \tcode{operator==},
937941
and NaNs with the same payload will compare equal with \tcode{memcmp} but will not
938-
compare equal with \tcode{operator==}.\end{note}
942+
compare equal with \tcode{operator==}.
943+
\end{note}
944+
\begin{note}
945+
Because compare-and-exchange acts on an object's value representation,
946+
padding bits that never participate in the object's value representation
947+
are ignored. As a consequence, the following code is guaranteed to avoid
948+
spurious failure:
949+
\begin{codeblock}
950+
struct padded {
951+
char clank = 0x42;
952+
// Padding here.
953+
unsigned biff = 0xC0DEFEFE;
954+
};
955+
atomic<padded> pad = ATOMIC_VAR_INIT({});
956+
957+
bool zap() {
958+
padded expected, desired{0, 0};
959+
return pad.compare_exchange_strong(expected, desired);
960+
}
961+
\end{codeblock}
962+
\end{note}
963+
\begin{note}
964+
For a union with bits that participate in the value representation
965+
of some members but not others, compare-and-exchange might always fail.
966+
This is because such padding bits have an indeteminate value when they
967+
do not participate in the value representation of the active member.
968+
As a consequence, the following code is not guaranteed to ever succeed:
969+
\begin{codeblock}
970+
union pony {
971+
double celestia = 0.;
972+
short luna; // padded
973+
};
974+
atomic<pony> princesses = ATOMIC_VAR_INIT({});
975+
976+
bool party(pony desired) {
977+
pony expected;
978+
return princesses.compare_exchange_strong(expected, desired);
979+
}
980+
\end{codeblock}
981+
\end{note}
939982
\end{itemdescr}
940983

941984
\rSec2[atomics.types.int]{Specializations for integers}

0 commit comments

Comments
 (0)