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