1#ifndef SIMDUTF_ATOMIC_UTIL_H
2#define SIMDUTF_ATOMIC_UTIL_H
11inline void memcpy_atomic_read(
char *dst,
const char *src,
size_t len) {
12 static_assert(std::atomic_ref<char>::required_alignment ==
sizeof(char),
13 "std::atomic_ref requires the same alignment as char_type");
17 constexpr size_t alignment =
sizeof(uint64_t);
20 auto bbb_memcpy_atomic_read = [](
char *bytedst,
const char *bytesrc,
21 size_t bytelen)
noexcept {
22 char *mutable_src =
const_cast<char *
>(bytesrc);
23 for (
size_t j = 0; j < bytelen; ++j) {
25 std::atomic_ref<char>(mutable_src[j]).load(std::memory_order_relaxed);
30 size_t offset =
reinterpret_cast<std::uintptr_t
>(src) % alignment;
32 size_t to_align = detail::min(len, alignment - offset);
33 bbb_memcpy_atomic_read(dst, src, to_align);
40 while (len >= alignment) {
41 auto *src_aligned =
reinterpret_cast<uint64_t *
>(
const_cast<char *
>(src));
42 const auto dst_value =
43 std::atomic_ref<uint64_t>(*src_aligned).load(std::memory_order_relaxed);
44 std::memcpy(dst, &dst_value,
sizeof(uint64_t));
52 bbb_memcpy_atomic_read(dst, src, len);
58inline void memcpy_atomic_write(
char *dst,
const char *src,
size_t len) {
59 static_assert(std::atomic_ref<char>::required_alignment ==
sizeof(char),
60 "std::atomic_ref requires the same alignment as char");
65 constexpr size_t alignment =
sizeof(uint64_t);
68 auto bbb_memcpy_atomic_write = [](
char *bytedst,
const char *bytesrc,
69 size_t bytelen)
noexcept {
70 for (
size_t j = 0; j < bytelen; ++j) {
71 std::atomic_ref<char>(bytedst[j])
72 .store(bytesrc[j], std::memory_order_relaxed);
77 size_t offset =
reinterpret_cast<std::uintptr_t
>(dst) % alignment;
79 size_t to_align = detail::min(len, alignment - offset);
80 bbb_memcpy_atomic_write(dst, src, to_align);
87 while (len >= alignment) {
88 auto *dst_aligned =
reinterpret_cast<uint64_t *
>(dst);
90 std::memcpy(&src_val, src,
sizeof(uint64_t));
91 std::atomic_ref<uint64_t>(*dst_aligned)
92 .store(src_val, std::memory_order_relaxed);
100 bbb_memcpy_atomic_write(dst, src, len);
helpers placed in namespace detail are not a part of the public API