2dd63c6c76f88b332b0e00595c4e1ffab25fbb2c
[urcu.git] / doc / uatomic-api.md
1 Userspace RCU Atomic Operations API
2 ===================================
3
4 by Mathieu Desnoyers and Paul E. McKenney
5
6 This document describes the `<urcu/uatomic.h>` API. Those are the atomic
7 operations provided by the Userspace RCU library. The general rule
8 regarding memory barriers is that only `uatomic_xchg()`,
9 `uatomic_cmpxchg()`, `uatomic_add_return()`, and `uatomic_sub_return()` imply
10 full memory barriers before and after the atomic operation. Other
11 primitives don't guarantee any memory barrier.
12
13 Only atomic operations performed on integers (`int` and `long`, signed
14 and unsigned) are supported on all architectures. Some architectures
15 also support 1-byte and 2-byte atomic operations. Those respectively
16 have `UATOMIC_HAS_ATOMIC_BYTE` and `UATOMIC_HAS_ATOMIC_SHORT` defined when
17 `uatomic.h` is included. An architecture trying to perform an atomic write
18 to a type size not supported by the architecture will trigger an illegal
19 instruction.
20
21 In the description below, `type` is a type that can be atomically
22 written to by the architecture. It needs to be at most word-sized, and
23 its alignment needs to greater or equal to its size.
24
25
26 API
27 ---
28
29 ```c
30 void uatomic_set(type *addr, type v)
31 ```
32
33 Atomically write `v` into `addr`. By "atomically", we mean that no
34 concurrent operation that reads from addr will see partial
35 effects of `uatomic_set()`.
36
37
38 ```c
39 type uatomic_read(type *addr)
40 ```
41
42 Atomically read `v` from `addr`. By "atomically", we mean that
43 `uatomic_read()` cannot see a partial effect of any concurrent
44 uatomic update.
45
46
47 ```c
48 type uatomic_cmpxchg(type *addr, type old, type new)
49 ```
50
51 An atomic read-modify-write operation that performs this
52 sequence of operations atomically: check if `addr` contains `old`.
53 If true, then replace the content of `addr` by `new`. Return the
54 value previously contained by `addr`. This function imply a full
55 memory barrier before and after the atomic operation.
56
57
58 ```c
59 type uatomic_xchg(type *addr, type new)
60 ```
61
62 An atomic read-modify-write operation that performs this sequence
63 of operations atomically: replace the content of `addr` by `new`,
64 and return the value previously contained by `addr`. This
65 function imply a full memory barrier before and after the atomic
66 operation.
67
68
69 ```c
70 type uatomic_add_return(type *addr, type v)
71 type uatomic_sub_return(type *addr, type v)
72 ```
73
74 An atomic read-modify-write operation that performs this
75 sequence of operations atomically: increment/decrement the
76 content of `addr` by `v`, and return the resulting value. This
77 function imply a full memory barrier before and after the atomic
78 operation.
79
80
81 ```c
82 void uatomic_and(type *addr, type mask)
83 void uatomic_or(type *addr, type mask)
84 ```
85
86 Atomically write the result of bitwise "and"/"or" between the
87 content of `addr` and `mask` into `addr`.
88
89 These operations do not necessarily imply memory barriers.
90 If memory barriers are needed, they may be provided by explicitly using
91 `cmm_smp_mb__before_uatomic_and()`, `cmm_smp_mb__after_uatomic_and()`,
92 `cmm_smp_mb__before_uatomic_or()`, and `cmm_smp_mb__after_uatomic_or()`.
93 These explicit barriers are no-ops on architectures in which the underlying
94 atomic instructions implicitly supply the needed memory barriers.
95
96
97 ```c
98 void uatomic_add(type *addr, type v)
99 void uatomic_sub(type *addr, type v)
100 ```
101
102 Atomically increment/decrement the content of `addr` by `v`.
103 These operations do not necessarily imply memory barriers.
104 If memory barriers are needed, they may be provided by
105 explicitly using `cmm_smp_mb__before_uatomic_add()`,
106 `cmm_smp_mb__after_uatomic_add()`, `cmm_smp_mb__before_uatomic_sub()`, and
107 `cmm_smp_mb__after_uatomic_sub()`. These explicit barriers are
108 no-ops on architectures in which the underlying atomic
109 instructions implicitly supply the needed memory barriers.
110
111
112 ```c
113 void uatomic_inc(type *addr)
114 void uatomic_dec(type *addr)
115 ```
116
117 Atomically increment/decrement the content of `addr` by 1.
118 These operations do not necessarily imply memory barriers.
119 If memory barriers are needed, they may be provided by
120 explicitly using `cmm_smp_mb__before_uatomic_inc()`,
121 `cmm_smp_mb__after_uatomic_inc()`, `cmm_smp_mb__before_uatomic_dec()`,
122 and `cmm_smp_mb__after_uatomic_dec()`. These explicit barriers are
123 no-ops on architectures in which the underlying atomic
124 instructions implicitly supply the needed memory barriers.
This page took 0.042196 seconds and 3 git commands to generate.