X-Git-Url: https://git.lttng.org/?p=urcu.git;a=blobdiff_plain;f=doc%2Fuatomic-api.md;fp=doc%2Fuatomic-api.md;h=2dd63c6c76f88b332b0e00595c4e1ffab25fbb2c;hp=0000000000000000000000000000000000000000;hb=dcb9c05a081e2c8d4fe0250f3700e3efb1200cac;hpb=2fec8f05f010408e989356e6f9d8c1e191ba4dfa diff --git a/doc/uatomic-api.md b/doc/uatomic-api.md new file mode 100644 index 0000000..2dd63c6 --- /dev/null +++ b/doc/uatomic-api.md @@ -0,0 +1,124 @@ +Userspace RCU Atomic Operations API +=================================== + +by Mathieu Desnoyers and Paul E. McKenney + +This document describes the `` 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. + + +API +--- + +```c +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()`. + + +```c +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. + + +```c +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. + + +```c +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. + + +```c +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. + + +```c +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. + + +```c +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. + + +```c +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.