Zephyr API Documentation  2.7.0-rc2
A Scalable Open Source RTOS
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
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21typedef int atomic_t;
23typedef void *atomic_ptr_t;
25
26/* Low-level primitives come in several styles: */
27
28#if defined(CONFIG_ATOMIC_OPERATIONS_C)
29/* Generic-but-slow implementation based on kernel locking and syscalls */
30#include <sys/atomic_c.h>
31#elif defined(CONFIG_ATOMIC_OPERATIONS_ARCH)
32/* Some architectures need their own implementation */
33# ifdef CONFIG_XTENSA
34/* Not all Xtensa toolchains support GCC-style atomic intrinsics */
36# else
37/* Other arch specific implementation */
38# include <sys/atomic_arch.h>
39# endif /* CONFIG_XTENSA */
40#else
41/* Default. See this file for the Doxygen reference: */
42#include <sys/atomic_builtin.h>
43#endif
44
45/* Portable higher-level utilities: */
46
61#define ATOMIC_INIT(i) (i)
62
72#define ATOMIC_PTR_INIT(p) (p)
73
78#define ATOMIC_BITS (sizeof(atomic_val_t) * 8)
79#define ATOMIC_MASK(bit) (1U << ((uint32_t)(bit) & (ATOMIC_BITS - 1U)))
80#define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS))
81
92#define ATOMIC_BITMAP_SIZE(num_bits) (1 + ((num_bits) - 1) / ATOMIC_BITS)
93
113#define ATOMIC_DEFINE(name, num_bits) \
114 atomic_t name[ATOMIC_BITMAP_SIZE(num_bits)]
115
127static inline bool atomic_test_bit(const atomic_t *target, int bit)
128{
129 atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit));
130
131 return (1 & (val >> (bit & (ATOMIC_BITS - 1)))) != 0;
132}
133
145static inline bool atomic_test_and_clear_bit(atomic_t *target, int bit)
146{
147 atomic_val_t mask = ATOMIC_MASK(bit);
148 atomic_val_t old;
149
150 old = atomic_and(ATOMIC_ELEM(target, bit), ~mask);
151
152 return (old & mask) != 0;
153}
154
166static inline bool atomic_test_and_set_bit(atomic_t *target, int bit)
167{
168 atomic_val_t mask = ATOMIC_MASK(bit);
169 atomic_val_t old;
170
171 old = atomic_or(ATOMIC_ELEM(target, bit), mask);
172
173 return (old & mask) != 0;
174}
175
187static inline void atomic_clear_bit(atomic_t *target, int bit)
188{
189 atomic_val_t mask = ATOMIC_MASK(bit);
190
191 (void)atomic_and(ATOMIC_ELEM(target, bit), ~mask);
192}
193
205static inline void atomic_set_bit(atomic_t *target, int bit)
206{
207 atomic_val_t mask = ATOMIC_MASK(bit);
208
209 (void)atomic_or(ATOMIC_ELEM(target, bit), mask);
210}
211
224static inline void atomic_set_bit_to(atomic_t *target, int bit, bool val)
225{
226 atomic_val_t mask = ATOMIC_MASK(bit);
227
228 if (val) {
229 (void)atomic_or(ATOMIC_ELEM(target, bit), mask);
230 } else {
231 (void)atomic_and(ATOMIC_ELEM(target, bit), ~mask);
232 }
233}
234
239#ifdef __cplusplus
240} /* extern "C" */
241#endif
242
243#endif /* ZEPHYR_INCLUDE_SYS_ATOMIC_H_ */
atomic_t atomic_val_t
Definition: atomic.h:22
atomic_ptr_t atomic_ptr_val_t
Definition: atomic.h:24
void * atomic_ptr_t
Definition: atomic.h:23
int atomic_t
Definition: atomic.h:21
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
void
Definition: eswifi_shell.c:15
static void atomic_set_bit(atomic_t *target, int bit)
Atomically set a bit.
Definition: atomic.h:205
static bool atomic_test_bit(const atomic_t *target, int bit)
Atomically test a bit.
Definition: atomic.h:127
static void atomic_clear_bit(atomic_t *target, int bit)
Atomically clear a bit.
Definition: atomic.h:187
static bool atomic_test_and_clear_bit(atomic_t *target, int bit)
Atomically test and clear a bit.
Definition: atomic.h:145
static bool atomic_test_and_set_bit(atomic_t *target, int bit)
Atomically set a bit.
Definition: atomic.h:166
static void atomic_set_bit_to(atomic_t *target, int bit, bool val)
Atomically set a bit to a given value.
Definition: atomic.h:224
int target
Definition: main.c:68
Macros to abstract toolchain specific capabilities.