AWS IoT Device SDK C: Platform
Platform portability layer
Return to main page ↑
iot_atomic_generic.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy of
5  * this software and associated documentation files (the "Software"), to deal in
6  * the Software without restriction, including without limitation the rights to
7  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8  * the Software, and to permit persons to whom the Software is furnished to do so,
9  * subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all
12  * copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20  */
21 
30 #ifndef IOT_ATOMIC_GENERIC_H_
31 #define IOT_ATOMIC_GENERIC_H_
32 
33 /* Standard includes. */
34 #include <stdint.h>
35 
36 /* Atomic include. */
37 #include "iot_atomic.h"
38 
39 /* Platform threads include. */
40 #include "platform/iot_threads.h"
41 
42 /* Ensure that this header is only included when generic atomics are enabled. */
43 #if IOT_ATOMIC_GENERIC != 1
44  #error "Generic atomic implementation is not enabled."
45 #endif
46 
80 extern void Iot_EnterCritical( void );
81 extern void Iot_ExitCritical( void );
84 /*---------------- Swap and compare-and-swap ------------------*/
85 
97 /* @[declare_platform_atomic_compareandswap_u32] */
98 static inline uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pDestination,
99  uint32_t newValue,
100  uint32_t comparand )
101 /* @[declare_platform_atomic_compareandswap_u32] */
102 {
103  uint32_t swapped = 0;
104 
105  Iot_EnterCritical();
106 
107  if( *pDestination == comparand )
108  {
109  *pDestination = newValue;
110  swapped = 1;
111  }
112 
113  Iot_ExitCritical();
114 
115  return swapped;
116 }
117 
118 /*-----------------------------------------------------------*/
119 
128 /* @[declare_platform_atomic_swap_pointer] */
129 static inline void * Atomic_Swap_Pointer( void * volatile * pDestination,
130  void * pNewValue )
131 /* @[declare_platform_atomic_swap_pointer] */
132 {
133  void * pOldValue = NULL;
134 
135  Iot_EnterCritical();
136  pOldValue = *pDestination;
137  *pDestination = pNewValue;
138  Iot_ExitCritical();
139 
140  return pOldValue;
141 }
142 
143 /*-----------------------------------------------------------*/
144 
156 /* @[declare_platform_atomic_compareandswap_pointer] */
157 static inline uint32_t Atomic_CompareAndSwap_Pointer( void * volatile * pDestination,
158  void * pNewValue,
159  void * pComparand )
160 /* @[declare_platform_atomic_compareandswap_pointer] */
161 {
162  uint32_t swapped = 0;
163 
164  Iot_EnterCritical();
165 
166  if( *pDestination == pComparand )
167  {
168  *pDestination = pNewValue;
169  swapped = 1;
170  }
171 
172  Iot_ExitCritical();
173 
174  return swapped;
175 }
176 
177 /*----------------------- Arithmetic --------------------------*/
178 
187 /* @[declare_platform_atomic_add_u32] */
188 static inline uint32_t Atomic_Add_u32( uint32_t volatile * pAugend,
189  uint32_t addend )
190 /* @[declare_platform_atomic_add_u32] */
191 {
192  uint32_t oldValue = 0;
193 
194  Iot_EnterCritical();
195  oldValue = *pAugend;
196  *pAugend = oldValue + addend;
197  Iot_ExitCritical();
198 
199  return oldValue;
200 }
201 
202 /*-----------------------------------------------------------*/
203 
212 /* @[declare_platform_atomic_subtract_u32] */
213 static inline uint32_t Atomic_Subtract_u32( uint32_t volatile * pMinuend,
214  uint32_t subtrahend )
215 /* @[declare_platform_atomic_subtract_u32] */
216 {
217  uint32_t oldValue = 0;
218 
219  Iot_EnterCritical();
220  oldValue = *pMinuend;
221  *pMinuend = oldValue - subtrahend;
222  Iot_ExitCritical();
223 
224  return oldValue;
225 }
226 
227 /*-----------------------------------------------------------*/
228 
236 /* @[declare_platform_atomic_increment_u32] */
237 static inline uint32_t Atomic_Increment_u32( uint32_t volatile * pAugend )
238 /* @[declare_platform_atomic_increment_u32] */
239 {
240  return Atomic_Add_u32( pAugend, 1 );
241 }
242 
243 /*-----------------------------------------------------------*/
244 
252 /* @[declare_platform_atomic_decrement_u32] */
253 static inline uint32_t Atomic_Decrement_u32( uint32_t volatile * pMinuend )
254 /* @[declare_platform_atomic_decrement_u32] */
255 {
256  return Atomic_Subtract_u32( pMinuend, 1 );
257 }
258 
259 /*--------------------- Bitwise logic -------------------------*/
260 
269 /* @[declare_platform_atomic_or_u32] */
270 static inline uint32_t Atomic_OR_u32( uint32_t volatile * pOperand,
271  uint32_t mask )
272 /* @[declare_platform_atomic_or_u32] */
273 {
274  uint32_t oldValue = 0;
275 
276  Iot_EnterCritical();
277  oldValue = *pOperand;
278  *pOperand = ( oldValue | mask );
279  Iot_ExitCritical();
280 
281  return oldValue;
282 }
283 
284 /*-----------------------------------------------------------*/
285 
294 /* @[declare_platform_atomic_xor_u32] */
295 static inline uint32_t Atomic_XOR_u32( uint32_t volatile * pOperand,
296  uint32_t mask )
297 /* @[declare_platform_atomic_xor_u32] */
298 {
299  uint32_t oldValue = 0;
300 
301  Iot_EnterCritical();
302  oldValue = *pOperand;
303  *pOperand = ( oldValue ^ mask );
304  Iot_ExitCritical();
305 
306  return oldValue;
307 }
308 
309 /*-----------------------------------------------------------*/
310 
319 /* @[declare_platform_atomic_and_u32] */
320 static inline uint32_t Atomic_AND_u32( uint32_t volatile * pOperand,
321  uint32_t mask )
322 /* @[declare_platform_atomic_and_u32] */
323 {
324  uint32_t oldValue = 0;
325 
326  Iot_EnterCritical();
327  oldValue = *pOperand;
328  *pOperand = ( oldValue & mask );
329  Iot_ExitCritical();
330 
331  return oldValue;
332 }
333 
334 /*-----------------------------------------------------------*/
335 
344 /* @[declare_platform_atomic_nand_u32] */
345 static inline uint32_t Atomic_NAND_u32( uint32_t volatile * pOperand,
346  uint32_t mask )
347 /* @[declare_platform_atomic_nand_u32] */
348 {
349  uint32_t oldValue = 0;
350 
351  Iot_EnterCritical();
352  oldValue = *pOperand;
353  *pOperand = ~( oldValue & mask );
354  Iot_ExitCritical();
355 
356  return oldValue;
357 }
358 
359 #endif /* ifndef IOT_ATOMIC_GENERIC_H_ */
static uint32_t Atomic_Add_u32(uint32_t volatile *pAugend, uint32_t addend)
Performs an atomic addition of the given values.
Definition: iot_atomic_generic.h:246
static uint32_t Atomic_CompareAndSwap_Pointer(void *volatile *pDestination, void *pNewValue, void *pComparand)
Performs an atomic compare-and-swap operation on the given pointers.
Definition: iot_atomic_generic.h:215
Threading and synchronization functions used by libraries in this SDK.
static uint32_t Atomic_AND_u32(uint32_t volatile *pOperand, uint32_t mask)
Performs an atomic bitwise AND of the given values.
Definition: iot_atomic_generic.h:378
static void * Atomic_Swap_Pointer(void *volatile *pDestination, void *pNewValue)
Atomically writes a pointer value to memory.
Definition: iot_atomic_generic.h:187
static uint32_t Atomic_CompareAndSwap_u32(uint32_t volatile *pDestination, uint32_t newValue, uint32_t comparand)
Performs an atomic compare-and-swap operation on the given values.
Definition: iot_atomic_generic.h:156
static uint32_t Atomic_XOR_u32(uint32_t volatile *pOperand, uint32_t mask)
Performs an atomic bitwise XOR of the given values.
Definition: iot_atomic_generic.h:353
static uint32_t Atomic_OR_u32(uint32_t volatile *pOperand, uint32_t mask)
Performs an atomic bitwise OR of the given values.
Definition: iot_atomic_generic.h:328
static uint32_t Atomic_NAND_u32(uint32_t volatile *pOperand, uint32_t mask)
Performs an atomic bitwise NAND of the given values.
Definition: iot_atomic_generic.h:403
static uint32_t Atomic_Increment_u32(uint32_t volatile *pAugend)
Atomically adds 1 to the given value.
Definition: iot_atomic_generic.h:295
static uint32_t Atomic_Decrement_u32(uint32_t volatile *pMinuend)
Atomically subtracts 1 from the given value.
Definition: iot_atomic_generic.h:311
static uint32_t Atomic_Subtract_u32(uint32_t volatile *pMinuend, uint32_t subtrahend)
Performs an atomic subtraction of the given values.
Definition: iot_atomic_generic.h:271