From: Eli Friedman However, LLVM is not allowed to transform the former to the latter: it could
- introduce undefined behavior if another thread can access x at the same time.
- (This example is particularly of interest because before the concurrency model
- was implemented, LLVM would perform this transformation.)
Note that speculative loads are allowed; a load which
is part of a race returns undef, but does not have undefined
@@ -177,7 +178,7 @@ void f(int* a) {
In order to achieve a balance between performance and necessary guarantees, there are six levels of atomicity. They are listed in order of strength; each level includes all the guarantees of the previous level except for - Acquire/Release.
+ Acquire/Release. (See also LangRef.)NotAtomic is the obvious, a load or store which is not atomic. (This isn't really a level of atomicity, but is listed here for comparison.) This is - essentially a regular load or store. If code accesses a memory location - from multiple threads at the same time, the resulting loads return - 'undef'.
+ essentially a regular load or store. If there is a race on a given memory + location, loads from that location return undef.For a more informal introduction to this model, see the +LLVM Atomic Instructions and Concurrency Guide. +
We define a happens-before partial order as the least partial order that
Given that definition, Rbyte is defined as follows:
sig_atomic_t in C/C++, and may be used for accesses to
+ addresses which do not behave like normal memory. It does not generally
+ provide cross-thread synchronization.)
+ fence instructions
+check those specs (see spec references in the
+atomics guide).
+fence instructions
treat these orderings somewhat differently since they don't take an address.
See that instruction's documentation for details.
+For a simpler introduction to the ordering constraints, see the +LLVM Atomic Instructions and Concurrency Guide.
+unorderedmonotonic (or stronger) operations on the same address. If an
address is written monotonically by one thread, and other threads
monotonically read that address repeatedly, the other threads must
-eventually see the write. This is intended to model C++'s relaxed atomic
-variables.memory_order_relaxed.acquiremonotonic, if this operation
reads a value written by a release atomic operation, it
-synchronizes-with that operation.memory_order_acquire.
releasemonotonic,
-a synchronizes-with edge may be formed by an acquire
-operation.acquire
+operation. This is intended to model C++'s memory_order_release.
acq_rel (acquire+release)acquire and release operation on its address.acquire and release operation on its address.
+This corresponds to the C++0x/C1x memory_order_acq_rel.
seq_cst (sequentially consistent)acq_rel
(acquire for an operation which only reads, release
@@ -1637,9 +1652,8 @@ for an operation which only writes), there is a global total order on all
sequentially-consistent operations on all addresses, which is consistent with
the happens-before partial order and with the modification orders of
all the affected addresses. Each sequentially-consistent read sees the last
-preceding write to the same address in this global order. This is intended
-to model C++'s sequentially-consistent atomic variables and Java's volatile
-shared variables.memory_order_seq_cst and Java volatile.If an atomic operation is marked singlethread,