Zephyr API Documentation  3.0.0
A Scalable Open Source RTOS
3.0.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
atomic.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 1997-2015, Wind River Systems, Inc.
3 * Copyright (c) 2021 Intel Corporation
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef ZEPHYR_INCLUDE_SYS_ATOMIC_H_
9#define ZEPHYR_INCLUDE_SYS_ATOMIC_H_
10
11#include <stdbool.h>
12#include <toolchain.h>
13#include <stddef.h>
14
15#include <zephyr/types.h>
16#include <sys/util_macro.h>
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
22typedef long atomic_t;
24typedef void *atomic_ptr_t;
26
27/* Low-level primitives come in several styles: */
28
29#if defined(CONFIG_ATOMIC_OPERATIONS_C)
30/* Generic-but-slow implementation based on kernel locking and syscalls */
31#include <sys/atomic_c.h>
32#elif defined(CONFIG_ATOMIC_OPERATIONS_ARCH)
33/* Some architectures need their own implementation */
34# ifdef CONFIG_XTENSA
35/* Not all Xtensa toolchains support GCC-style atomic intrinsics */
37# else
38/* Other arch specific implementation */
39# include <sys/atomic_arch.h>
40# endif /* CONFIG_XTENSA */
41#else
42/* Default. See this file for the Doxygen reference: */
43#include <sys/atomic_builtin.h>
44#endif
45
46/* Portable higher-level utilities: */
47
62#define ATOMIC_INIT(i) (i)
63
73#define ATOMIC_PTR_INIT(p) (p)
74
79#define ATOMIC_BITS (sizeof(atomic_val_t) * 8)
80#define ATOMIC_MASK(bit) BIT((unsigned long)(bit) & (ATOMIC_BITS - 1U))
81#define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS))
82
93#define ATOMIC_BITMAP_SIZE(num_bits) (1 + ((num_bits) - 1) / ATOMIC_BITS)
94
114#define ATOMIC_DEFINE(name, num_bits) \
115 atomic_t name[ATOMIC_BITMAP_SIZE(num_bits)]
116
128static inline bool atomic_test_bit(const atomic_t *target, int bit)
129{
130 atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit));
131
132 return (1 & (val >> (bit & (ATOMIC_BITS - 1)))) != 0;
133}
134
146static inline bool atomic_test_and_clear_bit(atomic_t *target, int bit)
147{
148 atomic_val_t mask = ATOMIC_MASK(bit);
149 atomic_val_t old;
150
151 old = atomic_and(ATOMIC_ELEM(target, bit), ~mask);
152
153 return (old & mask) != 0;
154}
155
167static inline bool atomic_test_and_set_bit(atomic_t *target, int bit)
168{
169 atomic_val_t mask = ATOMIC_MASK(bit);
170 atomic_val_t old;
171
172 old = atomic_or(ATOMIC_ELEM(target, bit), mask);
173
174 return (old & mask) != 0;
175}
176
186static inline void atomic_clear_bit(atomic_t *target, int bit)
187{
188 atomic_val_t mask = ATOMIC_MASK(bit);
189
190 (void)atomic_and(ATOMIC_ELEM(target, bit), ~mask);
191}
192
202static inline void atomic_set_bit(atomic_t *target, int bit)
203{
204 atomic_val_t mask = ATOMIC_MASK(bit);
205
206 (void)atomic_or(ATOMIC_ELEM(target, bit), mask);
207}
208
219static inline void atomic_set_bit_to(atomic_t *target, int bit, bool val)
220{
221 atomic_val_t mask = ATOMIC_MASK(bit);
222
223 if (val) {
224 (void)atomic_or(ATOMIC_ELEM(target, bit), mask);
225 } else {
226 (void)atomic_and(ATOMIC_ELEM(target, bit), ~mask);
227 }
228}
229
234#ifdef __cplusplus
235} /* extern "C" */
236#endif
237
238#endif /* ZEPHYR_INCLUDE_SYS_ATOMIC_H_ */
long atomic_t
Definition: atomic.h:22
atomic_t atomic_val_t
Definition: atomic.h:23
atomic_ptr_t atomic_ptr_val_t
Definition: atomic.h:25
void * atomic_ptr_t
Definition: atomic.h:24
static ALWAYS_INLINE atomic_val_t atomic_and(atomic_t *target, atomic_val_t value)
Definition: atomic_xtensa.h:111
static ALWAYS_INLINE atomic_val_t atomic_get(const atomic_t *target)
Definition: atomic_xtensa.h:16
static ALWAYS_INLINE atomic_val_t atomic_or(atomic_t *target, atomic_val_t value)
Definition: atomic_xtensa.h:99
static void atomic_set_bit(atomic_t *target, int bit)
Atomically set a bit.
Definition: atomic.h:202
static bool atomic_test_bit(const atomic_t *target, int bit)
Atomically test a bit.
Definition: atomic.h:128
static void atomic_clear_bit(atomic_t *target, int bit)
Atomically clear a bit.
Definition: atomic.h:186
static bool atomic_test_and_clear_bit(atomic_t *target, int bit)
Atomically test and clear a bit.
Definition: atomic.h:146
static bool atomic_test_and_set_bit(atomic_t *target, int bit)
Atomically set a bit.
Definition: atomic.h:167
static void atomic_set_bit_to(atomic_t *target, int bit, bool val)
Atomically set a bit to a given value.
Definition: atomic.h:219
int target
Definition: main.c:68
Macros to abstract toolchain specific capabilities.
Macro utilities.