Commit daf1aab9 authored by Paul E. McKenney's avatar Paul E. McKenney

documentation: Clarify memory-barrier semantics of atomic operations

All value-returning atomic read-modify-write operations must provide full
memory-barrier semantics on both sides of the operation.  This commit
clarifies the documentation to make it clear that these memory-barrier
semantics are provided by the operations themselves, not by their callers.
Reported-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent f1360570
...@@ -201,11 +201,11 @@ These routines add 1 and subtract 1, respectively, from the given ...@@ -201,11 +201,11 @@ These routines add 1 and subtract 1, respectively, from the given
atomic_t and return the new counter value after the operation is atomic_t and return the new counter value after the operation is
performed. performed.
Unlike the above routines, it is required that explicit memory Unlike the above routines, it is required that these primitives
barriers are performed before and after the operation. It must be include explicit memory barriers that are performed before and after
done such that all memory operations before and after the atomic the operation. It must be done such that all memory operations before
operation calls are strongly ordered with respect to the atomic and after the atomic operation calls are strongly ordered with respect
operation itself. to the atomic operation itself.
For example, it should behave as if a smp_mb() call existed both For example, it should behave as if a smp_mb() call existed both
before and after the atomic operation. before and after the atomic operation.
...@@ -233,21 +233,21 @@ These two routines increment and decrement by 1, respectively, the ...@@ -233,21 +233,21 @@ These two routines increment and decrement by 1, respectively, the
given atomic counter. They return a boolean indicating whether the given atomic counter. They return a boolean indicating whether the
resulting counter value was zero or not. resulting counter value was zero or not.
It requires explicit memory barrier semantics around the operation as Again, these primitives provide explicit memory barrier semantics around
above. the atomic operation.
int atomic_sub_and_test(int i, atomic_t *v); int atomic_sub_and_test(int i, atomic_t *v);
This is identical to atomic_dec_and_test() except that an explicit This is identical to atomic_dec_and_test() except that an explicit
decrement is given instead of the implicit "1". It requires explicit decrement is given instead of the implicit "1". This primitive must
memory barrier semantics around the operation. provide explicit memory barrier semantics around the operation.
int atomic_add_negative(int i, atomic_t *v); int atomic_add_negative(int i, atomic_t *v);
The given increment is added to the given atomic counter value. A The given increment is added to the given atomic counter value. A boolean
boolean is return which indicates whether the resulting counter value is return which indicates whether the resulting counter value is negative.
is negative. It requires explicit memory barrier semantics around the This primitive must provide explicit memory barrier semantics around
operation. the operation.
Then: Then:
...@@ -257,7 +257,7 @@ This performs an atomic exchange operation on the atomic variable v, setting ...@@ -257,7 +257,7 @@ This performs an atomic exchange operation on the atomic variable v, setting
the given new value. It returns the old value that the atomic variable v had the given new value. It returns the old value that the atomic variable v had
just before the operation. just before the operation.
atomic_xchg requires explicit memory barriers around the operation. atomic_xchg must provide explicit memory barriers around the operation.
int atomic_cmpxchg(atomic_t *v, int old, int new); int atomic_cmpxchg(atomic_t *v, int old, int new);
...@@ -266,7 +266,7 @@ with the given old and new values. Like all atomic_xxx operations, ...@@ -266,7 +266,7 @@ with the given old and new values. Like all atomic_xxx operations,
atomic_cmpxchg will only satisfy its atomicity semantics as long as all atomic_cmpxchg will only satisfy its atomicity semantics as long as all
other accesses of *v are performed through atomic_xxx operations. other accesses of *v are performed through atomic_xxx operations.
atomic_cmpxchg requires explicit memory barriers around the operation. atomic_cmpxchg must provide explicit memory barriers around the operation.
The semantics for atomic_cmpxchg are the same as those defined for 'cas' The semantics for atomic_cmpxchg are the same as those defined for 'cas'
below. below.
...@@ -279,8 +279,8 @@ If the atomic value v is not equal to u, this function adds a to v, and ...@@ -279,8 +279,8 @@ If the atomic value v is not equal to u, this function adds a to v, and
returns non zero. If v is equal to u then it returns zero. This is done as returns non zero. If v is equal to u then it returns zero. This is done as
an atomic operation. an atomic operation.
atomic_add_unless requires explicit memory barriers around the operation atomic_add_unless must provide explicit memory barriers around the
unless it fails (returns 0). operation unless it fails (returns 0).
atomic_inc_not_zero, equivalent to atomic_add_unless(v, 1, 0) atomic_inc_not_zero, equivalent to atomic_add_unless(v, 1, 0)
...@@ -460,9 +460,9 @@ the return value into an int. There are other places where things ...@@ -460,9 +460,9 @@ the return value into an int. There are other places where things
like this occur as well. like this occur as well.
These routines, like the atomic_t counter operations returning values, These routines, like the atomic_t counter operations returning values,
require explicit memory barrier semantics around their execution. All must provide explicit memory barrier semantics around their execution.
memory operations before the atomic bit operation call must be made All memory operations before the atomic bit operation call must be
visible globally before the atomic bit operation is made visible. made visible globally before the atomic bit operation is made visible.
Likewise, the atomic bit operation must be visible globally before any Likewise, the atomic bit operation must be visible globally before any
subsequent memory operation is made visible. For example: subsequent memory operation is made visible. For example:
...@@ -536,8 +536,9 @@ except that two underscores are prefixed to the interface name. ...@@ -536,8 +536,9 @@ except that two underscores are prefixed to the interface name.
These non-atomic variants also do not require any special memory These non-atomic variants also do not require any special memory
barrier semantics. barrier semantics.
The routines xchg() and cmpxchg() need the same exact memory barriers The routines xchg() and cmpxchg() must provide the same exact
as the atomic and bit operations returning values. memory-barrier semantics as the atomic and bit operations returning
values.
Spinlocks and rwlocks have memory barrier expectations as well. Spinlocks and rwlocks have memory barrier expectations as well.
The rule to follow is simple: The rule to follow is simple:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment