summaryrefslogtreecommitdiff
path: root/deimos/core/status.cpp
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2024-04-13 01:41:13 +0200
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2024-04-13 01:41:13 +0200
commit10ec28c5de9442fe93635ae76ca397d138f9e93c (patch)
tree7795ff5e2b15659f78328d14338a7c033f0ffe41 /deimos/core/status.cpp
parenta6abeaaf3a68e3b7072f75acae4cfdf720ad20f4 (diff)
Add atomics
Diffstat (limited to 'deimos/core/status.cpp')
-rw-r--r--deimos/core/status.cpp27
1 files changed, 20 insertions, 7 deletions
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<int32_t> 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<StatusRep*>(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<StatusRep*>(m_rep)->code;
+}
+
void Status::Unref() const
{
if (!IsInline())
{
auto* rep = std::bit_cast<StatusRep*>(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<StatusRep>);
allocator_api->system->Free(
rep, (int64_t)sizeof(StatusRep) + rep->message.size() + 1);