Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #ifndef QUEUE_SCHEDULE_STATISTIC_MANAGER_H
12 : #define QUEUE_SCHEDULE_STATISTIC_MANAGER_H
13 :
14 : #include <atomic>
15 : #include <thread>
16 : #include <mutex>
17 : #include <condition_variable>
18 :
19 : #include "common/type_def.h"
20 : #include "qs_proc_mem_statistic.h"
21 :
22 : namespace bqs {
23 : struct EntityStatisticInfo {
24 : // call HcclImprobe total times (envelope-probed + non-envelope-probed + failed times)
25 : uint64_t hcclImprobeTotalTimes;
26 : // call HcclImprobe succ times (envelope-probed times)
27 : uint64_t hcclImprobeSuccTimes;
28 : // call HcclImprobe failed times
29 : uint64_t hcclImprobeFailTimes;
30 : // alloc mbuf times
31 : uint64_t allocMbufTimes;
32 : // call HcclImrecv succ times
33 : uint64_t hcclImrecvSuccTimes;
34 : // call HcclImrecv failed times
35 : uint64_t hcclImrecvFailTimes;
36 : // uncompReqQueue push times
37 : uint64_t uncompReqQueuePushTimes;
38 : // uncompReqQueue pop times
39 : uint64_t uncompReqQueuePopTimes;
40 : // call HcclIsend succ times
41 : uint64_t hcclIsendSuccTimes;
42 : // call HcclIsend full times
43 : uint64_t hcclIsendFullTimes;
44 : // call HcclIsend fail times
45 : uint64_t hcclIsendFailTimes;
46 : // call HcclTestSome succ times
47 : uint64_t hcclTestSomeSuccTimes;
48 : // free mbuf times (hccl send succ)
49 : uint64_t freeMbufTimes;
50 : // hccl enqueue succ times
51 : uint64_t hcclEnqueueSuccTimes;
52 : // hccl dequeue fail times
53 : uint64_t hcclEnqueueFailTimes;
54 : // tag or queue dequeue succ times in peek state
55 : uint64_t dequeueSuccTimes;
56 : // tag or queue dequeue fail times in peek state
57 : uint64_t dequeueFailTimes;
58 : // tag or queue dequeue empty times in peek state
59 : uint64_t dequeueEmptyTimes;
60 : // statistic for head transfering on tag
61 : uint64_t maxCompletionGapTickForHead;
62 : uint64_t minCompletionGapTickForHead;
63 : uint64_t totalCompletionGapTickForHead;
64 : uint64_t totalCompletionCountForHead;
65 : // statistic for body transfering on tag
66 : uint64_t maxCompletionGapTickForBody;
67 : uint64_t minCompletionGapTickForBody;
68 : uint64_t totalCompletionGapTickForBody;
69 : uint64_t totalCompletionCountForBody;
70 : // tag or queue enqueue succ times in peek state
71 : uint64_t enqueueSuccTimes;
72 :
73 366 : EntityStatisticInfo()
74 366 : : hcclImprobeTotalTimes(0UL),
75 366 : hcclImprobeSuccTimes(0UL),
76 366 : hcclImprobeFailTimes(0UL),
77 366 : allocMbufTimes(0UL),
78 366 : hcclImrecvSuccTimes(0UL),
79 366 : hcclImrecvFailTimes(0UL),
80 366 : uncompReqQueuePushTimes(0UL),
81 366 : uncompReqQueuePopTimes(0UL),
82 366 : hcclIsendSuccTimes(0UL),
83 366 : hcclIsendFullTimes(0UL),
84 366 : hcclIsendFailTimes(0UL),
85 366 : hcclTestSomeSuccTimes(0UL),
86 366 : freeMbufTimes(0UL),
87 366 : hcclEnqueueSuccTimes(0UL),
88 366 : hcclEnqueueFailTimes(0UL),
89 366 : dequeueSuccTimes(0UL),
90 366 : dequeueFailTimes(0UL),
91 366 : dequeueEmptyTimes(0UL),
92 366 : maxCompletionGapTickForHead(0UL),
93 366 : minCompletionGapTickForHead(0UL),
94 366 : totalCompletionGapTickForHead(0UL),
95 366 : totalCompletionCountForHead(0UL),
96 366 : maxCompletionGapTickForBody(0UL),
97 366 : minCompletionGapTickForBody(0UL),
98 366 : totalCompletionGapTickForBody(0UL),
99 366 : totalCompletionCountForBody(0UL),
100 366 : enqueueSuccTimes(0UL) {}
101 : };
102 :
103 : struct StatisticInfo {
104 : // event schedule times
105 : std::atomic<uint64_t> eventScheduleTimes;
106 : // enqueue event false waken times
107 : std::atomic<uint64_t> enqueueFalseAwakenTimes;
108 : // event schedule times
109 : std::atomic<uint64_t> daemonEventScheduleTimes;
110 : // awaken times
111 : std::atomic<uint64_t> awakenTimes;
112 : // data dequeue times
113 : std::atomic<uint64_t> dataDequeueTimes;
114 : // sched empty times
115 : std::atomic<uint64_t> scheduleEmptyTimes;
116 : // data schedule failed times
117 : std::atomic<uint64_t> dataScheduleFailedTimes;
118 : // relation queue enqueue times
119 : std::atomic<uint64_t> relationEnqueueTimes;
120 : // relation queue dequeue times
121 : std::atomic<uint64_t> relationDequeueTimes;
122 : // async mem queue enqueue times
123 : std::atomic<uint64_t> asynMemEnqueueTimes;
124 : // async mem queue dequeue times
125 : std::atomic<uint64_t> asynMemDequeueTimes;
126 : // full ot not full queue enqueue times
127 : std::atomic<uint64_t> f2nfEnqueueTimes;
128 : // full ot not full queue dequeue times
129 : std::atomic<uint64_t> f2nfDequeueTimes;
130 : // bind relation request times
131 : std::atomic<uint64_t> bindTimes;
132 : // unbind relation request times
133 : std::atomic<uint64_t> unbindTimes;
134 : // get bind relation request times
135 : std::atomic<uint64_t> getBindTimes;
136 : // get all bind relation request times
137 : std::atomic<uint64_t> getAllBindTimes;
138 : // relation response times
139 : std::atomic<uint64_t> responseTimes;
140 : // enqueue success times
141 : std::atomic<uint64_t> dataEnqueueSuccTimes;
142 : // enqueue fail times
143 : std::atomic<uint64_t> dataEnqueueFailTimes;
144 : // enqueue full times
145 : std::atomic<uint64_t> dataEnqueueFullTimes;
146 : // hccl mpi recv request event times
147 : std::atomic<uint64_t> hcclMpiRecvRequestEventTimes;
148 : // hccl mpi recv request event false awaken times
149 : std::atomic<uint64_t> hcclMpiRecvReqFalseAwakenTimes;
150 : // hccl mpi recv request event empty sched times
151 : std::atomic<uint64_t> hcclMpiRecvReqEmptySchedTimes;
152 : // hccl mpi recv request event callback times
153 : std::atomic<uint64_t> hcclMpiRecvReqCallbackTimes;
154 : // hccl mpi send completion event times
155 : std::atomic<uint64_t> hcclMpiSendCompEventTimes;
156 : // hccl mpi send completion event false awaken times
157 : std::atomic<uint64_t> hcclMpiSendCompFalseAwakenTimes;
158 : // hccl mpi send completion event empty sched times
159 : std::atomic<uint64_t> hcclMpiSendCompEmptySchedTimes;
160 : // hccl mpi recv request event callback times
161 : std::atomic<uint64_t> hcclMpiSendCompCallbackTimes;
162 : // hccl mpi recv completion event times
163 : std::atomic<uint64_t> hcclMpiRecvCompEventTimes;
164 : // hccl mpi recv completion event false awaken times
165 : std::atomic<uint64_t> hcclMpiRecvCompFalseAwakenTimes;
166 : // hccl mpi recv completion event empty sched times
167 : std::atomic<uint64_t> hcclMpiRecvCompEmptySchedTimes;
168 : // hccl mpi recv completion event callback times
169 : std::atomic<uint64_t> hcclMpiRecvCompCallbackTimes;
170 : // f2nf event times
171 : std::atomic<uint64_t> f2nfEventTimes;
172 : // f2nf event false awaken times
173 : std::atomic<uint64_t> f2nfFalseAwakenTimes;
174 : // hccl mpi call recv success times
175 : std::atomic<uint64_t> hcclMpiRecvSuccTimes;
176 : // hccl mpi call recv failed taimes
177 : std::atomic<uint64_t> hcclMpiRecvFailTimes;
178 : // hccl mpi call send success times
179 : std::atomic<uint64_t> hcclMpiSendSuccTimes;
180 : // hccl mpi call send failed taimes
181 : std::atomic<uint64_t> hcclMpiSendFailTimes;
182 : // hccl mpi call send full taimes
183 : std::atomic<uint64_t> hcclMpiSendFullTimes;
184 : // hccl mpi congestion relief event times
185 : std::atomic<uint64_t> hcclMpiF2nfEventTimes;
186 : // mbuf alloc size
187 : std::atomic<uint64_t> mbufAllocSize;
188 : // mbuf alloc times
189 : std::atomic<uint64_t> mbufAllocTimes;
190 : // mbuf free size
191 : std::atomic<uint64_t> mbufFreeSize;
192 : // mbuf free times
193 : std::atomic<uint64_t> mbufFreeTimes;
194 : // supply recv request event times
195 : std::atomic<uint64_t> supplyRecvReqEventTimes;
196 :
197 6 : StatisticInfo()
198 6 : {
199 6 : Reset();
200 6 : }
201 :
202 18 : void Reset()
203 : {
204 18 : eventScheduleTimes.store(0UL);
205 18 : enqueueFalseAwakenTimes.store(0UL);
206 18 : daemonEventScheduleTimes.store(0UL);
207 18 : awakenTimes.store(0UL);
208 18 : dataDequeueTimes.store(0UL);
209 18 : scheduleEmptyTimes.store(0UL);
210 18 : dataScheduleFailedTimes.store(0UL);
211 18 : relationEnqueueTimes.store(0UL);
212 18 : relationDequeueTimes.store(0UL);
213 18 : asynMemEnqueueTimes.store(0UL);
214 18 : asynMemDequeueTimes.store(0UL);
215 18 : f2nfEnqueueTimes.store(0UL);
216 18 : f2nfDequeueTimes.store(0UL);
217 18 : bindTimes.store(0UL);
218 18 : unbindTimes.store(0UL);
219 18 : getBindTimes.store(0UL);
220 18 : getAllBindTimes.store(0UL);
221 18 : responseTimes.store(0UL);
222 18 : dataEnqueueSuccTimes.store(0UL);
223 18 : dataEnqueueFailTimes.store(0UL);
224 18 : dataEnqueueFullTimes.store(0UL);
225 18 : hcclMpiRecvRequestEventTimes.store(0UL);
226 18 : hcclMpiRecvReqFalseAwakenTimes.store(0UL);
227 18 : hcclMpiRecvReqEmptySchedTimes.store(0UL);
228 18 : hcclMpiRecvReqCallbackTimes.store(0UL);
229 18 : hcclMpiSendCompEventTimes.store(0UL);
230 18 : hcclMpiSendCompFalseAwakenTimes.store(0UL);
231 18 : hcclMpiSendCompEmptySchedTimes.store(0UL);
232 18 : hcclMpiSendCompCallbackTimes.store(0UL);
233 18 : hcclMpiRecvCompEventTimes.store(0UL);
234 18 : hcclMpiRecvCompFalseAwakenTimes.store(0UL);
235 18 : hcclMpiRecvCompEmptySchedTimes.store(0UL);
236 18 : hcclMpiRecvCompCallbackTimes.store(0UL);
237 18 : f2nfEventTimes.store(0UL);
238 18 : f2nfFalseAwakenTimes.store(0UL);
239 18 : hcclMpiRecvSuccTimes.store(0UL);
240 18 : hcclMpiRecvFailTimes.store(0UL);
241 18 : hcclMpiSendSuccTimes.store(0UL);
242 18 : hcclMpiSendFailTimes.store(0UL);
243 18 : hcclMpiSendFullTimes.store(0UL);
244 18 : hcclMpiF2nfEventTimes.store(0UL);
245 18 : mbufAllocSize.store(0UL);
246 18 : mbufAllocTimes.store(0UL);
247 18 : mbufFreeSize.store(0UL);
248 18 : mbufFreeTimes.store(0UL);
249 18 : supplyRecvReqEventTimes.store(0UL);
250 18 : };
251 : };
252 :
253 : class ScheduleStatistic {
254 : public:
255 3 : ScheduleStatistic()
256 3 : {
257 3 : Reset();
258 3 : };
259 :
260 : ~ScheduleStatistic() = default;
261 :
262 : void Reset();
263 :
264 : void UpdateProcessCost(const float64_t cost);
265 :
266 : void UpdateScheduleDelay(const float64_t delay);
267 :
268 : float64_t GetMaxProcessCost();
269 :
270 : float64_t GetSecondProcessCost();
271 :
272 : float64_t GetMaxScheduleDelay();
273 :
274 : float64_t GetAvgProcessCost();
275 :
276 : private:
277 : float64_t maxProcessCostUs_;
278 : float64_t secondMaxProcessUs_;
279 : float64_t maxScheduleDelayUs_;
280 : std::mutex mutex_;
281 : float64_t totalProcessCostUs_;
282 : uint64_t totalProcessCount_;
283 : };
284 :
285 : class StatisticManager {
286 : public:
287 : static StatisticManager &GetInstance();
288 :
289 : ~StatisticManager();
290 :
291 : StatisticManager(const StatisticManager &) = delete;
292 :
293 : StatisticManager &operator=(const StatisticManager &) = delete;
294 :
295 : StatisticManager(StatisticManager &&) = delete;
296 :
297 : StatisticManager &operator=(StatisticManager &&) = delete;
298 :
299 : public:
300 : /**
301 : * event schedule statistic.
302 : * @param scheduleNum schedule num, default is 1.
303 : */
304 : uint64_t EventScheduleStat(const uint32_t scheduleNum = 1U);
305 :
306 : /**
307 : * enqueue event false awaken times
308 : */
309 : void EnqueueEventFalseAwakenStat();
310 :
311 : /**
312 : * get event schedule statistic.
313 : */
314 : uint64_t GetEventScheduleStat() const;
315 :
316 : /**
317 : * daemon event schedule statistic.
318 : */
319 : void DaemonEventScheduleStat();
320 :
321 : /**
322 : * awaken count add.
323 : */
324 : void AwakenAdd();
325 :
326 : /**
327 : * return awaken times.
328 : */
329 : uint64_t GetAwakenTimes() const;
330 :
331 : /**
332 : * data sched empty statistic.
333 : */
334 : void AddScheduleEmpty();
335 :
336 : /**
337 : * data schedule failed statistic.
338 : * @param failedNum: data schedule failed, default is 1
339 : */
340 : void DataScheduleFailedStat(const uint64_t failedNum = 1UL);
341 :
342 : /**
343 : * relation queue enqueue statistic.
344 : */
345 : void RelationEnqueueStat();
346 :
347 : /**
348 : * relation queue dequeue statistic.
349 : */
350 : void RelationDequeueStat();
351 :
352 : /**
353 : * get relation queue enqueue statistic.
354 : */
355 : uint64_t GetRelationEnqueCnt() const;
356 :
357 : /**
358 : * get relation queue dequeue statistic.
359 : */
360 : uint64_t GetRelationDequeCnt() const;
361 :
362 : /**
363 : * asyn mem queue enqueue statistic.
364 : */
365 : void AsynMemEnqueueStat();
366 :
367 : /**
368 : * asyn mem queue dequeue statistic.
369 : */
370 : void AsynMemDequeueStat();
371 :
372 : /**
373 : * get asyn mem queue enqueue statistic.
374 : */
375 : uint64_t GetAsynMemEnqueCnt() const;
376 :
377 : /**
378 : * get asyn mem queue dequeue statistic.
379 : */
380 : uint64_t GetAsynMemDequeCnt() const;
381 :
382 : /**
383 : * full to not full queue enqueue statistic.
384 : */
385 : void F2nfEnqueueStat();
386 :
387 : /**
388 : * full to not full queue dequeue statistic.
389 : */
390 : void F2nfDequeueStat();
391 :
392 : /**
393 : * hccl mpi recv request event times statistic.
394 : */
395 : uint64_t HcclMpiRecvRequestEventStat();
396 :
397 : /**
398 : * hccl mpi recv request event false awaken times statistic.
399 : */
400 : void HcclMpiRecvReqFalseAwakenStat();
401 :
402 : /**
403 : * hccl mpi recv request event empty sched times statistic.
404 : */
405 : void HcclMpiRecvReqEmptySchedStat();
406 :
407 : /**
408 : * hccl mpi recv request event callback times statistic.
409 : */
410 : void HcclMpiRecvReqCallbackStat();
411 :
412 : /**
413 : * hccl mpi send completion event times statistic.
414 : */
415 : uint64_t HcclMpiSendCompEventStat();
416 :
417 : /**
418 : * hccl mpi send completion event false awaken times statistic.
419 : */
420 : void HcclMpiSendCompFalseAwakenStat();
421 :
422 : /**
423 : * hccl mpi send completion event empty sched times statistic.
424 : */
425 : void HcclMpiSendCompEmptySchedStat();
426 :
427 : /**
428 : * hccl mpi send completion event callback times statistic.
429 : */
430 : void HcclMpiSendCompCallbackStat();
431 :
432 : /**
433 : * hccl mpi recv completion event times statistic.
434 : */
435 : uint64_t HcclMpiRecvCompEventStat();
436 :
437 : /**
438 : * hccl mpi recv completion event false awaken times statistic.
439 : */
440 : void HcclMpiRecvCompFalseAwakenStat();
441 :
442 : /**
443 : * hccl mpi recv completion event empty sched times statistic.
444 : */
445 : void HcclMpiRecvCompEmptySchedStat();
446 :
447 : /**
448 : * hccl mpi recv completion event callback times statistic.
449 : */
450 : void HcclMpiRecvCompCallbackStat();
451 :
452 : /**
453 : * hccl mpi call hcclImrecv success times statistic.
454 : */
455 : void HcclMpiRecvSuccStat();
456 :
457 : /**
458 : * hccl mpi call hcclImrecv failed times statistic.
459 : */
460 : void HcclMpiRecvFailStat();
461 :
462 : /**
463 : * hccl mpi call hcclIsend success times statistic.
464 : */
465 : void HcclMpiSendSuccStat();
466 :
467 : /**
468 : * hccl mpi call hcclIsend failed times statistic.
469 : */
470 : void HcclMpiSendFailStat();
471 :
472 : /**
473 : * hccl mpi call hcclIsend full times statistic.
474 : */
475 : void HcclMpiSendFullStat();
476 :
477 : /**
478 : * hccl mpi congestion relief event times statistic
479 : */
480 : void HcclMpiF2nfEventStat();
481 :
482 : /**
483 : * mbuf alloc statistic
484 : */
485 : void MbufAllocStat(const uint64_t size);
486 :
487 : /**
488 : * mbuf free statistic
489 : */
490 : void MbufFreeStat(const uint64_t size);
491 :
492 : /**
493 : * recv request event supply statistic
494 : */
495 : void RecvReqEventSupplyStat();
496 :
497 : /**
498 : * f2nf event times statistic.
499 : */
500 : void F2nfEventStat();
501 :
502 : /**
503 : * f2nf event false awaken times statistic.
504 : */
505 : void F2nfEventFalseAwakenStat();
506 :
507 : /**
508 : * total dequeue times statistic.
509 : */
510 : void DataDequeueStat();
511 :
512 : void DataQueueEnqueueSuccStat();
513 :
514 : void DataQueueEnqueueFailStat();
515 :
516 : void DataQueueEnqueueFullStat();
517 :
518 : /**
519 : * bind relation request statistic
520 : */
521 : void BindStat();
522 :
523 : /**
524 : * unbind relation request statistic
525 : */
526 : void UnbindStat();
527 :
528 : /**
529 : * get bind relation request statistic
530 : */
531 : void GetBindStat();
532 :
533 : /**
534 : * get all bind relation request statistic
535 : */
536 : void GetAllBindStat();
537 :
538 : /**
539 : * relation response statistic
540 : */
541 : void ResponseStat();
542 :
543 : /**
544 : * subscribe queue statistic
545 : */
546 : void SubscribeNum(const uint32_t subscribeNum);
547 :
548 : /**
549 : * pause subscribe queue statistic, pause then +1
550 : */
551 : void PauseSubscribe();
552 :
553 : /**
554 : * pause subscribe queue statistic, resume then -1
555 : */
556 : void ResumeSubscribe();
557 :
558 : /**
559 : * bind relation number statistic
560 : */
561 : void BindNum(const uint32_t bindNum);
562 :
563 : /**
564 : * abnormal bind relation number statistic
565 : */
566 : void AbnormalBindNum(const uint32_t bindNum);
567 :
568 : /**
569 : * start dump static thread.
570 : */
571 : void StartStatisticManager(const uint32_t abnormalInterval, const uint32_t hostPid, const bool numaFlag = false,
572 : const uint32_t deviceIdExtra = 0U, const uint32_t enqueGroupIdExtra = 0U);
573 :
574 : /**
575 : * stop dump static thread.
576 : */
577 : void StopStatisticManager();
578 :
579 : /**
580 : * dump static thread function.
581 : */
582 : void ThreadFunc();
583 :
584 : /**
585 : * set exist entity flag
586 : */
587 : void SetExistEntityFlag(const bool flag);
588 :
589 : /**
590 : * Dump statistic info
591 : */
592 : void DumpStatistic();
593 :
594 : /**
595 : * Reset statistic info
596 : */
597 : void ResetStatistic();
598 :
599 : /**
600 : * Add unlink tag count
601 : * @return unlink tag count
602 : */
603 : const uint32_t AddUnlinkCount();
604 :
605 : /**
606 : * Reduce unlink tag count
607 : * @return unlink tag count
608 : */
609 : const uint32_t ReduceUnlinkCount();
610 :
611 : void RefreshEnqueHeartBeat();
612 :
613 : void AddTagCount();
614 :
615 : void ReduceTagCount();
616 :
617 : void UpdateScheuleStatistic(const float64_t delay, const float64_t cost);
618 :
619 : void DumpOutProcMemStatInfo();
620 :
621 : void RecordProcMemInfo();
622 :
623 : private:
624 3 : StatisticManager() = default;
625 :
626 : /**
627 : * dump channel statistic info
628 : */
629 : void DumpChannelStatistic();
630 :
631 : private:
632 : // lock for timerThread_
633 : std::mutex timerMutex_;
634 : // thread for record static
635 : std::thread timerThread_;
636 :
637 : // thread run flag
638 : volatile bool runFlag_ = false;
639 :
640 : // total statistic
641 : StatisticInfo totalStat_;
642 : // period statistic
643 : StatisticInfo periodStat_;
644 : // bind relation number
645 : std::atomic<uint32_t> bindNum_ = {0U};
646 : // need subscribe number
647 : std::atomic<uint32_t> subscribeNum_ = {0U};
648 : // need pause subscribe number
649 : std::atomic<uint32_t> pauseSubscribeNum_ = {0U};
650 :
651 : // exist entity flag
652 : std::atomic<bool> existEntityFlag_ = {false};
653 : // unlink tag number
654 : std::atomic<uint32_t> unLinkTagNum_ = {0U};
655 : // abnormal bind relation number
656 : std::atomic<uint32_t> abnormalBindNum_ = {0U};
657 : std::atomic<uint32_t> enqueThreadHearBeat_ = {0U};
658 : uint32_t abnormalInterval_;
659 : std::atomic<uint32_t> totalTagNum_ = {0U};
660 : ScheduleStatistic scheduleStatistic_{};
661 :
662 : bool numaFlag_{false};
663 : uint32_t deviceIdExtra_{0U};
664 : uint32_t enqueGroupIdExtra_{0U};
665 :
666 : QsProcMemStatistic procMemStat_;
667 : uint32_t hostPid_{0U};
668 : };
669 : } // namespace bqs
670 : #endif // QUEUE_SCHEDULE_STATISTIC_MANAGER_H
|