LCOV - code coverage report
Current view: top level - base_comm/resources/ccu/ccu_instance - ccu_var_event_res_mgr.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 2 2
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 2 2

            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 HCOMM_CCU_VAR_EVENT_RES_MGR_H
      12              : #define HCOMM_CCU_VAR_EVENT_RES_MGR_H
      13              : 
      14              : #include <shared_mutex>
      15              : #include <vector>
      16              : #include <unordered_map>
      17              : 
      18              : #include "ccu_types.h"
      19              : 
      20              : #include "ccu_res_repo.h"
      21              : 
      22              : namespace hcomm {
      23              : 
      24              : enum class CcuVarEventType {
      25              :     VARIABLE = 0,
      26              :     EVENT = 1,
      27              : };
      28              : 
      29              : struct CcuVarEventRes {
      30              :     CcuInsHandle insHandle{0};
      31              :     int32_t devLogicId{-1};
      32              :     uint8_t dieId{0};
      33              :     CcuVarEventType type{CcuVarEventType::VARIABLE};
      34              :     std::vector<ResInfo> resInfos{};
      35              :     // 借用指针,指向发起预约的 CcuInstance 名下 CcuResPack 持有的资源仓,本类不持有所有权。
      36              :     // 有效性依赖既定时序:~CcuInstance 中 ReleaseByInstance 先于 resPack_ 置空执行,
      37              :     // CcuInstance::Reset 调 ExcludeAllocatedFromRepo 时资源仓亦仍存活。
      38              :     // 新增读写该指针的路径时,须确认调用点仍在 CcuResPack 析构之前。
      39              :     CcuResRepository* resRepo{nullptr};
      40              :     // 申请时对每个资源注册好的进程可访问 VA,下标与资源 index 一一对应
      41              :     std::vector<uint64_t> vaList{};
      42              : };
      43              : 
      44              : // 职责:管理通信域内 Variable(XN) / Event(CKE) 预约资源的完整生命周期,涵盖四个阶段——
      45              : // 从实例资源仓切出连续块、申请期为每个资源注册进程可访问 VA、按 handle 记账、随实例回收。
      46              : // 四者是同一份资源的先后阶段而非彼此独立的职责,故收敛在同一个类内:Acquire 完成
      47              : // 「切块 + 映射 + 记账」,ReleaseByHandle / ReleaseByInstance 完成对称的「解映射 + 归还」。
      48              : //
      49              : // 为何 Variable 与 Event 合用一个管理器:两类资源共享完全相同的使用模式——一次性预约连续块、
      50              : // 申请期暴露地址、句柄随通信域销毁统一回收;差异仅在资源池(blockXn / blockCke)与 runtime
      51              : // 资源类型(RT_RES_TYPE_CCU_XN / RT_RES_TYPE_CCU_CKE)两处,均由 CcuVarEventType 参数化。
      52              : // 拆成两个类会使上述四阶段流程与回滚逻辑重复一遍,故不拆。
      53              : //
      54              : // 与 CcuResIdAllocator 的边界:后者位于设备层,管理自持的 [0, capacity) 完整 id 空间,
      55              : // 其 resInfos_ 记录的是「已分配块」;本类位于实例层,从上游下发给本通信域的若干段「空闲块」
      56              : // 中做二次切分,无 capacity 概念。两者数据结构语义相反,不存在替代关系。
      57              : //
      58              : // 线程安全契约:
      59              : // 1) resMap_ 与 handleSeed_ 为 per-device、跨 CcuInstance 共享,全部读写均由 mapMutex_ 保护;
      60              : // 2) CcuVarEventRes::resRepo 指向的资源池由发起预约的 CcuInstance(经其 CcuResPack)持有,
      61              : //    不在 mapMutex_ 的保护范围内。CcuInstance 自身不含锁,约定同一 instance 只由单线程串行
      62              : //    访问,池的并发安全由该约定保证;不同 instance 的池互不相交,跨 instance 并发是安全的。
      63              : // 因此 ExcludeAllocatedFromRepo 取 shared_lock 是为遍历 resMap_,而非保护池。
      64              : class CcuVarEventResMgr {
      65              : public:
      66              :     static CcuVarEventResMgr& GetInstance(const int32_t deviceLogicId);
      67              : 
      68              :     // 预约一段连续资源并在申请期完成地址映射;任一阶段失败均整笔回滚,仅全程成功才写 handle
      69              :     CcuResult Acquire(
      70              :         CcuInsHandle insHandle, CcuResRepository& resRepo, CcuVarEventType type, uint8_t dieId, uint32_t num,
      71              :         uint64_t& handle);
      72              :     CcuResult GetVariableXnId(uint64_t handle, uint32_t index, uint8_t& dieId, uint32_t& xnId) const;
      73              :     CcuResult GetEventCkeId(uint64_t handle, uint32_t index, uint8_t& dieId, uint32_t& ckeId) const;
      74              :     // 保存 Alloc 阶段为该 handle 注册好的全部资源 VA(下标与资源 index 一一对应)
      75              :     CcuResult SaveAddrs(CcuVarEventType type, uint64_t handle, const std::vector<uint64_t>& vaList);
      76              :     // 返回 Alloc 阶段已注册的第 index 个资源 VA
      77              :     CcuResult GetSavedAddr(CcuVarEventType type, uint64_t handle, uint32_t index, uint64_t& va) const;
      78              :     CcuResult ReleaseByHandle(uint64_t handle);
      79              :     CcuResult ReleaseByInstance(CcuInsHandle insHandle);
      80              :     CcuResult ExcludeAllocatedFromRepo(CcuInsHandle insHandle) const;
      81              : 
      82              : private:
      83          132 :     explicit CcuVarEventResMgr() = default;
      84          132 :     ~CcuVarEventResMgr() = default;
      85              : 
      86              :     CcuVarEventResMgr(const CcuVarEventResMgr& that) = delete;
      87              :     CcuVarEventResMgr& operator=(const CcuVarEventResMgr& that) = delete;
      88              : 
      89              :     // 校验参数、选池、切出连续块并登记到 resMap_,成功时经 newHandle 返回新句柄
      90              :     CcuResult AllocAndRecord(
      91              :         CcuInsHandle insHandle, CcuResRepository& resRepo, CcuVarEventType type, uint8_t dieId, uint32_t num,
      92              :         uint64_t& newHandle);
      93              :     // 为 handle 名下 num 个资源逐个注册进程可访问 VA 并缓存;失败时解除本次已完成的映射,
      94              :     // 资源池的归还由 Acquire 与切池动作配对完成
      95              :     CcuResult RegisterAddrs(CcuVarEventType type, uint64_t handle, uint32_t num);
      96              : 
      97              :     static CcuResult AllocFromPool(std::vector<ResInfo>& pool, uint32_t num, std::vector<ResInfo>& out);
      98              :     static void ReturnToPool(std::vector<ResInfo>& pool, const std::vector<ResInfo>& res);
      99              :     // 释放资源前,将 Alloc 阶段映射的进程可访问 VA 逐个 unmap(仅处理已保存 VA 的资源);
     100              :     // 返回首个 unmap 失败的错误码,失败不中断,其余资源继续 unmap
     101              :     static CcuResult UnmapSavedAddrs(const CcuVarEventRes& res);
     102              : 
     103              :     int32_t devLogicId_{-1};
     104              :     uint64_t handleSeed_{0};
     105              :     mutable std::shared_timed_mutex mapMutex_;
     106              :     std::unordered_map<uint64_t, CcuVarEventRes> resMap_{};
     107              : };
     108              : 
     109              : } // namespace hcomm
     110              : 
     111              : #endif // HCOMM_CCU_VAR_EVENT_RES_MGR_H
        

Generated by: LCOV version 2.0-1