Skip to content

Commit 4b4c3c8

Browse files
authored
[atomic] add stdc atomic detection. (#7536)
1 parent 1e5dc55 commit 4b4c3c8

File tree

7 files changed

+68
-38
lines changed

7 files changed

+68
-38
lines changed

.github/workflows/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,15 +348,15 @@ jobs:
348348
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-riscv64-unknown-elf' && success() }}
349349
run: |
350350
wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/v1.4/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz
351-
sudo tar zxvf riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz -C /opt
351+
sudo tar zxf riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz -C /opt
352352
/opt/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-gcc --version
353353
echo "RTT_EXEC_PATH=/opt/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin" >> $GITHUB_ENV
354354
355355
- name: Install Riscv-none-embed ToolChains
356356
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-riscv-none-embed' && success() }}
357357
run: |
358358
wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/v1.5/xpack-riscv-none-embed-gcc-8.3.0-2.3-linux-x64.tar.gz
359-
sudo tar zxvf xpack-riscv-none-embed-gcc-8.3.0-2.3-linux-x64.tar.gz -C /opt
359+
sudo tar zxf xpack-riscv-none-embed-gcc-8.3.0-2.3-linux-x64.tar.gz -C /opt
360360
/opt/xpack-riscv-none-embed-gcc-8.3.0-2.3/bin/riscv-none-embed-gcc --version
361361
echo "RTT_EXEC_PATH=/opt/xpack-riscv-none-embed-gcc-8.3.0-2.3/bin" >> $GITHUB_ENV
362362

include/rtatomic.h

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
* Change Logs:
77
* Date Author Notes
88
* 2023-03-14 WangShun first version
9+
* 2023-05-20 Bernard add stdc atomic detection.
910
*/
1011
#ifndef __RT_ATOMIC_H__
1112
#define __RT_ATOMIC_H__
1213

14+
#if !defined(__cplusplus)
15+
1316
rt_atomic_t rt_hw_atomic_load(volatile rt_atomic_t *ptr);
1417
void rt_hw_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val);
1518
rt_atomic_t rt_hw_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val);
@@ -20,9 +23,30 @@ rt_atomic_t rt_hw_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val);
2023
rt_atomic_t rt_hw_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val);
2124
void rt_hw_atomic_flag_clear(volatile rt_atomic_t *ptr);
2225
rt_atomic_t rt_hw_atomic_flag_test_and_set(volatile rt_atomic_t *ptr);
23-
rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_atomic_t *old, rt_atomic_t new);
26+
rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_atomic_t *expected, rt_atomic_t desired);
27+
28+
/* To detect stdatomic */
29+
#if !defined(RT_USING_HW_ATOMIC) && !defined(RT_USING_STDC_ATOMIC)
30+
#if defined(__GNUC__) && defined(RT_USING_LIBC) && !defined(__STDC_NO_ATOMICS__)
31+
#define RT_USING_STDC_ATOMIC
32+
#endif /* __GNUC__ && .. */
33+
#endif /* !RT_USING_HW_ATOMIC && !RT_USING_STDC_ATOMIC */
34+
35+
#if defined(RT_USING_HW_ATOMIC)
36+
#define rt_atomic_load(ptr) rt_hw_atomic_load(ptr)
37+
#define rt_atomic_store(ptr, v) rt_hw_atomic_store(ptr, v)
38+
#define rt_atomic_add(ptr, v) rt_hw_atomic_add(ptr, v)
39+
#define rt_atomic_sub(ptr, v) rt_hw_atomic_sub(ptr, v)
40+
#define rt_atomic_and(ptr, v) rt_hw_atomic_and(ptr, v)
41+
#define rt_atomic_or(ptr, v) rt_hw_atomic_or(ptr, v)
42+
#define rt_atomic_xor(ptr, v) rt_hw_atomic_xor(ptr, v)
43+
#define rt_atomic_exchange(ptr, v) rt_hw_atomic_exchange(ptr, v)
44+
#define rt_atomic_flag_clear(ptr) rt_hw_atomic_flag_clear(ptr)
45+
#define rt_atomic_flag_test_and_set(ptr) rt_hw_atomic_flag_test_and_set(ptr)
46+
#define rt_atomic_compare_exchange_strong(ptr, v,des) rt_hw_atomic_compare_exchange_strong(ptr, v ,des)
47+
48+
#elif defined(RT_USING_STDC_ATOMIC)
2449

