Skip to content

Commit 8a924f9

Browse files
committed
[c++] Implement all atomics for AVR and Cortex-M
1 parent 0078155 commit 8a924f9

File tree

10 files changed

+560
-166
lines changed

10 files changed

+560
-166
lines changed

ext/gcc/atomic

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright (c) 2024, Niklas Hauser
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#include_next <atomic>
13+
14+
#include <modm_atomic.hpp>

ext/gcc/atomic.cpp.in

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright (c) 2020, 2024, Niklas Hauser
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#include <modm_atomic.hpp>
13+
14+
/* We are implementing the libary interface described here:
15+
* See https://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary
16+
*
17+
* We ignore the memory order, since the runtime switching takes longer than
18+
* the DMB instruction.
19+
*/
20+
21+
// ============================ atomics for arrays ============================
22+
// These functions cannot be inlined, since the compiler builtins are named the
23+
// same. Terrible design really.
24+
extern "C" void
25+
__atomic_load(unsigned int size, const volatile void *src, void *dest, int /*memorder*/)
26+
{
27+
__modm_atomic_pre_barrier(__ATOMIC_SEQ_CST);
28+
{
29+
modm::atomic::Lock _;
30+
__builtin_memcpy(dest, (const void*)src, size);
31+
}
32+
__modm_atomic_post_barrier(__ATOMIC_SEQ_CST);
33+
}
34+
35+
extern "C" void
36+
__atomic_store(unsigned int size, volatile void *dest, void *src, int /*memorder*/)
37+
{
38+
__modm_atomic_pre_barrier(__ATOMIC_SEQ_CST);
39+
{
40+
modm::atomic::Lock _;
41+
__builtin_memcpy((void*)dest, src, size);
42+
}
43+
__modm_atomic_post_barrier(__ATOMIC_SEQ_CST);
44+
}
45+
46+
extern "C" void
47+
__atomic_exchange(unsigned int size, volatile void *ptr, void *val, void *ret, int /*memorder*/)
48+
{
49+
__modm_atomic_pre_barrier(__ATOMIC_SEQ_CST);
50+
{
51+
modm::atomic::Lock _;
52+
__builtin_memcpy(ret, (void*)ptr, size);
53+
__builtin_memcpy((void*)ptr, val, size);
54+
}
55+
__modm_atomic_post_barrier(__ATOMIC_SEQ_CST);
56+
}
57+
58+
extern "C" bool
59+
__atomic_compare_exchange(unsigned int len, volatile void *ptr, void *expected, void *desired,
60+
int /*success_memorder*/, int /*failure_memorder*/)
61+
{
62+
bool retval{false};
63+
__modm_atomic_pre_barrier(__ATOMIC_SEQ_CST);
64+
{
65+
modm::atomic::Lock _;
66+
if (__builtin_memcmp((void*)ptr, expected, len) == 0) [[likely]]
67+
{
68+
__builtin_memcpy((void*)ptr, desired, len);
69+
retval = true;
70+
}
71+
else __builtin_memcpy(expected, (void*)ptr, len);
72+
}
73+
__modm_atomic_post_barrier(__ATOMIC_SEQ_CST);
74+
return retval;
75+
}
76+
77+
%% macro atomic_fetch(len)
78+
%% for name, op in [("add", "+"), ("sub", "-")]
79+
extern "C" {{len|u}}
80+
__atomic_fetch_{{name}}_{{len//8}}(volatile void *ptr, {{len|u}} value, int /*memorder*/)
81+
{
82+
{{len|u}} previous{};
83+
__modm_atomic_pre_barrier(__ATOMIC_SEQ_CST);
84+
{
85+
modm::atomic::Lock _;
86+
previous = *reinterpret_cast<volatile {{len|u}}*>(ptr);
87+
*reinterpret_cast<volatile {{len|u}}*>(ptr) = (previous {{op}} value);
88+
}
89+
__modm_atomic_post_barrier(__ATOMIC_SEQ_CST);
90+
return previous;
91+
}
92+
%% endfor
93+
%% endmacro
94+
95+
%% for length in bit_lengths
96+
// ========================= atomics for {{length}} bit integers =========================
97+
// These functions cannot be inlined since the compiler refuses to find these
98+
// functions even if they are declared right at the call site. Unclear why.
99+
{{ atomic_fetch(length) }}
100+
%% endfor

ext/gcc/atomics_c11_cortex.cpp.in

Lines changed: 0 additions & 150 deletions
This file was deleted.

0 commit comments

Comments
 (0)