Skip to content

Commit 0032663

Browse files
authored
Add mailbox stat (#6680)
1 parent 4dbd617 commit 0032663

File tree

5 files changed

+130
-23
lines changed

5 files changed

+130
-23
lines changed

ydb/library/actors/core/actor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ namespace NActors {
161161
return NHPTimer::GetSeconds(GetCurrentEventTicks());
162162
}
163163

164+
void TActivationContext::EnableMailboxStats() {
165+
TlsActivationContext->Mailbox.EnableStats();
166+
}
167+
164168
TActorId IActor::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) const noexcept {
165169
return TlsActivationContext->ExecutorThread.RegisterActor(actor, mailboxType, poolId, SelfActorId);
166170
}

ydb/library/actors/core/actor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "actorsystem.h"
44
#include "event.h"
55
#include "executor_thread.h"
6+
#include "mailbox.h"
67
#include "monotonic.h"
78
#include "thread_context.h"
89

@@ -130,6 +131,8 @@ namespace NActors {
130131

131132
static i64 GetCurrentEventTicks();
132133
static double GetCurrentEventTicksAsSeconds();
134+
135+
static void EnableMailboxStats();
133136
};
134137

135138
struct TActorContext: public TActivationContext {

ydb/library/actors/core/executor_thread.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ namespace NActors {
269269

270270
Ctx.AddElapsedCycles(activityType, hpnow - hpprev);
271271
NHPTimer::STime elapsed = Ctx.AddEventProcessingStats(eventStart, hpnow, activityType, CurrentActorScheduledEventsCounter);
272+
mailbox->AddElapsedCycles(elapsed);
272273
if (elapsed > 1000000) {
273274
LwTraceSlowEvent(ev.Get(), evTypeForTracing, actorType, Ctx.PoolId, CurrentRecipient, NHPTimer::GetSeconds(elapsed) * 1000.0);
274275
}
@@ -372,7 +373,7 @@ namespace NActors {
372373
break; // empty queue, leave
373374
}
374375
}
375-
TlsThreadContext->ActivationStartTS.store(GetCycleCountFast(), std::memory_order_release);
376+
TlsThreadContext->ActivationStartTS.store(hpnow, std::memory_order_release);
376377
TlsThreadContext->ElapsingActorActivity.store(ActorSystemIndex, std::memory_order_release);
377378

378379
NProfiling::TMemoryTagScope::Reset(0);

ydb/library/actors/core/mailbox.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,9 +373,9 @@ namespace NActors {
373373
CleanupActors();
374374
}
375375

376-
bool TMailboxHeader::CleanupActors() {
376+
bool TMailboxHeader::CleanupActors(TMailboxActorPack::EType &actorPack, TActorsInfo &ActorsInfo) {
377377
bool done = true;
378-
switch (ActorPack) {
378+
switch (actorPack) {
379379
case TMailboxActorPack::Simple: {
380380
if (ActorsInfo.Simple.ActorId != 0) {
381381
delete ActorsInfo.Simple.Actor;
@@ -399,13 +399,31 @@ namespace NActors {
399399
done = false;
400400
break;
401401
}
402+
case TMailboxActorPack::Complex:
403+
Y_ABORT("Unexpected ActorPack type");
402404
}
403-
ActorPack = TMailboxActorPack::Simple;
405+
actorPack = TMailboxActorPack::Simple;
404406
ActorsInfo.Simple.ActorId = 0;
405407
ActorsInfo.Simple.Actor = nullptr;
406408
return done;
407409
}
408410

411+
bool TMailboxHeader::CleanupActors() {
412+
if (ActorPack != TMailboxActorPack::Complex) {
413+
TMailboxActorPack::EType pack = ActorPack;
414+
bool done = CleanupActors(pack, ActorsInfo);
415+
ActorPack = pack;
416+
return done;
417+
} else {
418+
bool done = CleanupActors(ActorsInfo.Complex->ActorPack, ActorsInfo.Complex->ActorsInfo);
419+
delete ActorsInfo.Complex;
420+
ActorPack = TMailboxActorPack::Simple;
421+
ActorsInfo.Simple.ActorId = 0;
422+
ActorsInfo.Simple.Actor = nullptr;
423+
return done;
424+
}
425+
}
426+
409427
std::pair<ui32, ui32> TMailboxHeader::CountMailboxEvents(ui64 localActorId, ui32 maxTraverse) {
410428
switch (Type) {
411429
case TMailboxType::Simple:

ydb/library/actors/core/mailbox.h

Lines changed: 100 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "executor_pool.h"
66
#include "mailbox_queue_simple.h"
77
#include "mailbox_queue_revolving.h"
8+
#include <functional>
89
#include <ydb/library/actors/util/unordered_cache.h>
910
#include <library/cpp/threading/queue/mpsc_htswap.h>
1011
#include <library/cpp/threading/queue/mpsc_read_as_filled.h>
@@ -27,6 +28,10 @@ namespace NActors {
2728

2829
struct TMailboxHeader;
2930

31+
struct TMailboxStats {
32+
ui64 ElapsedCycles = 0;
33+
};
34+
3035
template<bool>
3136
struct TMailboxUsageImpl {
3237
void Push(ui64 /*localId*/) {}
@@ -53,7 +58,8 @@ namespace NActors {
5358
enum EType {
5459
Simple = 0,
5560
Array = 1,
56-
Map = 2
61+
Map = 2,
62+
Complex = 3,
5763
};
5864
};
5965

@@ -79,7 +85,7 @@ namespace NActors {
7985
volatile ui32 ExecutionState;
8086
ui32 Reserved : 4; // never changes, always zero
8187
ui32 Type : 4; // never changes
82-
ui32 ActorPack : 2;
88+
TMailboxActorPack::EType ActorPack : 2;
8389
ui32 Knobs : 22;
8490

8591
struct TActorPair {
@@ -91,6 +97,8 @@ namespace NActors {
9197
TActorPair Actors[ARRAY_CAPACITY];
9298
};
9399

100+
struct alignas(64) TComplexActorInfo;
101+
94102
union TActorsInfo {
95103
TActorPair Simple;
96104
struct {
@@ -100,11 +108,19 @@ namespace NActors {
100108
struct {
101109
TActorMap* ActorsMap;
102110
} Map;
111+
TComplexActorInfo* Complex;
103112
} ActorsInfo;
104113

114+
struct alignas(64) TComplexActorInfo{
115+
TActorsInfo ActorsInfo;
116+
TMailboxActorPack::EType ActorPack;
117+
TMailboxStats Stats;
118+
};
119+
105120
TMailboxHeader(TMailboxType::EType type);
106121
~TMailboxHeader();
107122

123+
static bool CleanupActors(TMailboxActorPack::EType &actorPack, TActorsInfo &ActorsInfo);
108124
bool CleanupActors();
109125

110126
// this interface is used exclusively by executor thread, so implementation is there
@@ -119,12 +135,13 @@ namespace NActors {
119135
bool UnlockAsFree(bool wouldReschedule); // preceed with releasing lock, but mark as free one
120136

121137
bool IsEmpty() const noexcept {
122-
return (ActorPack == TMailboxActorPack::Simple && ActorsInfo.Simple.ActorId == 0);
138+
return (ActorPack == TMailboxActorPack::Simple && ActorsInfo.Simple.ActorId == 0) ||
139+
(ActorPack == TMailboxActorPack::Complex && ActorsInfo.Complex->ActorPack == TMailboxActorPack::Simple && ActorsInfo.Complex->ActorsInfo.Simple.ActorId == 0);
123140
}
124141

125142
template<typename T>
126-
void ForEach(T&& callback) noexcept {
127-
switch (ActorPack) {
143+
static void ForEach(TMailboxActorPack::EType actorPack, TActorsInfo &ActorsInfo, T&& callback) noexcept {
144+
switch (actorPack) {
128145
case TMailboxActorPack::Simple:
129146
if (ActorsInfo.Simple.ActorId) {
130147
callback(ActorsInfo.Simple.ActorId, ActorsInfo.Simple.Actor);
@@ -143,10 +160,22 @@ namespace NActors {
143160
callback(row.ActorId, row.Actor);
144161
}
145162
break;
163+
164+
case TMailboxActorPack::Complex:
165+
Y_ABORT("Unexpected ActorPack type");
146166
}
147167
}
148168

149-
IActor* FindActor(ui64 localActorId) noexcept {
169+
template<typename T>
170+
void ForEach(T&& callback) noexcept {
171+
if (ActorPack != TMailboxActorPack::Complex) {
172+
ForEach(static_cast<TMailboxActorPack::EType>(ActorPack), ActorsInfo, std::move(callback));
173+
} else {
174+
ForEach(ActorsInfo.Complex->ActorPack, ActorsInfo.Complex->ActorsInfo, std::move(callback));
175+
}
176+
}
177+
178+
static IActor* FindActor(TMailboxActorPack::EType ActorPack, TActorsInfo &ActorsInfo, ui64 localActorId) noexcept {
150179
switch (ActorPack) {
151180
case TMailboxActorPack::Simple: {
152181
if (ActorsInfo.Simple.ActorId == localActorId)
@@ -167,14 +196,22 @@ namespace NActors {
167196
}
168197
break;
169198
}
170-
default:
171-
Y_ABORT();
199+
case TMailboxActorPack::Complex:
200+
Y_ABORT("Unexpected ActorPack type");
172201
}
173202
return nullptr;
174203
}
175204

176-
void AttachActor(ui64 localActorId, IActor* actor) noexcept {
177-
switch (ActorPack) {
205+
IActor* FindActor(ui64 localActorId) noexcept {
206+
if (ActorPack != TMailboxActorPack::Complex) {
207+
return FindActor(static_cast<TMailboxActorPack::EType>(ActorPack), ActorsInfo, localActorId);
208+
} else {
209+
return FindActor(ActorsInfo.Complex->ActorPack, ActorsInfo.Complex->ActorsInfo, localActorId);
210+
}
211+
}
212+
213+
static void AttachActor(TMailboxActorPack::EType &actorPack, TActorsInfo &ActorsInfo, ui64 localActorId, IActor* actor) noexcept {
214+
switch (actorPack) {
178215
case TMailboxActorPack::Simple: {
179216
if (ActorsInfo.Simple.ActorId == 0) {
180217
ActorsInfo.Simple.ActorId = localActorId;
@@ -185,7 +222,7 @@ namespace NActors {
185222
ar->Actors[0] = ActorsInfo.Simple;
186223
ar->Actors[1] = TActorPair{actor, localActorId};
187224
ActorsInfo.Array.ActorsCount = 2;
188-
ActorPack = TMailboxActorPack::Array;
225+
actorPack = TMailboxActorPack::Array;
189226
ActorsInfo.Array.ActorsArray = ar;
190227
}
191228
break;
@@ -201,7 +238,7 @@ namespace NActors {
201238
mp->emplace(ActorsInfo.Array.ActorsArray->Actors[i].ActorId, ActorsInfo.Array.ActorsArray->Actors[i].Actor);
202239
}
203240
mp->emplace(localActorId, actor);
204-
ActorPack = TMailboxActorPack::Map;
241+
actorPack = TMailboxActorPack::Map;
205242
ActorsInfo.Array.ActorsCount = 0;
206243
delete ActorsInfo.Array.ActorsArray;
207244
ActorsInfo.Map.ActorsMap = mp;
@@ -210,17 +247,27 @@ namespace NActors {
210247
}
211248
break;
212249
}
213-
default:
214-
Y_ABORT();
250+
case TMailboxActorPack::Complex:
251+
Y_ABORT("Unexpected ActorPack type");
215252
}
216253
}
217254

218-
IActor* DetachActor(ui64 localActorId) noexcept {
219-
Y_DEBUG_ABORT_UNLESS(FindActor(localActorId) != nullptr);
255+
void AttachActor(ui64 localActorId, IActor* actor) noexcept {
256+
if (ActorPack != TMailboxActorPack::Complex) {
257+
TMailboxActorPack::EType pack = ActorPack;
258+
AttachActor(pack, ActorsInfo, localActorId, actor);
259+
ActorPack = pack;
260+
} else {
261+
AttachActor(ActorsInfo.Complex->ActorPack, ActorsInfo.Complex->ActorsInfo, localActorId, actor);
262+
}
263+
}
264+
265+
static IActor* DetachActor(TMailboxActorPack::EType &actorPack, TActorsInfo &ActorsInfo, ui64 localActorId) noexcept {
266+
Y_DEBUG_ABORT_UNLESS(FindActor(actorPack, ActorsInfo, localActorId) != nullptr);
220267

221268
IActor* actorToDestruct = nullptr;
222269

223-
switch (ActorPack) {
270+
switch (actorPack) {
224271
case TMailboxActorPack::Simple: {
225272
Y_ABORT_UNLESS(ActorsInfo.Simple.ActorId == localActorId);
226273
actorToDestruct = ActorsInfo.Simple.Actor;
@@ -243,7 +290,7 @@ namespace NActors {
243290
ar->Actors[i++] = TActorPair{actor, actorId};
244291
}
245292
delete ActorsInfo.Map.ActorsMap;
246-
ActorPack = TMailboxActorPack::Array;
293+
actorPack = TMailboxActorPack::Array;
247294
ActorsInfo.Array.ActorsArray = ar;
248295
ActorsInfo.Array.ActorsCount = ARRAY_CAPACITY;
249296
}
@@ -265,16 +312,50 @@ namespace NActors {
265312
if (ActorsInfo.Array.ActorsCount == 1) {
266313
const TActorPair Actor = ActorsInfo.Array.ActorsArray->Actors[0];
267314
delete ActorsInfo.Array.ActorsArray;
268-
ActorPack = TMailboxActorPack::Simple;
315+
actorPack = TMailboxActorPack::Simple;
269316
ActorsInfo.Simple = Actor;
270317
}
271318
break;
272319
}
320+
case TMailboxActorPack::Complex:
321+
Y_ABORT("Unexpected ActorPack type");
273322
}
274323

275324
return actorToDestruct;
276325
}
277326

327+
IActor* DetachActor(ui64 localActorId) noexcept {
328+
if (ActorPack != TMailboxActorPack::Complex) {
329+
TMailboxActorPack::EType pack = ActorPack;
330+
IActor* result = DetachActor(pack, ActorsInfo, localActorId);
331+
ActorPack = pack;
332+
return result;
333+
} else {
334+
return DetachActor(ActorsInfo.Complex->ActorPack, ActorsInfo.Complex->ActorsInfo, localActorId);
335+
}
336+
}
337+
338+
void EnableStats() {
339+
TComplexActorInfo* complex = new TComplexActorInfo;
340+
complex->ActorPack = ActorPack;
341+
complex->ActorsInfo = std::move(ActorsInfo);
342+
ActorPack = TMailboxActorPack::Complex;
343+
ActorsInfo.Complex = complex;
344+
}
345+
346+
void AddElapsedCycles(ui64 elapsed) {
347+
if (ActorPack == TMailboxActorPack::Complex) {
348+
ActorsInfo.Complex->Stats.ElapsedCycles += elapsed;
349+
}
350+
}
351+
352+
std::optional<ui64> GetElapsedCycles() {
353+
if (ActorPack == TMailboxActorPack::Complex) {
354+
return ActorsInfo.Complex->Stats.ElapsedCycles;
355+
}
356+
return std::nullopt;
357+
}
358+
278359
std::pair<ui32, ui32> CountMailboxEvents(ui64 localActorId, ui32 maxTraverse);
279360
};
280361

0 commit comments

Comments
 (0)