LCOV - code coverage report
Current view: top level - aicpu_schedule/statistic - aicpusd_period_statistic.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.7 % 72 66
Test Date: 2026-08-12 11:05:02 Functions: 88.9 % 9 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              : #include "aicpusd_period_statistic.h"
      11              : 
      12              : #include <errno.h>
      13              : #include <cstdio>
      14              : #include "aicpusd_util.h"
      15              : #include "aicpusd_drv_manager.h"
      16              : namespace AicpuSchedule {
      17              : namespace {
      18              : // 循环一次100ms
      19              : constexpr const uint64_t STATISTIC_LOOP_PERIOD = 100UL;
      20              : constexpr const uint64_t SECOND_TO_MS = 1000UL;
      21              : constexpr const uint64_t MS_TO_US = 1000UL;
      22              : constexpr const uint64_t PROC_MEM_PERIOD = 10U;
      23              : } // namespace
      24              : 
      25            2 : AicpuSdPeriodStatistic::AicpuSdPeriodStatistic() : initFlag_(false), runningFlag_(false), deviceId_(0U), hostPid_(0U) {}
      26              : 
      27           63 : AicpuSdPeriodStatistic& AicpuSdPeriodStatistic::GetInstance()
      28              : {
      29           63 :     static AicpuSdPeriodStatistic instance;
      30           63 :     return instance;
      31              : }
      32              : 
      33            2 : AicpuSdPeriodStatistic::~AicpuSdPeriodStatistic() { StopStatistic(); }
      34              : 
      35           26 : void AicpuSdPeriodStatistic::StopStatistic()
      36              : {
      37           26 :     aicpusd_info("StopStatistic start");
      38           26 :     const std::lock_guard<std::mutex> lk(initMutex_);
      39           26 :     if (!initFlag_) {
      40           24 :         aicpusd_info("already uninit no need uninit");
      41           24 :         return;
      42              :     }
      43            2 :     runningFlag_ = false;
      44            2 :     initFlag_ = false;
      45            2 :     if (statThread_.joinable()) {
      46            1 :         statThread_.join();
      47              :     }
      48            2 :     aicpusd_info("StopStatistic finish");
      49           26 : }
      50              : 
      51            2 : void AicpuSdPeriodStatistic::DoStatistic() noexcept
      52              : {
      53            2 :     if (SetThreadAffinity() != AICPU_SCHEDULE_OK) {
      54            1 :         aicpusd_run_warn("stat thread bind core nok.");
      55            1 :         return;
      56              :     }
      57            1 :     constexpr uint64_t procMemPeriod = PROC_MEM_PERIOD * SECOND_TO_MS / STATISTIC_LOOP_PERIOD;
      58            1 :     uint64_t loopCnt = 0UL;
      59           11 :     while (runningFlag_) {
      60           10 :         if (loopCnt % procMemPeriod == 0) {
      61            1 :             procMemInfo_.StatisticProcMemInfo();
      62              :         }
      63           10 :         loopCnt++;
      64           10 :         (void)usleep(STATISTIC_LOOP_PERIOD * MS_TO_US);
      65              :     }
      66            1 :     aicpusd_run_info("DoStatistic running over");
      67              : }
      68              : 
      69           24 : void AicpuSdPeriodStatistic::PrintOutStatisticInfo(const aicpu::AicpuRunMode runMode)
      70              : {
      71           24 :     if (runMode == aicpu::AicpuRunMode::PROCESS_SOCKET_MODE || (AicpuUtil::IsFpga())) {
      72           22 :         aicpusd_info("socket mode no need this statistic");
      73           22 :         return;
      74              :     }
      75            2 :     procMemInfo_.PrintOutProcMemInfo(hostPid_);
      76              : }
      77              : 
      78            8 : void AicpuSdPeriodStatistic::InitStatistic(
      79              :     const uint32_t deviceId, const uint32_t hostPid, const aicpu::AicpuRunMode runMode)
      80              : {
      81            8 :     if ((runMode == aicpu::AicpuRunMode::PROCESS_SOCKET_MODE) || (AicpuUtil::IsFpga())) {
      82            5 :         aicpusd_info("socket or fpga mode no need this statistic");
      83            7 :         return;
      84              :     }
      85            3 :     const std::lock_guard<std::mutex> lk(initMutex_);
      86            3 :     if (initFlag_) {
      87            1 :         aicpusd_info("already init before");
      88            1 :         return;
      89              :     }
      90            2 :     deviceId_ = deviceId;
      91            2 :     runningFlag_ = true;
      92            2 :     hostPid_ = hostPid;
      93            2 :     aicpusd_info("Start initializing statistics, deviceId:%u, hostPid:%u", deviceId_, hostPid_);
      94            2 :     if (!procMemInfo_.InitProcMemStatistic()) {
      95            1 :         aicpusd_err("InitProcMemStatistic failed");
      96            1 :         return;
      97              :     }
      98              : 
      99              :     try {
     100            1 :         statThread_ = std::thread(&AicpuSdPeriodStatistic::DoStatistic, this);
     101            0 :     } catch (std::exception& e) {
     102            0 :         aicpusd_err("create thread file:%s", e.what());
     103            0 :         return;
     104            0 :     }
     105            1 :     initFlag_ = true;
     106            3 : }
     107              : 
     108            2 : int32_t AicpuSdPeriodStatistic::SetThreadAffinity() const
     109              : {
     110            2 :     std::vector<uint32_t> ccpuIds = AicpuDrvManager::GetInstance().GetCcpuList();
     111            2 :     if (ccpuIds.empty()) {
     112            0 :         aicpusd_run_info("ccpu list is empty no need bind core");
     113            0 :         return AICPU_SCHEDULE_OK;
     114              :     }
     115            2 :     const pthread_t threadId = pthread_self();
     116              :     cpu_set_t cpuset;
     117           20 :     for (const auto cpuId : ccpuIds) {
     118           18 :         CPU_SET(cpuId, &cpuset);
     119           18 :         aicpusd_info("prepare bind threadId=%lu to cpuId=%u", threadId, static_cast<uint32_t>(cpuId));
     120              :     }
     121            2 :     const int32_t ret = pthread_setaffinity_np(threadId, sizeof(cpu_set_t), &cpuset);
     122            2 :     if (ret != 0) {
     123            1 :         aicpusd_run_warn("aicpu bind tid by self, res[%d], reason[%s].", ret, strerror(errno));
     124            1 :         return AICPU_SCHEDULE_ERROR_INNER_ERROR;
     125              :     } else {
     126            1 :         aicpusd_run_info("aicpu bind by self success");
     127            1 :         return AICPU_SCHEDULE_OK;
     128              :     }
     129            2 : }
     130              : } // namespace AicpuSchedule
        

Generated by: LCOV version 2.0-1