firmware
IEM Firmware Documentation
Loading...
Searching...
No Matches
atomic.h
Go to the documentation of this file.
1/*
2 * FreeRTOS Kernel V11.1.0
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
8 * this software and associated documentation files (the "Software"), to deal in
9 * the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 * the Software, and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * https://www.FreeRTOS.org
25 * https://github.com/FreeRTOS
26 *
27 */
28
45
46#ifndef ATOMIC_H
47#define ATOMIC_H
48
49#ifndef INC_FREERTOS_H
50 #error "include FreeRTOS.h must appear in source files before include atomic.h"
51#endif
52
53/* Standard includes. */
54#include <stdint.h>
55
56/* *INDENT-OFF* */
57#ifdef __cplusplus
58 extern "C" {
59#endif
60/* *INDENT-ON* */
61
62/*
63 * Port specific definitions -- entering/exiting critical section.
64 * Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h
65 *
66 * Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with
67 * ATOMIC_ENTER_CRITICAL().
68 *
69 */
70#if ( portHAS_NESTED_INTERRUPTS == 1 )
71
72/* Nested interrupt scheme is supported in this port. */
73 #define ATOMIC_ENTER_CRITICAL() \
74 UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
75
76 #define ATOMIC_EXIT_CRITICAL() \
77 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
78
79#else
80
81/* Nested interrupt scheme is NOT supported in this port. */
82 #define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
83 #define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
84
85#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
86
87/*
88 * Port specific definition -- "always inline".
89 * Inline is compiler specific, and may not always get inlined depending on your
90 * optimization level. Also, inline is considered as performance optimization
91 * for atomic. Thus, if portFORCE_INLINE is not provided by portmacro.h,
92 * instead of resulting error, simply define it away.
93 */
94#ifndef portFORCE_INLINE
95 #define portFORCE_INLINE
96#endif
97
98#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U
99#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U
100
101/*----------------------------- Swap && CAS ------------------------------*/
102
118static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination,
119 uint32_t ulExchange,
120 uint32_t ulComparand )
121{
122 uint32_t ulReturnValue;
123
125 {
126 if( *pulDestination == ulComparand )
127 {
128 *pulDestination = ulExchange;
129 ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
130 }
131 else
132 {
133 ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
134 }
135 }
137
138 return ulReturnValue;
139}
140/*-----------------------------------------------------------*/
141
154static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination,
155 void * pvExchange )
156{
157 void * pReturnValue;
158
160 {
161 pReturnValue = *ppvDestination;
162 *ppvDestination = pvExchange;
163 }
165
166 return pReturnValue;
167}
168/*-----------------------------------------------------------*/
169
186static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
187 void * pvExchange,
188 void * pvComparand )
189{
190 uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
191
193 {
194 if( *ppvDestination == pvComparand )
195 {
196 *ppvDestination = pvExchange;
197 ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
198 }
199 }
201
202 return ulReturnValue;
203}
204
205
206/*----------------------------- Arithmetic ------------------------------*/
207
219static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
220 uint32_t ulCount )
221{
222 uint32_t ulCurrent;
223
225 {
226 ulCurrent = *pulAddend;
227 *pulAddend += ulCount;
228 }
230
231 return ulCurrent;
232}
233/*-----------------------------------------------------------*/
234
247static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend,
248 uint32_t ulCount )
249{
250 uint32_t ulCurrent;
251
253 {
254 ulCurrent = *pulAddend;
255 *pulAddend -= ulCount;
256 }
258
259 return ulCurrent;
260}
261/*-----------------------------------------------------------*/
262
273static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
274{
275 uint32_t ulCurrent;
276
278 {
279 ulCurrent = *pulAddend;
280 *pulAddend += 1;
281 }
283
284 return ulCurrent;
285}
286/*-----------------------------------------------------------*/
287
298static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
299{
300 uint32_t ulCurrent;
301
303 {
304 ulCurrent = *pulAddend;
305 *pulAddend -= 1;
306 }
308
309 return ulCurrent;
310}
311
312/*----------------------------- Bitwise Logical ------------------------------*/
313
325static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination,
326 uint32_t ulValue )
327{
328 uint32_t ulCurrent;
329
331 {
332 ulCurrent = *pulDestination;
333 *pulDestination |= ulValue;
334 }
336
337 return ulCurrent;
338}
339/*-----------------------------------------------------------*/
340
352static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination,
353 uint32_t ulValue )
354{
355 uint32_t ulCurrent;
356
358 {
359 ulCurrent = *pulDestination;
360 *pulDestination &= ulValue;
361 }
363
364 return ulCurrent;
365}
366/*-----------------------------------------------------------*/
367
379static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination,
380 uint32_t ulValue )
381{
382 uint32_t ulCurrent;
383
385 {
386 ulCurrent = *pulDestination;
387 *pulDestination = ~( ulCurrent & ulValue );
388 }
390
391 return ulCurrent;
392}
393/*-----------------------------------------------------------*/
394
406static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination,
407 uint32_t ulValue )
408{
409 uint32_t ulCurrent;
410
412 {
413 ulCurrent = *pulDestination;
414 *pulDestination ^= ulValue;
415 }
417
418 return ulCurrent;
419}
420
421/* *INDENT-OFF* */
422#ifdef __cplusplus
423 }
424#endif
425/* *INDENT-ON* */
426
427#endif /* ATOMIC_H */
static portFORCE_INLINE uint32_t Atomic_XOR_u32(uint32_t volatile *pulDestination, uint32_t ulValue)
Performs an atomic XOR operation on the specified values.
Definition atomic.h:406
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32(void *volatile *ppvDestination, void *pvExchange, void *pvComparand)
Performs an atomic compare-and-swap operation on the specified pointer values.
Definition atomic.h:186
static portFORCE_INLINE uint32_t Atomic_Add_u32(uint32_t volatile *pulAddend, uint32_t ulCount)
Atomically adds count to the value of the specified pointer points to.
Definition atomic.h:219
#define ATOMIC_ENTER_CRITICAL()
Definition atomic.h:82
#define ATOMIC_EXIT_CRITICAL()
Definition atomic.h:83
#define ATOMIC_COMPARE_AND_SWAP_SUCCESS
Definition atomic.h:98
static portFORCE_INLINE uint32_t Atomic_Decrement_u32(uint32_t volatile *pulAddend)
Atomically decrements the value of the specified pointer points to.
Definition atomic.h:298
static portFORCE_INLINE uint32_t Atomic_Increment_u32(uint32_t volatile *pulAddend)
Atomically increments the value of the specified pointer points to.
Definition atomic.h:273
static portFORCE_INLINE void * Atomic_SwapPointers_p32(void *volatile *ppvDestination, void *pvExchange)
Atomically sets the address pointed to by *ppvDestination to the value of *pvExchange.
Definition atomic.h:154
static portFORCE_INLINE uint32_t Atomic_NAND_u32(uint32_t volatile *pulDestination, uint32_t ulValue)
Performs an atomic NAND operation on the specified values.
Definition atomic.h:379
static portFORCE_INLINE uint32_t Atomic_AND_u32(uint32_t volatile *pulDestination, uint32_t ulValue)
Performs an atomic AND operation on the specified values.
Definition atomic.h:352
#define portFORCE_INLINE
Definition atomic.h:95
#define ATOMIC_COMPARE_AND_SWAP_FAILURE
Definition atomic.h:99
static portFORCE_INLINE uint32_t Atomic_Subtract_u32(uint32_t volatile *pulAddend, uint32_t ulCount)
Atomically subtracts count from the value of the specified pointer pointers to.
Definition atomic.h:247
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32(uint32_t volatile *pulDestination, uint32_t ulExchange, uint32_t ulComparand)
Performs an atomic compare-and-swap operation on the specified values.
Definition atomic.h:118
static portFORCE_INLINE uint32_t Atomic_OR_u32(uint32_t volatile *pulDestination, uint32_t ulValue)
Performs an atomic OR operation on the specified values.
Definition atomic.h:325