Skip to content

Commit a9e6ce0

Browse files
authored
Use std::atomic in shared data header (#1584)
1 parent bc5b8c1 commit a9e6ce0

File tree

4 files changed

+20
-10
lines changed

4 files changed

+20
-10
lines changed

ydb/library/actors/util/shared_data.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ namespace NActors {
2323
NActors::NMemory::TLabel<MemoryLabelSharedData>::Add(allocSize);
2424

2525
auto* header = reinterpret_cast<THeader*>(raw + PrivateHeaderSize);
26-
header->RefCount = 1;
27-
header->Owner = nullptr;
26+
new (header) THeader(nullptr);
2827

2928
data = raw + OverheadSize;
3029
NSan::Poison(data, size);
@@ -41,6 +40,7 @@ namespace NActors {
4140

4241
auto* header = reinterpret_cast<THeader*>(raw + PrivateHeaderSize);
4342
Y_DEBUG_ABORT_UNLESS(header->Owner == nullptr);
43+
header->~THeader();
4444

4545
y_deallocate(raw);
4646
}

ydb/library/actors/util/shared_data.h

+11-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <util/system/compiler.h>
77
#include <util/generic/array_ref.h>
88

9+
#include <atomic>
10+
911
namespace NActors {
1012

1113
class TSharedData {
@@ -25,8 +27,13 @@ namespace NActors {
2527
static_assert(sizeof(TPrivateHeader) == 16, "TPrivateHeader has an unexpected size");
2628

2729
struct THeader {
28-
TAtomic RefCount;
30+
std::atomic<size_t> RefCount;
2931
IOwner* Owner;
32+
33+
explicit THeader(IOwner* owner)
34+
: RefCount{ 1 }
35+
, Owner(owner)
36+
{}
3037
};
3138

3239
static_assert(sizeof(THeader) == 16, "THeader has an unexpected size");
@@ -193,19 +200,19 @@ namespace NActors {
193200
}
194201

195202
static bool IsPrivate(THeader* header) noexcept {
196-
return 1 == AtomicGet(header->RefCount);
203+
return 1 == header->RefCount.load(std::memory_order_relaxed);
197204
}
198205

199206
void AddRef() noexcept {
200207
if (Data_) {
201-
AtomicIncrement(Header()->RefCount);
208+
Header()->RefCount.fetch_add(1, std::memory_order_relaxed);
202209
}
203210
}
204211

205212
void Release() noexcept {
206213
if (Data_) {
207214
auto* header = Header();
208-
if (IsPrivate(header) || 0 == AtomicDecrement(header->RefCount)) {
215+
if (1 == header->RefCount.fetch_sub(1, std::memory_order_acq_rel)) {
209216
if (auto* owner = header->Owner) {
210217
owner->Deallocate(Data_);
211218
} else {

ydb/library/actors/util/shared_data_backtracing_owner.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ class TBackTracingOwner : public NActors::TSharedData::IOwner {
3030
TSelf* btOwner = new TSelf;
3131
btOwner->BackTrace.Capture();
3232
btOwner->Info = info;
33-
header->RefCount = 1;
34-
header->Owner = btOwner;
33+
new (header) THeader(btOwner);
3534
char* data = raw + OverheadSize;
3635
return data;
3736
}
@@ -59,6 +58,8 @@ class TBackTracingOwner : public NActors::TSharedData::IOwner {
5958

6059
void Deallocate(char* data) noexcept override {
6160
if (!RealOwner) {
61+
THeader* header = reinterpret_cast<THeader*>(data - sizeof(THeader));
62+
header->~THeader();
6263
char* raw = data - OverheadSize;
6364
y_deallocate(raw);
6465
} else {

ydb/library/actors/util/shared_data_ut.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ namespace NActors {
8080
TSharedData Allocate(size_t size) {
8181
char* raw = reinterpret_cast<char*>(y_allocate(sizeof(THeader) + size));
8282
THeader* header = reinterpret_cast<THeader*>(raw);
83-
header->RefCount = 1;
84-
header->Owner = this;
83+
new (header) THeader(this);
8584
char* data = raw + sizeof(THeader);
8685
Y_ABORT_UNLESS(Allocated_.insert(data).second);
8786
return TSharedData::AttachUnsafe(data, size);
@@ -90,6 +89,8 @@ namespace NActors {
9089
void Deallocate(char* data) noexcept {
9190
Y_ABORT_UNLESS(Allocated_.erase(data) > 0);
9291
char* raw = data - sizeof(THeader);
92+
THeader* header = reinterpret_cast<THeader*>(raw);
93+
header->~THeader();
9394
y_deallocate(raw);
9495
Deallocated_.push_back(data);
9596
}
@@ -190,6 +191,7 @@ namespace NActors {
190191
// Test Detach copies correctly and doesn't affect owned data
191192
{
192193
auto data = owner.Allocate(42);
194+
ptr = data.data();
193195
auto disowned = data;
194196
disowned.Detach();
195197
UNIT_ASSERT(owner.NextDeallocated() == nullptr);

0 commit comments

Comments
 (0)