1 /*
2  * Copyright (c) 2025 Google LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief C-based implementation of GCC __atomic built-ins.
10  *
11  * This file provides a fallback implementation for the C++ atomic functions
12  * required by the compiler on architectures that do not have native atomic
13  * instructions and are using the generic C implementation of atomics.
14  * All operations are made atomic by using a global interrupt lock.
15  */
16 
17 #include <zephyr/kernel.h>
18 #include <stdint.h>
19 
20 /*
21  * Note on memory ordering:
22  * The `memorder` parameters are ignored because the irq_lock() provides
23  * a full memory barrier, which is equivalent to the strongest memory order,
24  * __ATOMIC_SEQ_CST. This is always safe.
25  */
26 
27 /* === compare_exchange ======================================================= */
28 
29 #define DEFINE_ATOMIC_COMPARE_EXCHANGE(n, type)                                                    \
30 	bool __atomic_compare_exchange_##n(volatile void *ptr, void *expected, type desired,       \
31 					   bool weak, int success, int failure)                    \
32 	{                                                                                          \
33 		bool ret = false;                                                                  \
34 		unsigned int key = irq_lock();                                                     \
35 		volatile type *p = ptr;                                                            \
36 		type *e = expected;                                                                \
37                                                                                                    \
38 		if (*p == *e) {                                                                    \
39 			*p = desired;                                                              \
40 			ret = true;                                                                \
41 		} else {                                                                           \
42 			*e = *p;                                                                   \
43 			ret = false;                                                               \
44 		}                                                                                  \
45 		irq_unlock(key);                                                                   \
46 		return ret;                                                                        \
47 	}
48 
49 DEFINE_ATOMIC_COMPARE_EXCHANGE(1, uint8_t)
50 DEFINE_ATOMIC_COMPARE_EXCHANGE(2, uint16_t)
51 DEFINE_ATOMIC_COMPARE_EXCHANGE(4, uint32_t)
52