Line data Source code
1 : /**
2 : * Copyright (c) 2026 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 ENDPOINT_MONITOR_H
12 : #define ENDPOINT_MONITOR_H
13 : #include <memory>
14 : #include <thread>
15 : #include <unordered_set>
16 : #include <mutex>
17 : #include <atomic>
18 : #include "log.h"
19 : #include "hccl/hccl_types.h"
20 : #include "hcomm_res_defs.h"
21 : #include "hccp_ctx.h"
22 :
23 : namespace hcomm {
24 :
25 : /**
26 : * @note 每张卡一格 Endpoint 监控。Device UB 才 Register 进 set 并起线程。
27 : *
28 : * 仍是单例(每格一份)。构造禁止拷贝,GetHolder(id) 里 static 数组只构造一次,
29 : * 之后每次调用返回同一格的 shared_ptr 拷贝。变的是生命周期,不是实例个数。
30 : * 旧写法是 Meyers 数组(static array + GetInstance 返回 T&),寿命绑在静态析构上;
31 : * 静态对象先构造的晚析构。GetHolder 往往比其它静态对象更晚才第一次调用,
32 : * 退出时自己的 static 会先拆。已 Register 的 Endpoint 多持有一份,就能活过那些先构造的静态对象的析构。
33 : *
34 : * 用法:
35 : * 1. 入口只留 GetHolder()。Register:Endpoint AttachMonitor 拷贝后,用持有的指针 Register。ResMgr warmup 调
36 : * GetHolder()。
37 : * 2. Destroy / 析构:走持有的指针 Remove,再 reset。未 Register 的空指针直接返回。
38 : * 3. 析构路径不要再调 GetHolder()。函数内那份 static 数组拆掉后,入口已悬空。
39 : */
40 : class EndpointMonitor {
41 : public:
42 132 : EndpointMonitor() = default;
43 : EndpointMonitor(const EndpointMonitor&) = delete;
44 : EndpointMonitor& operator=(const EndpointMonitor&) = delete;
45 : EndpointMonitor(EndpointMonitor&&) = delete;
46 : EndpointMonitor& operator=(EndpointMonitor&&) = delete;
47 : ~EndpointMonitor();
48 :
49 : static std::shared_ptr<EndpointMonitor> GetHolder(s32 deviceId);
50 : HcclResult RegisterToEndpointMonitor(s32 deviceLogicId, EndpointHandle epHandle);
51 : HcclResult UnRegisterToEndpointMonitor();
52 : void RemoveEpHandleFromEndpointMonitor(EndpointHandle epHandle);
53 :
54 : private:
55 : HcclResult RunMonitorThread();
56 : void MonitorThread();
57 : HcclResult DeInit(s32 deviceLogicId);
58 :
59 : void ProcessUbAsyncEvents();
60 : void PrintUbAsyncEventsContext(void* epHandle, u32 seq, const struct AsyncEvent& event);
61 :
62 : static constexpr u32 MONITOR_INTERVAL = 1000;
63 : std::unique_ptr<std::thread> endpointMonitorThread_;
64 :
65 : std::atomic<bool> initialized_{false};
66 : std::atomic<bool> endpointMonitorThreadFlag_{false};
67 : std::mutex threadLock_;
68 : u32 devPhyId_{0};
69 : s32 deviceLogicId_{0};
70 : std::unordered_set<u64> epHandleSet_;
71 :
72 : struct AsyncEvent events_[ASYNC_EVENT_MAX_NUM];
73 : };
74 : } // namespace hcomm
75 : #endif // ENDPOINT_MONITOR_H
|