5
5
#include " executor_pool.h"
6
6
#include " mailbox_queue_simple.h"
7
7
#include " mailbox_queue_revolving.h"
8
+ #include < functional>
8
9
#include < ydb/library/actors/util/unordered_cache.h>
9
10
#include < library/cpp/threading/queue/mpsc_htswap.h>
10
11
#include < library/cpp/threading/queue/mpsc_read_as_filled.h>
@@ -27,6 +28,10 @@ namespace NActors {
27
28
28
29
struct TMailboxHeader ;
29
30
31
+ struct TMailboxStats {
32
+ ui64 ElapsedCycles = 0 ;
33
+ };
34
+
30
35
template <bool >
31
36
struct TMailboxUsageImpl {
32
37
void Push (ui64 /* localId*/ ) {}
@@ -53,7 +58,8 @@ namespace NActors {
53
58
enum EType {
54
59
Simple = 0 ,
55
60
Array = 1 ,
56
- Map = 2
61
+ Map = 2 ,
62
+ Complex = 3 ,
57
63
};
58
64
};
59
65
@@ -79,7 +85,7 @@ namespace NActors {
79
85
volatile ui32 ExecutionState;
80
86
ui32 Reserved : 4 ; // never changes, always zero
81
87
ui32 Type : 4 ; // never changes
82
- ui32 ActorPack : 2 ;
88
+ TMailboxActorPack::EType ActorPack : 2 ;
83
89
ui32 Knobs : 22 ;
84
90
85
91
struct TActorPair {
@@ -91,6 +97,8 @@ namespace NActors {
91
97
TActorPair Actors[ARRAY_CAPACITY];
92
98
};
93
99
100
+ struct alignas (64 ) TComplexActorInfo;
101
+
94
102
union TActorsInfo {
95
103
TActorPair Simple;
96
104
struct {
@@ -100,11 +108,19 @@ namespace NActors {
100
108
struct {
101
109
TActorMap* ActorsMap;
102
110
} Map;
111
+ TComplexActorInfo* Complex;
103
112
} ActorsInfo;
104
113
114
+ struct alignas (64 ) TComplexActorInfo{
115
+ TActorsInfo ActorsInfo;
116
+ TMailboxActorPack::EType ActorPack;
117
+ TMailboxStats Stats;
118
+ };
119
+
105
120
TMailboxHeader (TMailboxType::EType type);
106
121
~TMailboxHeader ();
107
122
123
+ static bool CleanupActors (TMailboxActorPack::EType &actorPack, TActorsInfo &ActorsInfo);
108
124
bool CleanupActors ();
109
125
110
126
// this interface is used exclusively by executor thread, so implementation is there
@@ -119,12 +135,13 @@ namespace NActors {
119
135
bool UnlockAsFree (bool wouldReschedule); // preceed with releasing lock, but mark as free one
120
136
121
137
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 );
123
140
}
124
141
125
142
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 ) {
128
145
case TMailboxActorPack::Simple:
129
146
if (ActorsInfo.Simple .ActorId ) {
130
147
callback (ActorsInfo.Simple .ActorId , ActorsInfo.Simple .Actor );
@@ -143,10 +160,22 @@ namespace NActors {
143
160
callback (row.ActorId , row.Actor );
144
161
}
145
162
break ;
163
+
164
+ case TMailboxActorPack::Complex:
165
+ Y_ABORT (" Unexpected ActorPack type" );
146
166
}
147
167
}
148
168
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 {
150
179
switch (ActorPack) {
151
180
case TMailboxActorPack::Simple: {
152
181
if (ActorsInfo.Simple .ActorId == localActorId)
@@ -167,14 +196,22 @@ namespace NActors {
167
196
}
168
197
break ;
169
198
}
170
- default :
171
- Y_ABORT ();
199
+ case TMailboxActorPack::Complex :
200
+ Y_ABORT (" Unexpected ActorPack type " );
172
201
}
173
202
return nullptr ;
174
203
}
175
204
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) {
178
215
case TMailboxActorPack::Simple: {
179
216
if (ActorsInfo.Simple .ActorId == 0 ) {
180
217
ActorsInfo.Simple .ActorId = localActorId;
@@ -185,7 +222,7 @@ namespace NActors {
185
222
ar->Actors [0 ] = ActorsInfo.Simple ;
186
223
ar->Actors [1 ] = TActorPair{actor, localActorId};
187
224
ActorsInfo.Array .ActorsCount = 2 ;
188
- ActorPack = TMailboxActorPack::Array;
225
+ actorPack = TMailboxActorPack::Array;
189
226
ActorsInfo.Array .ActorsArray = ar;
190
227
}
191
228
break ;
@@ -201,7 +238,7 @@ namespace NActors {
201
238
mp->emplace (ActorsInfo.Array .ActorsArray ->Actors [i].ActorId , ActorsInfo.Array .ActorsArray ->Actors [i].Actor );
202
239
}
203
240
mp->emplace (localActorId, actor);
204
- ActorPack = TMailboxActorPack::Map;
241
+ actorPack = TMailboxActorPack::Map;
205
242
ActorsInfo.Array .ActorsCount = 0 ;
206
243
delete ActorsInfo.Array .ActorsArray ;
207
244
ActorsInfo.Map .ActorsMap = mp;
@@ -210,17 +247,27 @@ namespace NActors {
210
247
}
211
248
break ;
212
249
}
213
- default :
214
- Y_ABORT ();
250
+ case TMailboxActorPack::Complex :
251
+ Y_ABORT (" Unexpected ActorPack type " );
215
252
}
216
253
}
217
254
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 );
220
267
221
268
IActor* actorToDestruct = nullptr ;
222
269
223
- switch (ActorPack ) {
270
+ switch (actorPack ) {
224
271
case TMailboxActorPack::Simple: {
225
272
Y_ABORT_UNLESS (ActorsInfo.Simple .ActorId == localActorId);
226
273
actorToDestruct = ActorsInfo.Simple .Actor ;
@@ -243,7 +290,7 @@ namespace NActors {
243
290
ar->Actors [i++] = TActorPair{actor, actorId};
244
291
}
245
292
delete ActorsInfo.Map .ActorsMap ;
246
- ActorPack = TMailboxActorPack::Array;
293
+ actorPack = TMailboxActorPack::Array;
247
294
ActorsInfo.Array .ActorsArray = ar;
248
295
ActorsInfo.Array .ActorsCount = ARRAY_CAPACITY;
249
296
}
@@ -265,16 +312,50 @@ namespace NActors {
265
312
if (ActorsInfo.Array .ActorsCount == 1 ) {
266
313
const TActorPair Actor = ActorsInfo.Array .ActorsArray ->Actors [0 ];
267
314
delete ActorsInfo.Array .ActorsArray ;
268
- ActorPack = TMailboxActorPack::Simple;
315
+ actorPack = TMailboxActorPack::Simple;
269
316
ActorsInfo.Simple = Actor;
270
317
}
271
318
break ;
272
319
}
320
+ case TMailboxActorPack::Complex:
321
+ Y_ABORT (" Unexpected ActorPack type" );
273
322
}
274
323
275
324
return actorToDestruct;
276
325
}
277
326
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
+
278
359
std::pair<ui32, ui32> CountMailboxEvents (ui64 localActorId, ui32 maxTraverse);
279
360
};
280
361
0 commit comments