LCOV - code coverage report
Current view: top level - legacy/ascend950/framework/communicator/aicpu - hdc_lite.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.1 % 84 74
Test Date: 2026-07-28 12:11:00 Functions: 85.7 % 7 6

            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 "hdc_lite.h"
      12              : #include <chrono>
      13              : #include "log.h"
      14              : 
      15              : namespace Hccl {
      16              : constexpr u32 HCCL_HDC_CONTROL_WORDS = 2;
      17              : constexpr u32 HCCL_HDC_HEAD_POS = 2;
      18              : constexpr u32 HCCL_HDC_TAIL_POS = 1;
      19              : 
      20            0 : inline u32* HcclHdcGetControlWordAddr(void *base, u64 size, u32 pos)
      21              : {
      22            0 :     return reinterpret_cast<u32 *>(reinterpret_cast<u8 *>((base)) + size - pos * sizeof(pos));
      23              : }
      24              : 
      25           19 : HcclResult HDCommunicateLite::Init(const struct HDCommunicateParams &params)
      26              : {
      27           19 :     CHK_PRT_RET((params.devMemSize == 0),
      28              :         HCCL_ERROR("[HDCommunicateLite][InitDevice]Invalid devMemSize=%u", params.devMemSize), HCCL_E_PARA);
      29           19 :     void *deviceAddr = reinterpret_cast<void *>(params.deviceAddr);
      30           19 :     CHK_PTR_NULL(deviceAddr);
      31           19 :     readCacheAddr = reinterpret_cast<void *>(params.readCacheAddr);
      32           19 :     CHK_PTR_NULL(readCacheAddr);
      33           19 :     devMem = std::make_unique<Buffer>(reinterpret_cast<uintptr_t>(deviceAddr), params.devMemSize);
      34           19 :     buffLen = params.buffLen;
      35           19 :     flag = params.flag;
      36              : 
      37           19 :     headCntAddr = HcclHdcGetControlWordAddr(reinterpret_cast<void *>(devMem->GetAddr()), devMem->GetSize(), HCCL_HDC_HEAD_POS);
      38           19 :     tailCntAddr = HcclHdcGetControlWordAddr(reinterpret_cast<void *>(devMem->GetAddr()), devMem->GetSize(), HCCL_HDC_TAIL_POS);
      39              : 
      40           57 :     HCCL_INFO(
      41              :         "[HDCommunicateLite][Init] buffLen=%u, flag=%u, readCacheAddr=%p, headCntAddr=%p, tailCntAddr=%p",
      42              :         buffLen, flag, readCacheAddr, headCntAddr, tailCntAddr);
      43           19 :     return HCCL_SUCCESS;
      44              : }
      45              : 
      46           13 : HcclResult HDCommunicateLite::Put(u32 offset, u32 length, u8 *value)
      47              : {
      48           13 :     if (length == 0) {
      49            0 :         return HCCL_SUCCESS;
      50              :     }
      51           13 :     CHK_PTR_NULL(value);
      52           13 :     if ((flag == HCCLV2_HDC_TYPE_H2D)) {
      53            0 :         HCCL_ERROR("[HDCommunicateLite][Put]Invalid usage, flag=%u", flag);
      54            0 :         return HCCL_E_PARA;
      55              :     }
      56           13 :     CHK_PRT_RET((static_cast<u64>(offset) + length > buffLen),
      57              :         HCCL_ERROR("[HDCommunicateLite][Put]Invalid length, offset=%u, length=%u", offset, length), HCCL_E_PARA);
      58           13 :     std::unique_lock<std::mutex> lock(shmLock);
      59           13 :     return Write(offset, length, value);
      60           13 : }
      61              : 
      62        19843 : HcclResult HDCommunicateLite::Get(u32 offset, u32 length, u8 *value)
      63              : {
      64        19843 :     if (length == 0) {
      65            0 :         return HCCL_SUCCESS;
      66              :     }
      67        19843 :     CHK_PTR_NULL(value);
      68        19843 :     CHK_PRT_RET((static_cast<u64>(offset) + length > buffLen),
      69              :         HCCL_ERROR("[HDCommunicateLite][Get]Invalid length, offset=%u, length=%u, befferLen=%u", offset, length, buffLen),
      70              :         HCCL_E_PARA);
      71        19843 :     std::unique_lock<std::mutex> lock(shmLock);
      72        19843 :     return Read(offset, length, value);
      73        19843 : }
      74              : 
      75              : #pragma GCC push_options
      76              : #pragma GCC optimize("O0")
      77           13 : HcclResult HDCommunicateLite::Write(u32 offset, u32 length, u8 *value)
      78              : {
      79           13 :     if (length == 0) {
      80            0 :         return HCCL_SUCCESS;
      81              :     }
      82           13 :     CHK_PTR_NULL(value);
      83           13 :     u32 head = *headCntAddr;
      84           13 :     head++;
      85           13 :     *headCntAddr = head;
      86              : 
      87           13 :     auto ret = memcpy_s(reinterpret_cast<u8 *>(devMem->GetAddr()) + offset,
      88           13 :         devMem->GetSize() - HCCL_HDC_CONTROL_WORDS * sizeof(u32) - offset, value, length);
      89           13 :     CHK_PRT_RET(ret != EOK, HCCL_ERROR("[HDCommunicateLite][Write]memcpy_s failed, return[%d].", ret), HCCL_E_INTERNAL);
      90              : 
      91           13 :     u32 tail = *tailCntAddr;
      92           13 :     tail++;
      93           13 :     *tailCntAddr = tail;
      94              : 
      95           13 :     return HCCL_SUCCESS;
      96              : }
      97              : 
      98        19843 : HcclResult HDCommunicateLite::Read(u32 offset, u32 length, u8 *value)
      99              : {
     100        19843 :     if (length == 0) {
     101            0 :         return HCCL_SUCCESS;
     102              :     }
     103        19843 :     CHK_PTR_NULL(value);
     104        19843 :     u32 *cachedTailCntAddr = HcclHdcGetControlWordAddr(readCacheAddr, devMem->GetSize(), HCCL_HDC_TAIL_POS);
     105        19843 :     volatile u32 cachedTailCnt = *cachedTailCntAddr;
     106        19843 :     volatile u32 tailCnt = 0;
     107        19843 :     tailCnt = *tailCntAddr;
     108              : 
     109        19843 :     if (cachedTailCnt != tailCnt) {
     110              :         // 默认HDC超时时间为10s
     111           11 :         CHK_RET(UpdateCache(10));
     112              :     }
     113        19843 :     auto ret = memcpy_s(value, length, static_cast<u8 *>(readCacheAddr) + offset, length);
     114        19843 :     CHK_PRT_RET(ret != EOK, HCCL_ERROR("[HDCommunicateLite][Read]memcpy_s failed, return[%d].", ret), HCCL_E_INTERNAL);
     115        19843 :     return HCCL_SUCCESS;
     116              : }
     117              : 
     118           11 : HcclResult HDCommunicateLite::UpdateCache(u32 timeoutSec)
     119              : {
     120           11 :     void *srcBaseAddr = reinterpret_cast<void *>(devMem->GetAddr());
     121           11 :     u32 *srcHeadCntAddr = HcclHdcGetControlWordAddr(srcBaseAddr, devMem->GetSize(), HCCL_HDC_HEAD_POS);
     122           11 :     u32 *srcTailCntAddr = HcclHdcGetControlWordAddr(srcBaseAddr, devMem->GetSize(), HCCL_HDC_TAIL_POS);
     123           11 :     u32 *cachedHeadCntAddr = HcclHdcGetControlWordAddr(readCacheAddr, devMem->GetSize(), HCCL_HDC_HEAD_POS);
     124           11 :     u32 *cachedTailCntAddr = HcclHdcGetControlWordAddr(readCacheAddr, devMem->GetSize(), HCCL_HDC_TAIL_POS);
     125              : 
     126           11 :     s32 ret = 0;
     127           11 :     auto startTime = std::chrono::steady_clock::now();
     128           11 :     auto timeout = std::chrono::seconds(timeoutSec);
     129              :     while (1) {
     130              :         // step1: cache尾计数
     131           11 :         ret = memcpy_s(cachedTailCntAddr, sizeof(u32), srcTailCntAddr, sizeof(u32));
     132           11 :         CHK_PRT_RET(ret != EOK, HCCL_ERROR("[HDCommunicateLite][UpdateCache]memcpy_s failed, return[%d].", ret),
     133              :             HCCL_E_INTERNAL);
     134              : 
     135              :         // step2: cache数据
     136           11 :         ret = memcpy_s(readCacheAddr, devMem->GetSize() - HCCL_HDC_CONTROL_WORDS * sizeof(u32), srcBaseAddr,
     137           11 :             devMem->GetSize() - HCCL_HDC_CONTROL_WORDS * sizeof(u32));
     138           11 :         CHK_PRT_RET(ret != EOK, HCCL_ERROR("[HDCommunicateLite][UpdateCache]memcpy_s failed, return[%d].", ret),
     139              :             HCCL_E_INTERNAL);
     140              : 
     141              :         // step3:cache头计数
     142           11 :         ret = memcpy_s(cachedHeadCntAddr, sizeof(u32), srcHeadCntAddr, sizeof(u32));
     143           11 :         CHK_PRT_RET(ret != EOK, HCCL_ERROR("[HDCommunicateLite][UpdateCache]memcpy_s failed, return[%d].", ret),
     144              :             HCCL_E_INTERNAL);
     145              : 
     146           11 :         volatile u32 cachedHeadCnt = *cachedHeadCntAddr;
     147           11 :         volatile u32 cachedTailCnt = *cachedTailCntAddr;
     148              : 
     149           11 :         if (cachedHeadCnt == cachedTailCnt) {
     150           11 :             break;
     151              :         }
     152            0 :         CHK_PRT_RET(((std::chrono::steady_clock::now() - startTime) >= timeout),
     153              :             HCCL_WARNING("[HDCommunicateLite][UpdateCache]get remote data timeout[%u s].", timeoutSec), HCCL_E_AGAIN);
     154            0 :     }
     155           11 :     return HCCL_SUCCESS;
     156              : }
     157              : #pragma GCC pop_options
     158              : 
     159              : }
        

Generated by: LCOV version 2.0-1