Skip to content

Commit

Permalink
[c++] Implement all atomics for AVR and Cortex-M
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed May 20, 2024
1 parent 0078155 commit 8a924f9
Show file tree
Hide file tree
Showing 10 changed files with 560 additions and 166 deletions.
14 changes: 14 additions & 0 deletions ext/gcc/atomic
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include_next <atomic>

#include <modm_atomic.hpp>
100 changes: 100 additions & 0 deletions ext/gcc/atomic.cpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2020, 2024, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <modm_atomic.hpp>

/* We are implementing the libary interface described here:
* See https://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary
*
* We ignore the memory order, since the runtime switching takes longer than
* the DMB instruction.
*/

// ============================ atomics for arrays ============================
// These functions cannot be inlined, since the compiler builtins are named the
// same. Terrible design really.
extern "C" void
__atomic_load(unsigned int size, const volatile void *src, void *dest, int /*memorder*/)
{
__modm_atomic_pre_barrier(__ATOMIC_SEQ_CST);
{
modm::atomic::Lock _;
__builtin_memcpy(dest, (const void*)src, size);
}
__modm_atomic_post_barrier(__ATOMIC_SEQ_CST);
}

extern "C" void
__atomic_store(unsigned int size, volatile void *dest, void *src, int /*memorder*/)
{
__modm_atomic_pre_barrier(__ATOMIC_SEQ_CST);
{
modm::atomic::Lock _;
__builtin_memcpy((void*)dest, src, size);
}
__modm_atomic_post_barrier(__ATOMIC_SEQ_CST);
}

extern "C" void
__atomic_exchange(unsigned int size, volatile void *ptr, void *val, void *ret, int /*memorder*/)
{
__modm_atomic_pre_barrier(__ATOMIC_SEQ_CST);
{
modm::atomic::Lock _;
__builtin_memcpy(ret, (void*)ptr, size);
__builtin_memcpy((void*)ptr, val, size);
}
__modm_atomic_post_barrier(__ATOMIC_SEQ_CST);
}

extern "C" bool
__atomic_compare_exchange(unsigned int len, volatile void *ptr, void *expected, void *desired,
int /*success_memorder*/, int /*failure_memorder*/)
{
bool retval{false};
__modm_atomic_pre_barrier(__ATOMIC_SEQ_CST);
{
modm::atomic::Lock _;
if (__builtin_memcmp((void*)ptr, expected, len) == 0) [[likely]]
{
__builtin_memcpy((void*)ptr, desired, len);
retval = true;
}
else __builtin_memcpy(expected, (void*)ptr, len);
}
__modm_atomic_post_barrier(__ATOMIC_SEQ_CST);
return retval;
}

%% macro atomic_fetch(len)
%% for name, op in [("add", "+"), ("sub", "-")]
extern "C" {{len|u}}
__atomic_fetch_{{name}}_{{len//8}}(volatile void *ptr, {{len|u}} value, int /*memorder*/)
{
{{len|u}} previous{};
__modm_atomic_pre_barrier(__ATOMIC_SEQ_CST);
{
modm::atomic::Lock _;
previous = *reinterpret_cast<volatile {{len|u}}*>(ptr);
*reinterpret_cast<volatile {{len|u}}*>(ptr) = (previous {{op}} value);
}
__modm_atomic_post_barrier(__ATOMIC_SEQ_CST);
return previous;
}
%% endfor
%% endmacro

%% for length in bit_lengths
// ========================= atomics for {{length}} bit integers =========================
// These functions cannot be inlined since the compiler refuses to find these
// functions even if they are declared right at the call site. Unclear why.
{{ atomic_fetch(length) }}
%% endfor
150 changes: 0 additions & 150 deletions ext/gcc/atomics_c11_cortex.cpp.in

This file was deleted.

2 changes: 1 addition & 1 deletion ext/gcc/libstdc++
Loading

0 comments on commit 8a924f9

Please sign in to comment.