From a2aa51eb22370832dc04267aa91f4ff245b1555c Mon Sep 17 00:00:00 2001 From: Exverge Date: Thu, 6 Aug 2026 18:21:11 -0400 Subject: [PATCH] [page_table] replace atomic union with bit_cast atomic unions are considered UB by C++ (even though in this case it *should* be safe), and bit_cast just looks cleaner --- src/common/page_table.h | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/common/page_table.h b/src/common/page_table.h index e0da3c9eb9..88e071a74e 100644 --- a/src/common/page_table.h +++ b/src/common/page_table.h @@ -67,33 +67,33 @@ struct PageTable { }; [[nodiscard]] Data Raw() const noexcept { - return data.load(std::memory_order_relaxed); + return std::bit_cast(data_raw.load(std::memory_order_relaxed)); } /// Returns the page pointer [[nodiscard]] uintptr_t Pointer(bool ignored_marked = false) const noexcept { - return ExtractPointer(data.load(std::memory_order_relaxed), ignored_marked); + return ExtractPointer(std::bit_cast(data_raw.load(std::memory_order_relaxed)), ignored_marked); } /// Returns the page type attribute [[nodiscard]] PageType Type() const noexcept { - return static_cast(data.load(std::memory_order_relaxed).type); + return static_cast(std::bit_cast(data_raw.load(std::memory_order_relaxed)).type); } /// Returns the block identifier. [[nodiscard]] u16 Block() const noexcept { - return static_cast(data.load(std::memory_order_relaxed).block); + return static_cast(std::bit_cast(data_raw.load(std::memory_order_relaxed)).block); } /// Returns the page pointer and attribute pair, extracted from the same atomic read [[nodiscard]] std::tuple PointerTypeBlock(bool ignore_marked = false) const noexcept { - const Data non_atomic_raw = data.load(std::memory_order_relaxed); + const auto non_atomic_raw = std::bit_cast(data_raw.load(std::memory_order_relaxed)); return {ExtractPointer(non_atomic_raw, ignore_marked), static_cast(non_atomic_raw.type), static_cast(non_atomic_raw.block)}; } /// Write page info atomically constexpr void Store(bool marked, PageType type, u16 block, uintptr_t pointer) noexcept { - data.store({marked, type, block, pointer}); + data_raw.store(std::bit_cast(Data{marked, type, block, pointer})); } constexpr void MarkRasterizerCached() noexcept { @@ -110,12 +110,8 @@ struct PageTable { } private: - union { - std::atomic data; - std::atomic data_raw; - }; - static_assert(sizeof(std::atomic) == 8); - static_assert(std::atomic::is_always_lock_free); + std::atomic data_raw; + static_assert(sizeof(Data) == sizeof(std::atomic)); }; PageTable();