Deprecate atomic_mb_read and atomic_mb_set; it is not really possible to
use them correctly because they do not interoperate with sequentially-consistent
RMW operations.
Signed-off-by: Paolo Bonzini <address@hidden>
---
docs/devel/atomics.rst | 290 ++++++++++++++++-------------------------
1 file changed, 114 insertions(+), 176 deletions(-)
@@ -24,6 +29,14 @@ Macros defined by ``qemu/atomic.h`` fall in three camps:
- sequentially consistent atomic access: everything else.
+In general, use of ``qemu/atomic.h`` should be wrapped with more easily
+used data structures (e.g. the lock-free singly-liked list operations
+``QSLIST_INSERT_HEAD_ATOMIC`` and ``QSLIST_MOVE_ATOMIC``) or synchronization
+primitives (such as RCU, ``QemuEvent`` or ``QemuLockCnt``). Bare use of
+atomic operations and memory barriers should be limited to inter-thread
+checking of flags and documented thoroughly.
+
+
Compiler memory barrier
=======================
@@ -85,36 +98,14 @@ Similar operations return the new value of ``*ptr``::
typeof(*ptr) atomic_or_fetch(ptr, val)
typeof(*ptr) atomic_xor_fetch(ptr, val)
-Sequentially consistent loads and stores can be done using::
-
- atomic_fetch_add(ptr, 0) for loads
- atomic_xchg(ptr, val) for stores
+These operations operate on any type that is as wide as an int or smaller.
-However, they are quite expensive on some platforms, notably POWER and
-Arm. Therefore, qemu/atomic.h provides two primitives with slightly
-weaker constraints::
+``qemu/atomic.h`` also provides sequentially consistent loads and stores can::
typeof(*ptr) atomic_mb_read(ptr)
void atomic_mb_set(ptr, val)
-The semantics of these primitives map to Java volatile variables,
-and are strongly related to memory barriers as used in the Linux
-kernel (see below).
-
-As long as you use atomic_mb_read and atomic_mb_set, accesses cannot
-be reordered with each other, and it is also not possible to reorder
-"normal" accesses around them.
-
-However, and this is the important difference between
-atomic_mb_read/atomic_mb_set and sequential consistency, it is important
-for both threads to access the same volatile variable. It is not the
-case that everything visible to thread A when it writes volatile field f
-becomes visible to thread B after it reads volatile field g. The store
-and load have to "match" (i.e., be performed on the same volatile
-field) to achieve the right semantics.
-
-
-These operations operate on any type that is as wide as an int or smaller.
+which however are deprecated.