xref: /nrf52832-nimble/nordic/nrfx/soc/nrfx_atomic.h (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
1*150812a8SEvalZero /*
2*150812a8SEvalZero  * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
3*150812a8SEvalZero  * All rights reserved.
4*150812a8SEvalZero  *
5*150812a8SEvalZero  * Redistribution and use in source and binary forms, with or without
6*150812a8SEvalZero  * modification, are permitted provided that the following conditions are met:
7*150812a8SEvalZero  *
8*150812a8SEvalZero  * 1. Redistributions of source code must retain the above copyright notice, this
9*150812a8SEvalZero  *    list of conditions and the following disclaimer.
10*150812a8SEvalZero  *
11*150812a8SEvalZero  * 2. Redistributions in binary form must reproduce the above copyright
12*150812a8SEvalZero  *    notice, this list of conditions and the following disclaimer in the
13*150812a8SEvalZero  *    documentation and/or other materials provided with the distribution.
14*150812a8SEvalZero  *
15*150812a8SEvalZero  * 3. Neither the name of the copyright holder nor the names of its
16*150812a8SEvalZero  *    contributors may be used to endorse or promote products derived from this
17*150812a8SEvalZero  *    software without specific prior written permission.
18*150812a8SEvalZero  *
19*150812a8SEvalZero  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*150812a8SEvalZero  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*150812a8SEvalZero  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*150812a8SEvalZero  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23*150812a8SEvalZero  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*150812a8SEvalZero  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*150812a8SEvalZero  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*150812a8SEvalZero  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*150812a8SEvalZero  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*150812a8SEvalZero  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*150812a8SEvalZero  * POSSIBILITY OF SUCH DAMAGE.
30*150812a8SEvalZero  */
31*150812a8SEvalZero 
32*150812a8SEvalZero #ifndef NRFX_ATOMIC_H__
33*150812a8SEvalZero #define NRFX_ATOMIC_H__
34*150812a8SEvalZero 
35*150812a8SEvalZero #include <nrfx.h>
36*150812a8SEvalZero 
37*150812a8SEvalZero #ifdef __cplusplus
38*150812a8SEvalZero extern "C" {
39*150812a8SEvalZero #endif
40*150812a8SEvalZero 
41*150812a8SEvalZero /**
42*150812a8SEvalZero  * @defgroup nrfx_atomic Atomic operations API
43*150812a8SEvalZero  * @ingroup nrfx
44*150812a8SEvalZero  * @{
45*150812a8SEvalZero  *
46*150812a8SEvalZero  * @brief This module implements C11 stdatomic.h simplified API.
47*150812a8SEvalZero  *
48*150812a8SEvalZero  * At this point, only Cortex-M3 and M4 cores are supported (LDREX/STREX instructions).
49*150812a8SEvalZero  * Atomic types are limited to @ref nrfx_atomic_u32_t and @ref nrfx_atomic_flag_t.
50*150812a8SEvalZero  */
51*150812a8SEvalZero 
52*150812a8SEvalZero 
53*150812a8SEvalZero /**
54*150812a8SEvalZero  * @brief Atomic 32-bit unsigned type.
55*150812a8SEvalZero  */
56*150812a8SEvalZero typedef volatile uint32_t nrfx_atomic_u32_t;
57*150812a8SEvalZero 
58*150812a8SEvalZero /**
59*150812a8SEvalZero  * @brief Atomic 1-bit flag type (technically 32-bit).
60*150812a8SEvalZero  */
61*150812a8SEvalZero typedef volatile uint32_t nrfx_atomic_flag_t;
62*150812a8SEvalZero 
63*150812a8SEvalZero /**
64*150812a8SEvalZero  * @brief Function for storing a value to an atomic object and returning its previous value.
65*150812a8SEvalZero  *
66*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
67*150812a8SEvalZero  * @param[in] value     Value to store.
68*150812a8SEvalZero  *
69*150812a8SEvalZero  * @return Previous value stored in the atomic object.
70*150812a8SEvalZero  */
71*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_store(nrfx_atomic_u32_t * p_data, uint32_t value);
72*150812a8SEvalZero 
73*150812a8SEvalZero /**
74*150812a8SEvalZero  * @brief Function for storing a value to an atomic object and returning its new value.
75*150812a8SEvalZero  *
76*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
77*150812a8SEvalZero  * @param[in] value     Value to store.
78*150812a8SEvalZero  *
79*150812a8SEvalZero  * @return New value stored in the atomic object.
80*150812a8SEvalZero  */
81*150812a8SEvalZero uint32_t nrfx_atomic_u32_store(nrfx_atomic_u32_t * p_data, uint32_t value);
82*150812a8SEvalZero 
83*150812a8SEvalZero /**
84*150812a8SEvalZero  * @brief Function for running a logical OR operation on an atomic object
85*150812a8SEvalZero  *        and returning its previous value.
86*150812a8SEvalZero  *
87*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
88*150812a8SEvalZero  * @param[in] value     Value of the second operand in the OR operation.
89*150812a8SEvalZero  *
90*150812a8SEvalZero  * @return Previous value stored in the atomic object.
91*150812a8SEvalZero  */
92*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_or(nrfx_atomic_u32_t * p_data, uint32_t value);
93*150812a8SEvalZero 
94*150812a8SEvalZero /**
95*150812a8SEvalZero  * @brief Function for running a logical OR operation on an atomic object
96*150812a8SEvalZero  *        and returning its new value.
97*150812a8SEvalZero  *
98*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
99*150812a8SEvalZero  * @param[in] value     Value of the second operand in the OR operation.
100*150812a8SEvalZero  *
101*150812a8SEvalZero  * @return New value stored in the atomic object.
102*150812a8SEvalZero  */
103*150812a8SEvalZero uint32_t nrfx_atomic_u32_or(nrfx_atomic_u32_t * p_data, uint32_t value);
104*150812a8SEvalZero 
105*150812a8SEvalZero /**
106*150812a8SEvalZero  * @brief Function for running a logical AND operation on an atomic object
107*150812a8SEvalZero  *        and returning its previous value.
108*150812a8SEvalZero  *
109*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
110*150812a8SEvalZero  * @param[in] value     Value of the second operand in the AND operation.
111*150812a8SEvalZero  *
112*150812a8SEvalZero  * @return Previous value stored in the atomic object.
113*150812a8SEvalZero  */
114*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_and(nrfx_atomic_u32_t * p_data, uint32_t value);
115*150812a8SEvalZero 
116*150812a8SEvalZero /**
117*150812a8SEvalZero  * @brief Function for running a logical AND operation on an atomic object
118*150812a8SEvalZero  *        and returning its new value.
119*150812a8SEvalZero  *
120*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
121*150812a8SEvalZero  * @param[in] value     Value of the second operand in the AND operation.
122*150812a8SEvalZero  *
123*150812a8SEvalZero  * @return New value stored in the atomic object.
124*150812a8SEvalZero  */
125*150812a8SEvalZero uint32_t nrfx_atomic_u32_and(nrfx_atomic_u32_t * p_data, uint32_t value);
126*150812a8SEvalZero 
127*150812a8SEvalZero /**
128*150812a8SEvalZero  * @brief Function for running a logical XOR operation on an atomic object
129*150812a8SEvalZero  *        and returning its previous value.
130*150812a8SEvalZero  *
131*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
132*150812a8SEvalZero  * @param[in] value     Value of the second operand in the XOR operation.
133*150812a8SEvalZero  *
134*150812a8SEvalZero  * @return Previous value stored in the atomic object.
135*150812a8SEvalZero  */
136*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_xor(nrfx_atomic_u32_t * p_data, uint32_t value);
137*150812a8SEvalZero 
138*150812a8SEvalZero /**
139*150812a8SEvalZero  * @brief Function for running a logical XOR operation on an atomic object
140*150812a8SEvalZero  *        and returning its new value.
141*150812a8SEvalZero  *
142*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
143*150812a8SEvalZero  * @param[in] value     Value of the second operand in the XOR operation.
144*150812a8SEvalZero  *
145*150812a8SEvalZero  * @return New value stored in the atomic object.
146*150812a8SEvalZero  */
147*150812a8SEvalZero uint32_t nrfx_atomic_u32_xor(nrfx_atomic_u32_t * p_data, uint32_t value);
148*150812a8SEvalZero 
149*150812a8SEvalZero /**
150*150812a8SEvalZero  * @brief Function for running an arithmetic ADD operation on an atomic object
151*150812a8SEvalZero  *        and returning its previous value.
152*150812a8SEvalZero  *
153*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
154*150812a8SEvalZero  * @param[in] value     Value of the second operand in the ADD operation.
155*150812a8SEvalZero  *
156*150812a8SEvalZero  * @return Previous value stored in the atomic object.
157*150812a8SEvalZero  */
158*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_add(nrfx_atomic_u32_t * p_data, uint32_t value);
159*150812a8SEvalZero 
160*150812a8SEvalZero /**
161*150812a8SEvalZero  * @brief Function for running an arithmetic ADD operation on an atomic object
162*150812a8SEvalZero  *        and returning its new value.
163*150812a8SEvalZero  *
164*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
165*150812a8SEvalZero  * @param[in] value     Value of the second operand in the ADD operation.
166*150812a8SEvalZero  *
167*150812a8SEvalZero  * @return New value stored in the atomic object.
168*150812a8SEvalZero  */
169*150812a8SEvalZero uint32_t nrfx_atomic_u32_add(nrfx_atomic_u32_t * p_data, uint32_t value);
170*150812a8SEvalZero 
171*150812a8SEvalZero /**
172*150812a8SEvalZero  * @brief Function for running an arithmetic SUB operation on an atomic object
173*150812a8SEvalZero  *        and returning its previous value.
174*150812a8SEvalZero  *
175*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
176*150812a8SEvalZero  * @param[in] value     Value of the second operand in the SUB operation.
177*150812a8SEvalZero  *
178*150812a8SEvalZero  * @return Old value stored in the atomic object.
179*150812a8SEvalZero  */
180*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_sub(nrfx_atomic_u32_t * p_data, uint32_t value);
181*150812a8SEvalZero 
182*150812a8SEvalZero /**
183*150812a8SEvalZero  * @brief Function for running an arithmetic SUB operation on an atomic object
184*150812a8SEvalZero  *        and returning its new value.
185*150812a8SEvalZero  *
186*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
187*150812a8SEvalZero  * @param[in] value     Value of the second operand in the SUB operation.
188*150812a8SEvalZero  *
189*150812a8SEvalZero  * @return New value stored in the atomic object.
190*150812a8SEvalZero  */
191*150812a8SEvalZero uint32_t nrfx_atomic_u32_sub(nrfx_atomic_u32_t * p_data, uint32_t value);
192*150812a8SEvalZero 
193*150812a8SEvalZero /**
194*150812a8SEvalZero  * @brief Function for atomic conditional value replacement.
195*150812a8SEvalZero  *
196*150812a8SEvalZero  * Atomically compares the value pointed to by @p p_data with the value pointed to by @p p_expected.
197*150812a8SEvalZero  * If those are equal, replaces the former with desired. Otherwise, loads the actual value
198*150812a8SEvalZero  * pointed to by @p p_data into @p *p_expected.
199*150812a8SEvalZero  *
200*150812a8SEvalZero  * @param p_data     Atomic memory pointer to test and modify.
201*150812a8SEvalZero  * @param p_expected Pointer to the test value.
202*150812a8SEvalZero  * @param desired    Value to be stored to atomic memory.
203*150812a8SEvalZero  *
204*150812a8SEvalZero  * @retval true  @p *p_data was equal to @p *p_expected.
205*150812a8SEvalZero  * @retval false @p *p_data was not equal to @p *p_expected.
206*150812a8SEvalZero  */
207*150812a8SEvalZero bool nrfx_atomic_u32_cmp_exch(nrfx_atomic_u32_t * p_data,
208*150812a8SEvalZero                               uint32_t *         p_expected,
209*150812a8SEvalZero                               uint32_t           desired);
210*150812a8SEvalZero 
211*150812a8SEvalZero /**
212*150812a8SEvalZero  * @brief Function for running an arithmetic SUB operation on an atomic object
213*150812a8SEvalZero  *        if object >= value, and returning its previous value.
214*150812a8SEvalZero  *
215*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
216*150812a8SEvalZero  * @param[in] value     Value of the second operand in the SUB operation.
217*150812a8SEvalZero  *
218*150812a8SEvalZero  * @return Previous value stored in the atomic object.
219*150812a8SEvalZero  */
220*150812a8SEvalZero uint32_t nrfx_atomic_u32_fetch_sub_hs(nrfx_atomic_u32_t * p_data, uint32_t value);
221*150812a8SEvalZero 
222*150812a8SEvalZero /**
223*150812a8SEvalZero  * @brief Function for running an arithmetic SUB operation on an atomic object
224*150812a8SEvalZero  *        if object >= value, and returning its new value.
225*150812a8SEvalZero  *
226*150812a8SEvalZero  * @param[in] p_data    Atomic memory pointer.
227*150812a8SEvalZero  * @param[in] value     Value of the second operand in the SUB operation.
228*150812a8SEvalZero  *
229*150812a8SEvalZero  * @return New value stored in the atomic object.
230*150812a8SEvalZero  */
231*150812a8SEvalZero uint32_t nrfx_atomic_u32_sub_hs(nrfx_atomic_u32_t * p_data, uint32_t value);
232*150812a8SEvalZero 
233*150812a8SEvalZero /**
234*150812a8SEvalZero  * @brief Function for running a logical one bit flag set operation
235*150812a8SEvalZero  *        on an atomic object and returning its previous value.
236*150812a8SEvalZero  *
237*150812a8SEvalZero  * @param[in] p_data    Atomic flag memory pointer.
238*150812a8SEvalZero  *
239*150812a8SEvalZero  * @return Previous flag value.
240*150812a8SEvalZero  */
241*150812a8SEvalZero uint32_t nrfx_atomic_flag_set_fetch(nrfx_atomic_flag_t * p_data);
242*150812a8SEvalZero 
243*150812a8SEvalZero /**
244*150812a8SEvalZero  * @brief Function for running a logical one bit flag set operation
245*150812a8SEvalZero  *        on an atomic object and returning its new value.
246*150812a8SEvalZero  *
247*150812a8SEvalZero  * @param[in] p_data    Atomic flag memory pointer.
248*150812a8SEvalZero  *
249*150812a8SEvalZero  * @return New flag value.
250*150812a8SEvalZero  */
251*150812a8SEvalZero uint32_t nrfx_atomic_flag_set(nrfx_atomic_flag_t * p_data);
252*150812a8SEvalZero 
253*150812a8SEvalZero /**
254*150812a8SEvalZero  * @brief Function for running a logical one bit flag clear operation
255*150812a8SEvalZero  *        on an atomic object and returning its previous value.
256*150812a8SEvalZero  *
257*150812a8SEvalZero  * @param[in] p_data    Atomic flag memory pointer.
258*150812a8SEvalZero  *
259*150812a8SEvalZero  * @return Previous flag value.
260*150812a8SEvalZero  */
261*150812a8SEvalZero uint32_t nrfx_atomic_flag_clear_fetch(nrfx_atomic_flag_t * p_data);
262*150812a8SEvalZero 
263*150812a8SEvalZero /**
264*150812a8SEvalZero  * @brief Function for running a logical one bit flag clear operation
265*150812a8SEvalZero  *        on an atomic object and returning its new value.
266*150812a8SEvalZero  *
267*150812a8SEvalZero  * @param[in] p_data    Atomic flag memory pointer.
268*150812a8SEvalZero  *
269*150812a8SEvalZero  * @return New flag value.
270*150812a8SEvalZero  */
271*150812a8SEvalZero uint32_t nrfx_atomic_flag_clear(nrfx_atomic_flag_t * p_data);
272*150812a8SEvalZero 
273*150812a8SEvalZero /** @} */
274*150812a8SEvalZero 
275*150812a8SEvalZero #ifdef __cplusplus
276*150812a8SEvalZero }
277*150812a8SEvalZero #endif
278*150812a8SEvalZero 
279*150812a8SEvalZero #endif // NRFX_ATOMIC_H__
280