52 #ifndef INC_FREERTOS_H
53 #error "include FreeRTOS.h must appear in source files before include atomic.h"
63 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
69 #ifndef portFORCE_INLINE
70 #define portFORCE_INLINE inline __attribute__((always_inline))
81 #if defined( portSET_INTERRUPT_MASK_FROM_ISR )
84 #define ATOMIC_ENTER_CRITICAL() \
85 UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
87 #define ATOMIC_EXIT_CRITICAL() \
88 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
93 #define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
94 #define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
104 #ifndef portFORCE_INLINE
105 #define portFORCE_INLINE
110 #define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U
111 #define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U
131 uint32_t
volatile * pDestination,
133 uint32_t ulComparand )
138 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
140 if ( __atomic_compare_exchange( pDestination,
152 ATOMIC_ENTER_CRITICAL();
154 if ( *pDestination == ulComparand )
156 *pDestination = ulExchange;
160 ATOMIC_EXIT_CRITICAL();
164 return ulReturnValue;
181 void *
volatile * ppDestination,
186 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
188 __atomic_exchange( ppDestination, &pExchange, &pReturnValue, __ATOMIC_SEQ_CST );
192 ATOMIC_ENTER_CRITICAL();
194 pReturnValue = *ppDestination;
196 *ppDestination = pExchange;
198 ATOMIC_EXIT_CRITICAL();
222 void *
volatile * ppDestination,
223 void * pExchange,
void * pComparand )
227 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
228 if ( __atomic_compare_exchange( ppDestination,
240 ATOMIC_ENTER_CRITICAL();
242 if ( *ppDestination == pComparand )
244 *ppDestination = pExchange;
248 ATOMIC_EXIT_CRITICAL();
252 return ulReturnValue;
270 uint32_t
volatile * pAddend,
273 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
275 return __atomic_fetch_add(pAddend, ulCount, __ATOMIC_SEQ_CST);
281 ATOMIC_ENTER_CRITICAL();
283 ulCurrent = *pAddend;
287 ATOMIC_EXIT_CRITICAL();
307 uint32_t
volatile * pAddend,
310 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
312 return __atomic_fetch_sub(pAddend, ulCount, __ATOMIC_SEQ_CST);
318 ATOMIC_ENTER_CRITICAL();
320 ulCurrent = *pAddend;
324 ATOMIC_EXIT_CRITICAL();
343 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
345 return __atomic_fetch_add(pAddend, 1, __ATOMIC_SEQ_CST);
351 ATOMIC_ENTER_CRITICAL();
353 ulCurrent = *pAddend;
357 ATOMIC_EXIT_CRITICAL();
376 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
378 return __atomic_fetch_sub(pAddend, 1, __ATOMIC_SEQ_CST);
384 ATOMIC_ENTER_CRITICAL();
386 ulCurrent = *pAddend;
390 ATOMIC_EXIT_CRITICAL();
411 uint32_t
volatile * pDestination,
414 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
416 return __atomic_fetch_or(pDestination, ulValue, __ATOMIC_SEQ_CST);
422 ATOMIC_ENTER_CRITICAL();
424 ulCurrent = *pDestination;
426 *pDestination |= ulValue;
428 ATOMIC_EXIT_CRITICAL();
447 uint32_t
volatile * pDestination,
450 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
452 return __atomic_fetch_and(pDestination, ulValue, __ATOMIC_SEQ_CST);
458 ATOMIC_ENTER_CRITICAL();
460 ulCurrent = *pDestination;
462 *pDestination &= ulValue;
464 ATOMIC_EXIT_CRITICAL();
483 uint32_t
volatile * pDestination,
486 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
488 return __atomic_fetch_nand(pDestination, ulValue, __ATOMIC_SEQ_CST);
494 ATOMIC_ENTER_CRITICAL();
496 ulCurrent = *pDestination;
498 *pDestination = ~(ulCurrent & ulValue);
500 ATOMIC_EXIT_CRITICAL();
519 uint32_t
volatile * pDestination,
522 #if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
524 return __atomic_fetch_xor(pDestination, ulValue, __ATOMIC_SEQ_CST);
530 ATOMIC_ENTER_CRITICAL();
532 ulCurrent = *pDestination;
534 *pDestination ^= ulValue;
536 ATOMIC_EXIT_CRITICAL();