25-
#if defined(RT_USING_STDC_ATOMIC)
2650
#ifndef __STDC_NO_ATOMICS__
2751
#define rt_atomic_load(ptr) atomic_load(ptr)
2852
#define rt_atomic_store(ptr, v) atomic_store(ptr, v)
@@ -38,18 +62,7 @@ rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_a
3862
#else
3963
#error "The standard library C doesn't support the atomic operation"
4064
#endif /* __STDC_NO_ATOMICS__ */
41-
#elif defined(RT_USING_HW_ATOMIC)
42-
#define rt_atomic_load(ptr) rt_hw_atomic_load(ptr)
43-
#define rt_atomic_store(ptr, v) rt_hw_atomic_store(ptr, v)
44-
#define rt_atomic_add(ptr, v) rt_hw_atomic_add(ptr, v)
45-
#define rt_atomic_sub(ptr, v) rt_hw_atomic_sub(ptr, v)
46-
#define rt_atomic_and(ptr, v) rt_hw_atomic_and(ptr, v)
47-
#define rt_atomic_or(ptr, v) rt_hw_atomic_or(ptr, v)
48-
#define rt_atomic_xor(ptr, v) rt_hw_atomic_xor(ptr, v)
49-
#define rt_atomic_exchange(ptr, v) rt_hw_atomic_exchange(ptr, v)
50-
#define rt_atomic_flag_clear(ptr) rt_hw_atomic_flag_clear(ptr)
51-
#define rt_atomic_flag_test_and_set(ptr) rt_hw_atomic_flag_test_and_set(ptr)
52-
#define rt_atomic_compare_exchange_strong(ptr, v,des) rt_hw_atomic_compare_exchange_strong(ptr, v ,des)
65+
5366
#else
5467
#include <rthw.h>
5568
#define rt_atomic_load(ptr) rt_soft_atomic_load(ptr)
@@ -192,4 +205,7 @@ rt_inline rt_atomic_t rt_soft_atomic_compare_exchange_strong(volatile rt_atomic_
192205
return temp;
193206
}
194207
#endif /* RT_USING_STDC_ATOMIC */
208+
209+
#endif /* __cplusplus */
210+
195211
#endif /* __RT_ATOMIC_H__ */

include/rtdef.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
* 2022-09-12 Meco Man define rt_ssize_t
4949
* 2022-12-20 Meco Man add const name for rt_object
5050
* 2023-04-01 Chushicheng change version number to v5.0.1
51+
* 2023-05-20 Bernard add stdc atomic detection.
5152
*/
5253

5354
#ifndef __RT_DEF_H__
@@ -126,12 +127,24 @@ typedef rt_base_t rt_flag_t; /**< Type for flags */
126127
typedef rt_ubase_t rt_dev_t; /**< Type for device */
127128
typedef rt_base_t rt_off_t; /**< Type for offset */
128129

130+
#if !defined(__cplusplus)
129131
#if defined(RT_USING_STDC_ATOMIC)
130-
#include <stdatomic.h>
131-
typedef atomic_size_t rt_atomic_t;
132+
#include <stdatomic.h>
133+
typedef atomic_size_t rt_atomic_t;
134+
#elif defined(RT_USING_HW_ATOMIC)
135+
typedef volatile rt_base_t rt_atomic_t;
132136
#else
133-
typedef volatile rt_base_t rt_atomic_t;
134-
#endif
137+
138+
/* To detect std atomic */
139+
#if defined(RT_USING_LIBC) && defined(__GNUC__) && !defined(__STDC_NO_ATOMICS__)
140+
#include <stdatomic.h>
141+
typedef atomic_size_t rt_atomic_t;
142+
#else
143+
typedef volatile rt_base_t rt_atomic_t;
144+
#endif /* __GNUC__ && !__STDC_NO_ATOMICS__ */
145+
146+
#endif /* RT_USING_STDC_ATOMIC */
147+
#endif /* __cplusplus */
135148

136149
/* boolean type definitions */
137150
#define RT_TRUE 1 /**< boolean true */

