LCOV - code coverage report
Current view: top level - base_comm/resources/endpoint_pairs/channels/host/dpu_notify - dpu_notify_manager.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 86.2 % 65 56
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 8 8

            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              : #include "dpu_notify_manager.h"
      12              : #include "log.h"
      13              : namespace hcomm {
      14              : 
      15              : constexpr uint32_t BYTE_SIZE = 8; // 一个字节占8位,用于比较赋值等,避免使用魔法数字
      16              : 
      17          186 : DpuNotifyManager& DpuNotifyManager::GetInstance()
      18              : {
      19          186 :     int numNotify = 8192;
      20          186 :     static DpuNotifyManager instance{numNotify};
      21          186 :     return instance;
      22              : }
      23              : 
      24            2 : DpuNotifyManager::DpuNotifyManager(int numEntries)
      25              : {
      26            2 :     if (numEntries <= 0) {
      27            0 :         numEntries = 1;
      28              :     }
      29            2 :     byteSize = (numEntries + BYTE_SIZE - 1) / BYTE_SIZE;
      30            2 :     notifyIdBitMap = std::vector<unsigned char>(byteSize, 0x00);
      31            2 :     freeBit = std::vector<uint32_t>(byteSize, 0);
      32            2 : }
      33              : 
      34            2 : DpuNotifyManager::~DpuNotifyManager() = default;
      35              : 
      36          456 : void DpuNotifyManager::UpdateFreeBit(uint32_t index)
      37              : {
      38         1040 :     for (uint32_t j = 0; j < BYTE_SIZE; ++j) {
      39         1039 :         if (!(notifyIdBitMap[index] & (1 << j))) { // 检查第j位是否为0
      40          455 :             freeBit[index] = j;
      41          455 :             return;
      42              :         }
      43              :     }
      44            1 :     freeBit[index] = BYTE_SIZE; // 都检查完了,已满
      45              : }
      46              : 
      47          232 : int DpuNotifyManager::AllocSingleNotifyId()
      48              : {
      49          240 :     for (uint32_t i = 0; i < byteSize; ++i) {
      50          240 :         if (notifyIdBitMap[i] != 0xFF) {            // 当前字节未满
      51          232 :             notifyIdBitMap[i] |= (1 << freeBit[i]); // 设置为1
      52          232 :             size_t tmp = freeBit[i];                // 后续update会覆盖,所以先存起来。
      53          232 :             UpdateFreeBit(i);
      54          232 :             return i * BYTE_SIZE + tmp;
      55              :         }
      56              :     }
      57            0 :     return -1; // 无可用资源
      58              : }
      59              : 
      60           62 : HcclResult DpuNotifyManager::AllocNotifyIds(
      61              :     uint32_t notifyNum,
      62              :     std::vector<uint32_t>& notifyIds) // std::unique_ptr<uint64_t[]>& handles)
      63              : {
      64           62 :     if (notifyNum == 0) {
      65            0 :         HCCL_INFO("[DpuNotifyManager::%s] notifyNum == 0, no need to alloc.", __func__);
      66            0 :         return HCCL_SUCCESS;
      67              :     }
      68              : 
      69           62 :     if (notifyNum > byteSize * BYTE_SIZE) {
      70            1 :         HCCL_ERROR(
      71              :             "[DpuNotifyManager::%s] notifyNum[%u] is too large. Maximum: %u.", __func__, notifyNum,
      72              :             byteSize * BYTE_SIZE);
      73            1 :         return HCCL_E_PARA;
      74              :     }
      75              : 
      76           61 :     std::lock_guard<std::mutex> lock(mtxAlloc_);
      77              : 
      78           61 :     notifyIds.resize(notifyNum);
      79              : 
      80          293 :     for (uint32_t i = 0; i < notifyNum; ++i) {
      81          232 :         int notifyId = AllocSingleNotifyId();
      82          232 :         if (notifyId == -1) {
      83              :             // 空间不足,释放之前的申请,并报错
      84            0 :             FreeNotifyIds(i, notifyIds);
      85            0 :             HCCL_ERROR("[DpuNotifyManager::%s] no free notify to alloc.", __func__);
      86            0 :             return HCCL_E_MEMORY;
      87              :         }
      88          232 :         notifyIds[i] = notifyId; // 存起来
      89              :     }
      90           61 :     return HCCL_SUCCESS;
      91           61 : }
      92              : 
      93          224 : void DpuNotifyManager::FreeSingleNotifyId(uint32_t notifyId)
      94              : {
      95              :     // 校验输入是否溢出
      96          224 :     if (notifyId >= byteSize * BYTE_SIZE) {
      97            0 :         HCCL_INFO("[DpuNotifyManager::%s] no need to free.", __func__);
      98            0 :         return;
      99              :     }
     100          224 :     uint32_t byteIndex = notifyId / BYTE_SIZE;
     101          224 :     uint32_t bitIndex = notifyId % BYTE_SIZE;
     102          224 :     notifyIdBitMap[byteIndex] &= ~(1 << bitIndex);
     103          224 :     UpdateFreeBit(byteIndex);
     104          224 :     return;
     105              : }
     106              : 
     107          123 : HcclResult DpuNotifyManager::FreeNotifyIds(uint32_t notifyNum, std::vector<uint32_t>& notifyIds)
     108              : {
     109          123 :     if (notifyNum == 0) { // 没有需要回收的notify
     110           59 :         HCCL_INFO("[DpuNotifyManager::%s] notifyNum == 0, no need to free.", __func__);
     111           59 :         return HCCL_SUCCESS;
     112              :     }
     113              : 
     114           64 :     if (notifyNum > notifyIds.size()) {
     115            5 :         HCCL_ERROR(
     116              :             "[DpuNotifyManager::%s] notifyNum[%u] > notifyIds length[%zu].", __func__, notifyNum, notifyIds.size());
     117            5 :         return HCCL_E_PARA;
     118              :     }
     119              : 
     120           59 :     std::lock_guard<std::mutex> lock(mtxFree_);
     121              : 
     122          283 :     for (uint32_t i = 0; i < notifyNum; ++i) {
     123          224 :         FreeSingleNotifyId(notifyIds[i]);
     124              :     }
     125           59 :     return HCCL_SUCCESS;
     126           59 : }
     127              : 
     128              : } // namespace hcomm
        

Generated by: LCOV version 2.0-1