|
@@ -269,6 +269,50 @@ And there are a number of things that _must_ or _must_not_ be assumed:
|
|
|
STORE *(A + 4) = Y; STORE *A = X;
|
|
|
STORE {*A, *(A + 4) } = {X, Y};
|
|
|
|
|
|
+And there are anti-guarantees:
|
|
|
+
|
|
|
+ (*) These guarantees do not apply to bitfields, because compilers often
|
|
|
+ generate code to modify these using non-atomic read-modify-write
|
|
|
+ sequences. Do not attempt to use bitfields to synchronize parallel
|
|
|
+ algorithms.
|
|
|
+
|
|
|
+ (*) Even in cases where bitfields are protected by locks, all fields
|
|
|
+ in a given bitfield must be protected by one lock. If two fields
|
|
|
+ in a given bitfield are protected by different locks, the compiler's
|
|
|
+ non-atomic read-modify-write sequences can cause an update to one
|
|
|
+ field to corrupt the value of an adjacent field.
|
|
|
+
|
|
|
+ (*) These guarantees apply only to properly aligned and sized scalar
|
|
|
+ variables. "Properly sized" currently means variables that are
|
|
|
+ the same size as "char", "short", "int" and "long". "Properly
|
|
|
+ aligned" means the natural alignment, thus no constraints for
|
|
|
+ "char", two-byte alignment for "short", four-byte alignment for
|
|
|
+ "int", and either four-byte or eight-byte alignment for "long",
|
|
|
+ on 32-bit and 64-bit systems, respectively. Note that these
|
|
|
+ guarantees were introduced into the C11 standard, so beware when
|
|
|
+ using older pre-C11 compilers (for example, gcc 4.6). The portion
|
|
|
+ of the standard containing this guarantee is Section 3.14, which
|
|
|
+ defines "memory location" as follows:
|
|
|
+
|
|
|
+ memory location
|
|
|
+ either an object of scalar type, or a maximal sequence
|
|
|
+ of adjacent bit-fields all having nonzero width
|
|
|
+
|
|
|
+ NOTE 1: Two threads of execution can update and access
|
|
|
+ separate memory locations without interfering with
|
|
|
+ each other.
|
|
|
+
|
|
|
+ NOTE 2: A bit-field and an adjacent non-bit-field member
|
|
|
+ are in separate memory locations. The same applies
|
|
|
+ to two bit-fields, if one is declared inside a nested
|
|
|
+ structure declaration and the other is not, or if the two
|
|
|
+ are separated by a zero-length bit-field declaration,
|
|
|
+ or if they are separated by a non-bit-field member
|
|
|
+ declaration. It is not safe to concurrently update two
|
|
|
+ bit-fields in the same structure if all members declared
|
|
|
+ between them are also bit-fields, no matter what the
|
|
|
+ sizes of those intervening bit-fields happen to be.
|
|
|
+
|
|
|
|
|
|
=========================
|
|
|
WHAT ARE MEMORY BARRIERS?
|