include/rtthread.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* 2021-02-28 Meco Man add RT_KSERVICE_USING_STDLIB
1818
* 2021-11-14 Meco Man add rtlegacy.h for compatibility
1919
* 2022-06-04 Meco Man remove strnlen
20+
* 2023-05-20 Bernard add rtatomic.h header file to included files.
2021
*/
2122

2223
#ifndef __RT_THREAD_H__
@@ -27,6 +28,7 @@
2728
#include <rtdef.h>
2829
#include <rtservice.h>
2930
#include <rtm.h>
31+
#include <rtatomic.h>
3032
#ifdef RT_USING_LEGACY
3133
#include <rtlegacy.h>
3234
#endif

libcpu/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ config ARCH_ARMV8
166166
bool
167167
select ARCH_ARM
168168
select ARCH_ARM_MMU
169-
select RT_USING_HW_ATOMIC
170169

171170
config ARCH_MIPS
172171
bool

libcpu/arm/common/atomic_arm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ rt_atomic_t rt_hw_atomic_flag_test_and_set(volatile rt_atomic_t *ptr)
166166
return oldval;
167167
}
168168

169-
rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, volatile rt_atomic_t *old, rt_atomic_t new)
169+
rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_atomic_t *old, rt_atomic_t new)
170170
{
171171
rt_atomic_t result;
172172
rt_atomic_t temp = *old;

libcpu/risc-v/common/atomic_riscv.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
rt_atomic_t rt_hw_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val)
1414
{
15-
rt_atomic_t result;
15+
rt_atomic_t result = 0;
1616
#if __riscv_xlen == 32
1717
asm volatile ("amoswap.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory");
1818
#elif __riscv_xlen == 64
@@ -23,7 +23,7 @@ rt_atomic_t rt_hw_atomic_exchange(volatile rt_atomic_t *ptr, rt_atomic_t val)
2323

2424
rt_atomic_t rt_hw_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val)
2525
{
26-
rt_atomic_t result;
26+
rt_atomic_t result = 0;
2727
#if __riscv_xlen == 32
2828
asm volatile ("amoadd.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory");
2929
#elif __riscv_xlen == 64
@@ -34,7 +34,7 @@ rt_atomic_t rt_hw_atomic_add(volatile rt_atomic_t *ptr, rt_atomic_t val)
3434

3535
rt_atomic_t rt_hw_atomic_sub(volatile rt_atomic_t *ptr, rt_atomic_t val)
3636
{
37-
rt_atomic_t result;
37+
rt_atomic_t result = 0;
3838
val = -val;
3939
#if __riscv_xlen == 32
4040
asm volatile ("amoadd.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory");
@@ -46,7 +46,7 @@ rt_atomic_t rt_hw_atomic_sub(volatile rt_atomic_t *ptr, rt_atomic_t val)
4646

4747
rt_atomic_t rt_hw_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val)
4848
{
49-
rt_atomic_t result;
49+
rt_atomic_t result = 0;
5050
#if __riscv_xlen == 32
5151
asm volatile ("amoxor.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory");
5252
#elif __riscv_xlen == 64
@@ -57,7 +57,7 @@ rt_atomic_t rt_hw_atomic_xor(volatile rt_atomic_t *ptr, rt_atomic_t val)
5757

5858
rt_atomic_t rt_hw_atomic_and(volatile rt_atomic_t *ptr, rt_atomic_t val)
5959
{
60-
rt_atomic_t result;
60+
rt_atomic_t result = 0;
6161
#if __riscv_xlen == 32
6262
asm volatile ("amoand.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory");
6363
#elif __riscv_xlen == 64
@@ -68,7 +68,7 @@ rt_atomic_t rt_hw_atomic_and(volatile rt_atomic_t *ptr, rt_atomic_t val)
6868

6969
rt_atomic_t rt_hw_atomic_or(volatile rt_atomic_t *ptr, rt_atomic_t val)
7070
{
71-
rt_atomic_t result;
71+
rt_atomic_t result = 0;
7272
#if __riscv_xlen == 32
7373
asm volatile ("amoor.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory");
7474
#elif __riscv_xlen == 64
@@ -79,7 +79,7 @@ rt_atomic_t rt_hw_atomic_or(volatile rt_atomic_t *ptr, rt_atomic_t val)
7979

8080
rt_atomic_t rt_hw_atomic_load(volatile rt_atomic_t *ptr)
8181
{
82-
rt_atomic_t result;
82+
rt_atomic_t result = 0;
8383
#if __riscv_xlen == 32
8484
asm volatile ("amoxor.w %0, x0, (%1)" : "=r"(result) : "r"(ptr) : "memory");
8585
#elif __riscv_xlen == 64
@@ -90,7 +90,7 @@ rt_atomic_t rt_hw_atomic_load(volatile rt_atomic_t *ptr)
9090

9191
void rt_hw_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val)
9292
{
93-
rt_atomic_t result;
93+
rt_atomic_t result = 0;
9494
#if __riscv_xlen == 32
9595
asm volatile ("amoswap.w %0, %1, (%2)" : "=r"(result) : "r"(val), "r"(ptr) : "memory");
9696
#elif __riscv_xlen == 64
@@ -100,7 +100,7 @@ void rt_hw_atomic_store(volatile rt_atomic_t *ptr, rt_atomic_t val)
100100

101101
rt_atomic_t rt_hw_atomic_flag_test_and_set(volatile rt_atomic_t *ptr)
102102
{
103-
rt_atomic_t result;
103+
rt_atomic_t result = 0;
104104
rt_atomic_t temp = 1;
105105
#if __riscv_xlen == 32
106106
asm volatile ("amoor.w %0, %1, (%2)" : "=r"(result) : "r"(temp), "r"(ptr) : "memory");
@@ -112,47 +112,47 @@ rt_atomic_t rt_hw_atomic_flag_test_and_set(volatile rt_atomic_t *ptr)
112112

113113
void rt_hw_atomic_flag_clear(volatile rt_atomic_t *ptr)
114114
{
115-
rt_atomic_t result;
115+
rt_atomic_t result = 0;
116116
#if __riscv_xlen == 32
117117
asm volatile ("amoand.w %0, x0, (%1)" : "=r"(result) :"r"(ptr) : "memory");
118118
#elif __riscv_xlen == 64
119119
asm volatile ("amoand.d %0, x0, (%1)" : "=r"(result) :"r"(ptr) : "memory");
120120
#endif
121121
}
122122

123-
rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, volatile rt_atomic_t *old, rt_atomic_t new)
123+
rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_atomic_t *old, rt_atomic_t desired)
124124
{
125125
rt_atomic_t tmp = *old;
126-
rt_atomic_t result;
126+
rt_atomic_t result = 0;
127127
#if __riscv_xlen == 32
128128
asm volatile(
129129
" fence iorw, ow\n"
130130
"1: lr.w.aq %[result], (%[ptr])\n"
131131
" bne %[result], %[tmp], 2f\n"
132-
" sc.w.rl %[tmp], %[new], (%[ptr])\n"
132+
" sc.w.rl %[tmp], %[desired], (%[ptr])\n"
133133
" bnez %[tmp], 1b\n"
134134
" li %[result], 1\n"
135135
" j 3f\n"
136136
" 2:sw %[result], (%[old])\n"
137137
" li %[result], 0\n"
138138
" 3:\n"
139139
: [result]"+r" (result), [tmp]"+r" (tmp), [ptr]"+r" (ptr)
140-
: [new]"r" (new), [old]"r"(old)
140+
: [desired]"r" (desired), [old]"r"(old)
141141
: "memory");
142142
#elif __riscv_xlen == 64
143143
asm volatile(
144144
" fence iorw, ow\n"
145145
"1: lr.d.aq %[result], (%[ptr])\n"
146146
" bne %[result], %[tmp], 2f\n"
147-
" sc.d.rl %[tmp], %[new], (%[ptr])\n"
147+
" sc.d.rl %[tmp], %[desired], (%[ptr])\n"
148148
" bnez %[tmp], 1b\n"
149149
" li %[result], 1\n"
150150
" j 3f\n"
151151
" 2:sd %[result], (%[old])\n"
152152
" li %[result], 0\n"
153153
" 3:\n"
154154
: [result]"+r" (result), [tmp]"+r" (tmp), [ptr]"+r" (ptr)
155-
: [new]"r" (new), [old]"r"(old)
155+
: [desired]"r" (desired), [old]"r"(old)
156156
: "memory");
157157
#endif
158158
return result;

0 commit comments

Comments
 (0)