From 10ec28c5de9442fe93635ae76ca397d138f9e93c Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Sat, 13 Apr 2024 01:41:13 +0200 Subject: Add atomics --- deimos/core/status.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'deimos/core/status.cpp') diff --git a/deimos/core/status.cpp b/deimos/core/status.cpp index ed1a665..f472aac 100644 --- a/deimos/core/status.cpp +++ b/deimos/core/status.cpp @@ -2,12 +2,20 @@ #include "deimos/core/api_registry.h" #include "deimos/core/allocator.h" +#include "deimos/core/atomic.h" static deimos::AllocatorApi* allocator_api; namespace deimos { +struct StatusRep +{ + Atomic ref_count; + StatusCode code{}; + StringView message; +}; + Status::Status(StatusCode code, StringView message) { if (code == StatusCode::kOk) @@ -23,7 +31,7 @@ Status::Status(StatusCode code, StringView message) MemoryCopy(message_ptr, message.data(), message.size()); message_ptr[message.size()] = '\0'; // NOLINT - rep->ref_count = 1; + AtomicStore(&rep->ref_count, 1); rep->code = code; rep->message = StringView(message_ptr, message.size()); @@ -38,22 +46,27 @@ void Status::Ref() const { auto* rep = std::bit_cast(m_rep); - Expects(rep->ref_count > 0); - rep->ref_count += 1; + Expects(AtomicLoad(&rep->ref_count) > 0); + AtomicFetchIncrement(&rep->ref_count); } } +StatusCode Status::RepCode() const +{ + Expects(!IsInline()); + return std::bit_cast(m_rep)->code; +} + void Status::Unref() const { if (!IsInline()) { auto* rep = std::bit_cast(m_rep); - Expects(rep->ref_count > 0); - rep->ref_count -= 1; - - if (rep->ref_count == 0) + Expects(AtomicLoad(&rep->ref_count) > 0); + if (AtomicFetchDecrement(&rep->ref_count, MemoryOrder::kRelease) == 1) { + AtomicFence(MemoryOrder::kAcquire); deimos_StaticAssert(std::is_trivially_destructible_v); allocator_api->system->Free( rep, (int64_t)sizeof(StatusRep) + rep->message.size() + 1); -- cgit