From 234bccd1947bb06e35dce6312df2daa7ccfff4eb Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Mon, 22 Aug 2011 21:35:27 +0000 Subject: Some minor wording updates and cross-linking for atomic docs. Explicitly note that we don't try to portably define what volatile in LLVM IR means. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138274 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/Atomics.html | 17 +++++++++-------- docs/LangRef.html | 36 +++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 19 deletions(-) (limited to 'docs') diff --git a/docs/Atomics.html b/docs/Atomics.html index 357f43167b..d4a3795b9d 100644 --- a/docs/Atomics.html +++ b/docs/Atomics.html @@ -121,9 +121,10 @@ void f(int* a) {

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.)

+ indirectly 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.)

@@ -188,15 +189,15 @@ void f(int* a) {

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.

Relevant standard
This is intended to match shared variables in C/C++, and to be used in any other context where memory access is necessary, and - a race is impossible. + a race is impossible. (The precise definition is in + LangRef.)
Notes for frontends
The rule is essentially that all memory accessed with basic loads and stores by multiple threads should be protected by a lock or other diff --git a/docs/LangRef.html b/docs/LangRef.html index bf834c211a..fa4d74b67f 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -1497,6 +1497,9 @@ or to register signal handlers. Nonetheless, there are platform-specific ways to create them, and we define LLVM IR's behavior in their presence. This model is inspired by the C++0x memory model.

+

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

    @@ -1533,7 +1536,12 @@ any write to the same byte, except:

    Given that definition, Rbyte is defined as follows:

      -
    • If there is no write to the same byte that happens before +
    • If R is volatile, the result is target-dependent. (Volatile + is supposed to give guarantees which can support + 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.) +
    • Otherwise, if there is no write to the same byte that happens before Rbyte, Rbyte returns undef for that byte.
    • Otherwise, if Rbyte may see exactly one write, @@ -1590,10 +1598,15 @@ as if it writes to the relevant surrounding bytes. that determines which other atomic instructions on the same address they synchronize with. These semantics are borrowed from Java and C++0x, but are somewhat more colloquial. If these descriptions aren't precise enough, -check those specs. 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.

      +
      unordered
      The set of values that can be read is governed by the happens-before @@ -1618,18 +1631,20 @@ address's modification order. This disallows reordering of monotonic (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.
      +eventually see the write. This corresponds to the C++0x/C1x +memory_order_relaxed.
acquire
In addition to the guarantees of monotonic, if this operation reads a value written by a release atomic operation, it -synchronizes-with that operation.
+synchronizes-with that operation. This corresponds to the C++0x/C1x +memory_order_acquire.
release
In addition to the guarantees of monotonic, -a synchronizes-with edge may be formed by an acquire -operation.
+a synchronizes-with edge may be formed with an acquire +operation. This is intended to model C++'s memory_order_release.
acq_rel (acquire+release)
Acts as both an -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)
In addition to the guarantees of 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.
+preceding write to the same address in this global order. This corresponds +to the C++0x/C1x memory_order_seq_cst and Java volatile.

If an atomic operation is marked singlethread, -- cgit v1.2.3