History

atomic_load/atomic_store : to ensure return the latest value, should we add a memory barrier here?

If have no these memory barriers, sometime it will cause bug in multiple threads program.

kbkpbot committed 2 years ago

Commit 105d70f1 parent da0d4391 file · +52 −50Browse files

Unified · Split

lib/stdatomic.c+52−50
@@ -15,6 +15,56 @@ · 14 unmodified lines
1515 #define __ATOMIC_SEQ_CST 5
1616 typedef __SIZE_TYPE__ size_t;
1717
18+/* uses alias to allow building with gcc/clang */
19+#ifdef __TINYC__
20+#define ATOMIC(x) __atomic_##x
21+#else
22+#define ATOMIC(x) __tcc_atomic_##x
23+#endif
24+
25+void ATOMIC(signal_fence) (int memorder)
26+{
27+}
28+
29+void ATOMIC(thread_fence) (int memorder)
30+{
31+#if defined __i386__
32+ __asm__ volatile("lock orl $0, (%esp)");
33+#elif defined __x86_64__
34+ __asm__ volatile("lock orq $0, (%rsp)");
35+#elif defined __arm__
36+ __asm__ volatile(".int 0xee070fba"); // mcr p15, 0, r0, c7, c10, 5
37+#elif defined __aarch64__
38+ __asm__ volatile(".int 0xd5033bbf"); // dmb ish
39+#elif defined __riscv
40+ __asm__ volatile(".int 0x0ff0000f"); // fence iorw,iorw
41+#endif
42+}
43+
44+bool ATOMIC(is_lock_free) (unsigned long size, const volatile void *ptr)
45+{
46+ bool ret;
47+
48+ switch (size) {
49+ case 1: ret = true; break;
50+ case 2: ret = true; break;
51+ case 4: ret = true; break;
52+#if defined __x86_64__ || defined __aarch64__ || defined __riscv
53+ case 8: ret = true; break;
54+#else
55+ case 8: ret = false; break;
56+#endif
57+ default: ret = false; break;
58+ }
59+ return ret;
60+}
61+
62+#ifndef __TINYC__
63+void __atomic_signal_fence(int memorder) __attribute__((alias("__tcc_atomic_signal_fence")));
64+void __atomic_thread_fence(int memorder) __attribute__((alias("__tcc_atomic_thread_fence")));
65+bool __atomic_is_lock_free(unsigned long size, const volatile void *ptr) __attribute__((alias("__tcc_atomic_is_lock_free")));
66+#endif
67+
1868 #if defined __i386__ || defined __x86_64__
1969 #define ATOMIC_COMPARE_EXCHANGE(TYPE, MODE, SUFFIX) \
2070 bool __atomic_compare_exchange_##MODE \
@@ -42,6 +92,7 @@ typedef __SIZE_TYPE__ size_t; · 21 unmodified lines
4292 #define ATOMIC_LOAD(TYPE, MODE) \
4393 TYPE __atomic_load_##MODE(const volatile void *atom, int memorder) \
4494 { \
95+ __atomic_thread_fence(__ATOMIC_ACQUIRE); \
4596 return *(volatile TYPE *)atom; \
4697 }
4798
@@ -49,6 +100,7 @@ typedef __SIZE_TYPE__ size_t; · 1 unmodified line
49100 void __atomic_store_##MODE(volatile void *atom, TYPE value, int memorder) \
50101 { \
51102 *(volatile TYPE *)atom = value; \
103+ __atomic_thread_fence(__ATOMIC_RELEASE); \
52104 }
53105
54106 #define ATOMIC_GEN_OP(TYPE, MODE, NAME, OP, RET) \
@@ -114,53 +166,3 @@ ATOMIC_GEN(uint32_t, 4, "l") · 59 unmodified lines
114166 #if defined __x86_64__ || defined __aarch64__ || defined __riscv
115167 ATOMIC_GEN(uint64_t, 8, "q")
116168 #endif
117−
118−/* uses alias to allow building with gcc/clang */
119−#ifdef __TINYC__
120−#define ATOMIC(x) __atomic_##x
121−#else
122−#define ATOMIC(x) __tcc_atomic_##x
123−#endif
124−
125−void ATOMIC(signal_fence) (int memorder)
126−{
127−}
128−
129−void ATOMIC(thread_fence) (int memorder)
130−{
131−#if defined __i386__
132− __asm__ volatile("lock orl $0, (%esp)");
133−#elif defined __x86_64__
134− __asm__ volatile("lock orq $0, (%rsp)");
135−#elif defined __arm__
136− __asm__ volatile(".int 0xee070fba"); // mcr p15, 0, r0, c7, c10, 5
137−#elif defined __aarch64__
138− __asm__ volatile(".int 0xd5033bbf"); // dmb ish
139−#elif defined __riscv
140− __asm__ volatile(".int 0x0ff0000f"); // fence iorw,iorw
141−#endif
142−}
143−
144−bool ATOMIC(is_lock_free) (unsigned long size, const volatile void *ptr)
145−{
146− bool ret;
147−
148− switch (size) {
149− case 1: ret = true; break;
150− case 2: ret = true; break;
151− case 4: ret = true; break;
152−#if defined __x86_64__ || defined __aarch64__ || defined __riscv
153− case 8: ret = true; break;
154−#else
155− case 8: ret = false; break;
156−#endif
157− default: ret = false; break;
158− }
159− return ret;
160−}
161−
162−#ifndef __TINYC__
163−void __atomic_signal_fence(int memorder) __attribute__((alias("__tcc_atomic_signal_fence")));
164−void __atomic_thread_fence(int memorder) __attribute__((alias("__tcc_atomic_thread_fence")));
165−bool __atomic_is_lock_free(unsigned long size, const volatile void *ptr) __attribute__((alias("__tcc_atomic_is_lock_free")));
166−#endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t