diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-04-13 01:41:13 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-04-13 01:41:13 +0200 |
commit | 10ec28c5de9442fe93635ae76ca397d138f9e93c (patch) | |
tree | 7795ff5e2b15659f78328d14338a7c033f0ffe41 /deimos/core/status.cpp | |
parent | a6abeaaf3a68e3b7072f75acae4cfdf720ad20f4 (diff) |
Add atomics
Diffstat (limited to 'deimos/core/status.cpp')
-rw-r--r-- | deimos/core/status.cpp | 27 |
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);
|