1#ifndef SIMDUTF_ATOMIC_UTIL_H
2#define SIMDUTF_ATOMIC_UTIL_H
10inline void memcpy_atomic_read(
char *dst,
const char *src,
size_t len) {
11 static_assert(std::atomic_ref<char>::required_alignment ==
sizeof(char),
12 "std::atomic_ref requires the same alignment as char_type");
16 constexpr size_t alignment =
sizeof(uint64_t);
19 auto bbb_memcpy_atomic_read = [](
char *bytedst,
const char *bytesrc,
20 size_t bytelen)
noexcept {
21 char *mutable_src =
const_cast<char *
>(bytesrc);
22 for (
size_t j = 0; j < bytelen; ++j) {
24 std::atomic_ref<char>(mutable_src[j]).load(std::memory_order_relaxed);
29 size_t offset =
reinterpret_cast<std::uintptr_t
>(src) % alignment;
31 size_t to_align = std::min(len, alignment - offset);
32 bbb_memcpy_atomic_read(dst, src, to_align);
39 while (len >= alignment) {
40 auto *src_aligned =
reinterpret_cast<uint64_t *
>(
const_cast<char *
>(src));
41 const auto dst_value =
42 std::atomic_ref<uint64_t>(*src_aligned).load(std::memory_order_relaxed);
43 std::memcpy(dst, &dst_value,
sizeof(uint64_t));
51 bbb_memcpy_atomic_read(dst, src, len);
57inline void memcpy_atomic_write(
char *dst,
const char *src,
size_t len) {
58 static_assert(std::atomic_ref<char>::required_alignment ==
sizeof(char),
59 "std::atomic_ref requires the same alignment as char");
64 constexpr size_t alignment =
sizeof(uint64_t);
67 auto bbb_memcpy_atomic_write = [](
char *bytedst,
const char *bytesrc,
68 size_t bytelen)
noexcept {
69 for (
size_t j = 0; j < bytelen; ++j) {
70 std::atomic_ref<char>(bytedst[j])
71 .store(bytesrc[j], std::memory_order_relaxed);
76 size_t offset =
reinterpret_cast<std::uintptr_t
>(dst) % alignment;
78 size_t to_align = std::min(len, alignment - offset);
79 bbb_memcpy_atomic_write(dst, src, to_align);
86 while (len >= alignment) {
87 auto *dst_aligned =
reinterpret_cast<uint64_t *
>(dst);
89 std::memcpy(&src_val, src,
sizeof(uint64_t));
90 std::atomic_ref<uint64_t>(*dst_aligned)
91 .store(src_val, std::memory_order_relaxed);
99 bbb_memcpy_atomic_write(dst, src, len);