RT-Thread RTOS 1.2.0
An open source embedded real-time operating system
载入中...
搜索中...
未找到
rtatomic.h
浏览该文件的文档.
1/*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2023-03-14 WangShun first version
9 * 2023-05-20 Bernard add stdc atomic detection.
10 */
11#ifndef __RT_ATOMIC_H__
12#define __RT_ATOMIC_H__
13
14#include <rthw.h>
15
16#if !defined(__cplusplus)
17
29
30#if defined(RT_USING_STDC_ATOMIC)
31
32#ifndef __STDC_NO_ATOMICS__
33#define rt_atomic_load(ptr) atomic_load(ptr)
34#define rt_atomic_store(ptr, v) atomic_store(ptr, v)
35#define rt_atomic_add(ptr, v) atomic_fetch_add(ptr, v)
36#define rt_atomic_sub(ptr, v) atomic_fetch_sub(ptr, v)
37#define rt_atomic_and(ptr, v) atomic_fetch_and(ptr, v)
38#define rt_atomic_or(ptr, v) atomic_fetch_or(ptr, v)
39#define rt_atomic_xor(ptr, v) atomic_fetch_xor(ptr, v)
40#define rt_atomic_exchange(ptr, v) atomic_exchange(ptr, v)
41#define rt_atomic_flag_clear(ptr) atomic_flag_clear(ptr)
42#define rt_atomic_flag_test_and_set(ptr) atomic_flag_test_and_set(ptr)
43#define rt_atomic_compare_exchange_strong(ptr, v,des) atomic_compare_exchange_strong(ptr, v ,des)
44#else
45#error "The standard library C doesn't support the atomic operation"
46#endif /* __STDC_NO_ATOMICS__ */
47
48#elif defined(RT_USING_HW_ATOMIC)
49#define rt_atomic_load(ptr) rt_hw_atomic_load(ptr)
50#define rt_atomic_store(ptr, v) rt_hw_atomic_store(ptr, v)
51#define rt_atomic_add(ptr, v) rt_hw_atomic_add(ptr, v)
52#define rt_atomic_sub(ptr, v) rt_hw_atomic_sub(ptr, v)
53#define rt_atomic_and(ptr, v) rt_hw_atomic_and(ptr, v)
54#define rt_atomic_or(ptr, v) rt_hw_atomic_or(ptr, v)
55#define rt_atomic_xor(ptr, v) rt_hw_atomic_xor(ptr, v)
56#define rt_atomic_exchange(ptr, v) rt_hw_atomic_exchange(ptr, v)
57#define rt_atomic_flag_clear(ptr) rt_hw_atomic_flag_clear(ptr)
58#define rt_atomic_flag_test_and_set(ptr) rt_hw_atomic_flag_test_and_set(ptr)
59#define rt_atomic_compare_exchange_strong(ptr, v,des) rt_hw_atomic_compare_exchange_strong(ptr, v ,des)
60
61#else
62#include <rthw.h>
63#define rt_atomic_load(ptr) rt_soft_atomic_load(ptr)
64#define rt_atomic_store(ptr, v) rt_soft_atomic_store(ptr, v)
65#define rt_atomic_add(ptr, v) rt_soft_atomic_add(ptr, v)
66#define rt_atomic_sub(ptr, v) rt_soft_atomic_sub(ptr, v)
67#define rt_atomic_and(ptr, v) rt_soft_atomic_and(ptr, v)
68#define rt_atomic_or(ptr, v) rt_soft_atomic_or(ptr, v)
69#define rt_atomic_xor(ptr, v) rt_soft_atomic_xor(ptr, v)
70#define rt_atomic_exchange(ptr, v) rt_soft_atomic_exchange(ptr, v)
71#define rt_atomic_flag_clear(ptr) rt_soft_atomic_flag_clear(ptr)
72#define rt_atomic_flag_test_and_set(ptr) rt_soft_atomic_flag_test_and_set(ptr)
73#define rt_atomic_compare_exchange_strong(ptr, v,des) rt_soft_atomic_compare_exchange_strong(ptr, v ,des)
74
76{
77 rt_base_t level;
78 rt_atomic_t temp;
80 temp = *ptr;
81 *ptr = val;
83 return temp;
84}
85
87{
88 rt_base_t level;
89 rt_atomic_t temp;
91 temp = *ptr;
92 *ptr += val;
94 return temp;
95}
96
98{
99 rt_base_t level;
100 rt_atomic_t temp;
101 level = rt_hw_interrupt_disable();
102 temp = *ptr;
103 *ptr -= val;
105 return temp;
106}
107
109{
110 rt_base_t level;
111 rt_atomic_t temp;
112 level = rt_hw_interrupt_disable();
113 temp = *ptr;
114 *ptr = (*ptr) ^ val;
116 return temp;
117}
118
120{
121 rt_base_t level;
122 rt_atomic_t temp;
123 level = rt_hw_interrupt_disable();
124 temp = *ptr;
125 *ptr = (*ptr) & val;
127 return temp;
128}
129
131{
132 rt_base_t level;
133 rt_atomic_t temp;
134 level = rt_hw_interrupt_disable();
135 temp = *ptr;
136 *ptr = (*ptr) | val;
138 return temp;
139}
140
142{
143 rt_base_t level;
144 rt_atomic_t temp;
145 level = rt_hw_interrupt_disable();
146 temp = *ptr;
148 return temp;
149}
150
151rt_inline void rt_soft_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val)
152{
153 rt_base_t level;
154 level = rt_hw_interrupt_disable();
155 *ptr = val;
157}
158
160{
161 rt_base_t level;
162 rt_atomic_t temp;
163 level = rt_hw_interrupt_disable();
164 if (*ptr == 0)
165 {
166 temp = 0;
167 *ptr = 1;
168 }
169 else
170 temp = 1;
172 return temp;
173}
174
175rt_inline void rt_soft_atomic_flag_clear(volatile rt_atomic_t *ptr)
176{
177 rt_base_t level;
178 level = rt_hw_interrupt_disable();
179 *ptr = 0;
181}
182
184 rt_atomic_t desired)
185{
186 rt_base_t level;
187 rt_atomic_t temp;
188 level = rt_hw_interrupt_disable();
189 if ((*ptr1) != (*ptr2))
190 {
191 *ptr2 = *ptr1;
192 temp = 0;
193 }
194 else
195 {
196 *ptr1 = desired;
197 temp = 1;
198 }
200 return temp;
201}
202#endif /* RT_USING_STDC_ATOMIC */
203
205{
206 return rt_atomic_sub(ptr, 1) == 1;
207}
208
210{
212
213 do {
214 if (c == u)
215 {
216 break;
217 }
218 } while (!rt_atomic_compare_exchange_strong(ptr, &c, c + a));
219
220 return c;
221}
222
224{
225 return rt_atomic_fetch_add_unless(ptr, a, u) != u;
226}
227
229{
230 return rt_atomic_add_unless(ptr, 1, 0);
231}
232
239{
240 l->next = 0;
241}
242
244{
245 rt_base_t exp;
246 exp = rt_atomic_load(&l->next);
247 do
248 {
249 n->next = exp;
250 } while (!rt_atomic_compare_exchange_strong(&l->next, &exp, (rt_base_t)n));
251}
252
254{
255 rt_base_t exp;
256 rt_ll_slist_t *head;
257
258 exp = rt_atomic_load(&l->next);
259 do
260 {
261 head = (rt_ll_slist_t *)exp;
262 } while (head && !rt_atomic_compare_exchange_strong(&l->next, &exp, rt_atomic_load(&head->next)));
263 return head;
264}
265
266#endif /* __cplusplus */
267
268#endif /* __RT_ATOMIC_H__ */
void rt_hw_atomic_flag_clear(volatile rt_atomic_t *ptr)
rt_inline rt_bool_t rt_atomic_dec_and_test(volatile rt_atomic_t *ptr)
rt_inline rt_atomic_t rt_atomic_fetch_add_unless(volatile rt_atomic_t *ptr, rt_atomic_t a, rt_atomic_t u)
#define rt_atomic_sub(ptr, v)
rt_atomic_t rt_hw_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_atomic_t rt_hw_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_inline void rt_ll_slist_init(rt_ll_slist_t *l)
initialize a lock-less single list
rt_inline rt_ll_slist_t * rt_ll_slist_dequeue(rt_ll_slist_t *l)
rt_inline rt_atomic_t rt_soft_atomic_and(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_atomic_t rt_hw_atomic_sub(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_inline rt_bool_t rt_atomic_inc_not_zero(volatile rt_atomic_t *ptr)
void rt_hw_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val)
#define rt_atomic_compare_exchange_strong(ptr, v, des)
rt_atomic_t rt_hw_atomic_or(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_inline void rt_ll_slist_enqueue(rt_ll_slist_t *l, rt_ll_slist_t *n)
rt_inline rt_atomic_t rt_soft_atomic_load(volatile rt_atomic_t *ptr)
rt_inline rt_atomic_t rt_soft_atomic_sub(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_inline rt_atomic_t rt_soft_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_inline rt_bool_t rt_atomic_add_unless(volatile rt_atomic_t *ptr, rt_atomic_t a, rt_atomic_t u)
rt_inline rt_atomic_t rt_soft_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_atomic_t rt_hw_atomic_and(volatile rt_atomic_t *ptr, rt_atomic_t val)
#define rt_atomic_load(ptr)
rt_atomic_t rt_hw_atomic_load(volatile rt_atomic_t *ptr)
rt_inline rt_atomic_t rt_soft_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_inline void rt_soft_atomic_flag_clear(volatile rt_atomic_t *ptr)
rt_atomic_t rt_hw_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_atomic_t *expected, rt_atomic_t desired)
rt_inline rt_atomic_t rt_soft_atomic_flag_test_and_set(volatile rt_atomic_t *ptr)
rt_inline void rt_soft_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val)
rt_atomic_t rt_hw_atomic_flag_test_and_set(volatile rt_atomic_t *ptr)
rt_inline rt_atomic_t rt_soft_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr1, rt_atomic_t *ptr2, rt_atomic_t desired)
rt_inline rt_atomic_t rt_soft_atomic_or(volatile rt_atomic_t *ptr, rt_atomic_t val)
void rt_hw_interrupt_enable(rt_base_t level)
rt_base_t rt_hw_interrupt_disable(void)
rt_int32_t rt_base_t
struct rt_lockless_slist_node rt_ll_slist_t
int rt_bool_t
rt_base_t rt_atomic_t