Document uatomic operations
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 18 May 2012 03:18:35 +0000 (23:18 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 18 May 2012 03:18:35 +0000 (23:18 -0400)
Document each atomic operation provided by urcu/uatomic.h, along with
their memory barrier guarantees.

Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
doc/Makefile.am
doc/uatomic-api.txt [new file with mode: 0644]

index 27d37935b39655ac9a1933de9b89318e5a59f601..34226531250d5568c52b5c1149474dcf43d2213f 100644 (file)
@@ -1 +1 @@
-dist_doc_DATA = rcu-api.txt cds-api.txt
+dist_doc_DATA = rcu-api.txt cds-api.txt uatomic-api.txt
diff --git a/doc/uatomic-api.txt b/doc/uatomic-api.txt
new file mode 100644 (file)
index 0000000..edb7d4f
--- /dev/null
@@ -0,0 +1,102 @@
+Userspace RCU Atomic Operations API
+by Mathieu Desnoyers and Paul E. McKenney
+
+
+This document describes the <urcu/uatomic.h> API. Those are the atomic
+operations provided by the Userspace RCU library. The general rule
+regarding memory barriers is that only uatomic_xchg(),
+uatomic_cmpxchg(), uatomic_add_return(), and uatomic_sub_return() imply
+full memory barriers before and after the atomic operation. Other
+primitives don't guarantee any memory barrier.
+
+Only atomic operations performed on integers ("int" and "long", signed
+and unsigned) are supported on all architectures. Some architectures
+also support 1-byte and 2-byte atomic operations. Those respectively
+have UATOMIC_HAS_ATOMIC_BYTE and UATOMIC_HAS_ATOMIC_SHORT defined when
+uatomic.h is included. An architecture trying to perform an atomic write
+to a type size not supported by the architecture will trigger an illegal
+instruction.
+
+In the description below, "type" is a type that can be atomically
+written to by the architecture. It needs to be at most word-sized, and
+its alignment needs to greater or equal to its size.
+
+void uatomic_set(type *addr, type v)
+
+       Atomically write @v into @addr. By "atomically", we mean that no
+       concurrent operation that reads from addr will see partial
+       effects of uatomic_set().
+
+type uatomic_read(type *addr)
+
+       Atomically read @v from @addr. By "atomically", we mean that
+       uatomic_read() cannot see a partial effect of any concurrent
+       uatomic update.
+
+type uatomic_cmpxchg(type *addr, type old, type new)
+
+       An atomic read-modify-write operation that performs this
+       sequence of operations atomically: check if @addr contains @old.
+       If true, then replace the content of @addr by @new. Return the
+       value previously contained by @addr. This function imply a full
+       memory barrier before and after the atomic operation.
+
+type uatomic_xchg(type *addr, type new)
+
+       An atomic read-modify-write operation that performs this sequence
+       of operations atomically: replace the content of @addr by @new,
+       and return the value previously contained by @addr. This
+       function imply a full memory barrier before and after the atomic
+       operation.
+
+type uatomic_add_return(type *addr, type v)
+type uatomic_sub_return(type *addr, type v)
+
+       An atomic read-modify-write operation that performs this
+       sequence of operations atomically: increment/decrement the
+       content of @addr by @v, and return the resulting value. This
+       function imply a full memory barrier before and after the atomic
+       operation.
+
+void uatomic_and(type *addr, type mask)
+void uatomic_or(type *addr, type mask)
+
+       Atomically write the result of bitwise "and"/"or" between the
+       content of @addr and @mask into @addr.
+       These operations do not necessarily imply memory barriers.
+       If memory barriers are needed, they may be provided by
+       explicitly using
+       cmm_smp_mb__before_uatomic_and(),
+       cmm_smp_mb__after_uatomic_and(),
+       cmm_smp_mb__before_uatomic_or(), and
+       cmm_smp_mb__after_uatomic_or(). These explicit barriers are
+       no-ops on architectures in which the underlying atomic
+       instructions implicitly supply the needed memory barriers.
+
+void uatomic_add(type *addr, type v)
+void uatomic_sub(type *addr, type v)
+
+       Atomically increment/decrement the content of @addr by @v.
+       These operations do not necessarily imply memory barriers.
+       If memory barriers are needed, they may be provided by
+       explicitly using
+       cmm_smp_mb__before_uatomic_add(),
+       cmm_smp_mb__after_uatomic_add(),
+       cmm_smp_mb__before_uatomic_sub(), and
+       cmm_smp_mb__after_uatomic_sub(). These explicit barriers are 
+       no-ops on architectures in which the underlying atomic
+       instructions implicitly supply the needed memory barriers.
+
+void uatomic_inc(type *addr)
+void uatomic_dec(type *addr)
+
+       Atomically increment/decrement the content of @addr by 1.
+       These operations do not necessarily imply memory barriers.
+       If memory barriers are needed, they may be provided by
+       explicitly using
+       cmm_smp_mb__before_uatomic_inc(),
+       cmm_smp_mb__after_uatomic_inc(),
+       cmm_smp_mb__before_uatomic_dec(), and
+       cmm_smp_mb__after_uatomic_dec(). These explicit barriers are
+       no-ops on architectures in which the underlying atomic
+       instructions implicitly supply the needed memory barriers.
This page took 0.026361 seconds and 4 git commands to generate.