1.. _atomic_v2:
2
3Atomic Services
4###############
5
6An :dfn:`atomic variable` is one that can be read and modified
7by threads and ISRs in an uninterruptible manner. It is a 32-bit variable on
832-bit machines and a 64-bit variable on 64-bit machines.
9
10.. contents::
11    :local:
12    :depth: 2
13
14Concepts
15********
16
17Any number of atomic variables can be defined (limited only by available RAM).
18
19Using the kernel's atomic APIs to manipulate an atomic variable
20guarantees that the desired operation occurs correctly,
21even if higher priority contexts also manipulate the same variable.
22
23The kernel also supports the atomic manipulation of a single bit
24in an array of atomic variables.
25
26Implementation
27**************
28
29Defining an Atomic Variable
30===========================
31
32An atomic variable is defined using a variable of type :c:type:`atomic_t`.
33
34By default an atomic variable is initialized to zero. However, it can be given
35a different value using :c:macro:`ATOMIC_INIT`:
36
37.. code-block:: c
38
39    atomic_t flags = ATOMIC_INIT(0xFF);
40
41Manipulating an Atomic Variable
42===============================
43
44An atomic variable is manipulated using the APIs listed at the end of
45this section.
46
47The following code shows how an atomic variable can be used to keep track
48of the number of times a function has been invoked. Since the count is
49incremented atomically, there is no risk that it will become corrupted
50in mid-increment if a thread calling the function is interrupted if
51by a higher priority context that also calls the routine.
52
53.. code-block:: c
54
55    atomic_t call_count;
56
57    int call_counting_routine(void)
58    {
59        /* increment invocation counter */
60        atomic_inc(&call_count);
61
62        /* do rest of routine's processing */
63        ...
64    }
65
66Manipulating an Array of Atomic Variables
67=========================================
68
69An array of 32-bit atomic variables can be defined in the conventional manner.
70However, you can also define an N-bit array of atomic variables using
71:c:macro:`ATOMIC_DEFINE`.
72
73A single bit in array of atomic variables can be manipulated using
74the APIs listed at the end of this section that end with :c:func:`_bit`.
75
76The following code shows how a set of 200 flag bits can be implemented
77using an array of atomic variables.
78
79.. code-block:: c
80
81    #define NUM_FLAG_BITS 200
82
83    ATOMIC_DEFINE(flag_bits, NUM_FLAG_BITS);
84
85    /* set specified flag bit & return its previous value */
86    int set_flag_bit(int bit_position)
87    {
88        return (int)atomic_set_bit(flag_bits, bit_position);
89    }
90
91Memory Ordering
92===============
93
94For consistency and correctness, all Zephyr atomic APIs are expected
95to include a full memory barrier (in the sense of e.g. "serializing"
96instructions on x86, "DMB" on ARM, or a "sequentially consistent"
97operation as defined by the C++ memory model) where needed by hardware
98to guarantee a reliable picture across contexts.  Any
99architecture-specific implementations are responsible for ensuring
100this behavior.
101
102Suggested Uses
103**************
104
105Use an atomic variable to implement critical section processing that only
106requires the manipulation of a single 32-bit value.
107
108Use multiple atomic variables to implement critical section processing
109on a set of flag bits in a bit array longer than 32 bits.
110
111.. note::
112    Using atomic variables is typically far more efficient than using
113    other techniques to implement critical sections such as using a mutex
114    or locking interrupts.
115
116Configuration Options
117*********************
118
119Related configuration options:
120
121* :kconfig:option:`CONFIG_ATOMIC_OPERATIONS_BUILTIN`
122* :kconfig:option:`CONFIG_ATOMIC_OPERATIONS_ARCH`
123* :kconfig:option:`CONFIG_ATOMIC_OPERATIONS_C`
124
125API Reference
126*************
127
128.. important::
129    All atomic services APIs can be used by both threads and ISRs.
130
131.. doxygengroup:: atomic_apis
132