LCOV - code coverage report
Current view: top level - aicpu_cust_schedule/core/cust_mc2_maintenance - aicpu_cust_sd_mc2_maintenance_thread.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 90.7 % 193 175
Test Date: 2026-08-12 11:05:02 Functions: 94.1 % 17 16

            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 "aicpu_cust_sd_mc2_maintenance_thread.h"
      11              : #include <cstring>
      12              : #include <sched.h>
      13              : #include <semaphore.h>
      14              : #include "aicpusd_drv_manager.h"
      15              : #include "aicpusd_info.h"
      16              : #include "aicpusd_util.h"
      17              : #include "aicpusd_status.h"
      18              : #include "aicpu_cust_sd_proc_mgr_sys_operator_agent.h"
      19              : #include "aicpusd_interface_process.h"
      20              : #include "tsd.h"
      21              : #include "aicpu_cust_sd_mc2_maintenance_thread_api.h"
      22              : 
      23              : namespace AicpuSchedule {
      24              : const uint32_t DEFAULT_GROUP_ID_TO_TSD_CLIENT = 30U;
      25           59 : AicpuCustMc2MaintenanceThread& AicpuCustMc2MaintenanceThread::GetInstance(uint32_t type)
      26              : {
      27           59 :     if (type == 0) {
      28           58 :         static AicpuCustMc2MaintenanceThread instance(type);
      29           58 :         return instance;
      30              :     }
      31            1 :     static AicpuCustMc2MaintenanceThread instance(type);
      32            1 :     return instance;
      33              : }
      34              : 
      35            3 : AicpuCustMc2MaintenanceThread::~AicpuCustMc2MaintenanceThread()
      36              : {
      37            3 :     UnitCustMc2MaintenanceProcess();
      38            3 :     if (processThread_.joinable()) {
      39            1 :         processThread_.join();
      40              :     }
      41            3 : }
      42              : 
      43            2 : AicpuCustMc2MaintenanceThread::AicpuCustMc2MaintenanceThread(uint32_t type)
      44            2 :     : initFlag_(false),
      45            2 :       threadId_(0LU),
      46            2 :       processEventFuncPtr_(nullptr),
      47            2 :       processEventFuncParam_(nullptr),
      48            2 :       stopProcessEventFuncPtr_(nullptr),
      49            2 :       stopProcessEventFuncParam_(nullptr),
      50            2 :       type_(type)
      51            2 : {}
      52            2 : void AicpuCustMc2MaintenanceThread::SendCustMc2CreateThreadMsgToMain() const
      53              : {
      54            2 :     TsdSubEventInfo msg = {};
      55            2 :     event_summary eventInfo = {};
      56            2 :     eventInfo.pid = static_cast<pid_t>(getpid());
      57            2 :     eventInfo.grp_id = DEFAULT_GROUP_ID_TO_TSD_CLIENT;
      58            2 :     eventInfo.dst_engine = CCPU_DEVICE;
      59            2 :     eventInfo.event_id = EVENT_CCPU_CTRL_MSG;
      60            2 :     eventInfo.subevent_id = TSD_EVENT_START_MC2_THREAD;
      61            2 :     eventInfo.msg_len = sizeof(TsdSubEventInfo);
      62            2 :     eventInfo.msg = PtrToPtr<TsdSubEventInfo, char_t>(&msg);
      63            2 :     struct CreateCtrlThreadArgs* createCtrlThreadArgsPtr = PtrToPtr<char_t, struct CreateCtrlThreadArgs>(msg.priMsg);
      64            2 :     createCtrlThreadArgsPtr->type = type_;
      65              : 
      66            2 :     uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
      67            2 :     const drvError_t ret = halEschedSubmitEvent(deviceId, &eventInfo);
      68            2 :     if (ret != DRV_ERROR_NONE) {
      69            1 :         aicpusd_err("Failed to submit, eventId: [%d], ret: [%d].", TSD_EVENT_START_MC2_THREAD, ret);
      70              :     }
      71              : 
      72            4 :     return;
      73              : }
      74              : 
      75            3 : int32_t AicpuCustMc2MaintenanceThread::CreateCustMc2MaintenanceThread()
      76              : {
      77            3 :     if (initFlag_) {
      78            1 :         aicpusd_info("the thread no need to multiple init, threadId[%llu]", threadId_);
      79            1 :         return AICPU_SCHEDULE_OK;
      80              :     }
      81              :     try {
      82            2 :         if (processThread_.joinable()) {
      83            1 :             aicpusd_run_info("processThread join begin, threadId[%llu]", threadId_);
      84            1 :             processThread_.join();
      85            1 :             aicpusd_run_info("processThread join end, threadId[%llu]", threadId_);
      86              :         }
      87            2 :         processThread_ = std::thread(&AicpuCustMc2MaintenanceThread::StartProcessEvent, this);
      88            0 :     } catch (std::exception& e) {
      89            0 :         aicpusd_err("create thread file:%s", e.what());
      90            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      91            0 :     }
      92            2 :     return AICPU_SCHEDULE_OK;
      93              : }
      94              : 
      95           13 : int32_t AicpuCustMc2MaintenanceThread::InitCustMc2MaintenanceProcess(
      96              :     AicpuMC2MaintenanceFuncPtr loopFun, void* paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun,
      97              :     void* paramStopFun)
      98              : {
      99           13 :     aicpusd_info("init cust mc2 maintenance process start, type[%u]", type_);
     100              :     uint32_t runMode;
     101           13 :     const aicpu::status_t status = aicpu::GetAicpuRunMode(runMode);
     102           13 :     if (status != aicpu::AICPU_ERROR_NONE) {
     103            1 :         aicpusd_err("Get current aicpu ctx failed. type[%u]", type_);
     104            1 :         return AICPU_SCHEDULE_ERROR_INNER_ERROR;
     105              :     }
     106           12 :     if (runMode != aicpu::AicpuRunMode::PROCESS_PCIE_MODE) {
     107            2 :         aicpusd_info("not pcie mode no need this thread type[%u]", type_);
     108            2 :         return AICPU_SCHEDULE_NOT_SUPPORT;
     109              :     }
     110           10 :     const std::lock_guard<std::mutex> lk(initMutex_);
     111           10 :     if (initFlag_) {
     112            2 :         aicpusd_info("the thread is already init, threadId[%llu], type[%u]", threadId_, type_);
     113            2 :         return AICPU_SCHEDULE_THREAD_ALREADY_EXISTS;
     114              :     }
     115            8 :     int32_t ret = 0;
     116            8 :     ret = RegisterProcessEventFunc(loopFun, paramLoopFun);
     117            8 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     118            3 :         return ret;
     119              :     }
     120            5 :     ret = RegisterStopProcessEventFunc(stopNotifyFun, paramStopFun);
     121            5 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     122            2 :         return ret;
     123              :     }
     124            3 :     const int32_t semRet = sem_init(&workerSme_, 0, 0U);
     125            3 :     if (semRet == -1) {
     126            0 :         aicpusd_err("workerSme_ init failed, type[%u], %s", type_, strerror(errno));
     127            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     128              :     }
     129            3 :     SendCustMc2CreateThreadMsgToMain();
     130            3 :     const int32_t semWaitRet = sem_wait(&workerSme_);
     131            3 :     if (semWaitRet == -1) {
     132            1 :         sem_destroy(&workerSme_);
     133            1 :         aicpusd_err("workerSme wait failed, type[%u], %s", type_, strerror(errno));
     134            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     135              :     }
     136            2 :     sem_destroy(&workerSme_);
     137            2 :     initFlag_ = true;
     138            2 :     aicpusd_info("init cust mc2 maintenance process finish. type[%u]", type_);
     139            2 :     return AICPU_SCHEDULE_OK;
     140           10 : }
     141              : 
     142            8 : int32_t AicpuCustMc2MaintenanceThread::SetCustMc2MaintenanceThreadAffinity()
     143              : {
     144            8 :     std::vector<uint32_t> ccpuIds = AicpuDrvManager::GetInstance().GetCcpuList();
     145            8 :     if (ccpuIds.empty()) {
     146            3 :         aicpusd_run_info("ccpu list is empty no need bind core");
     147            3 :         return AICPU_SCHEDULE_OK;
     148              :     }
     149           10 :     if (AicpuUtil::IsEnvValEqual(ENV_NAME_PROCMGR_AICPU_CPUSET, "1")) {
     150            1 :         aicpusd_err("the chip is not supported, please check. type[%u]", type_);
     151            1 :         return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     152              :     } else {
     153            4 :         pthread_t threadId = pthread_self();
     154            4 :         threadId_ = GetTid();
     155              :         cpu_set_t cpuset;
     156           20 :         for (const auto cpuId : ccpuIds) {
     157           16 :             CPU_SET(cpuId, &cpuset);
     158           16 :             aicpusd_info(
     159              :                 "prepare bind threadId=%lu to cpuId=%u, type=%u", threadId, static_cast<uint32_t>(cpuId), type_);
     160              :         }
     161            4 :         const int32_t ret = pthread_setaffinity_np(threadId, sizeof(cpu_set_t), &cpuset);
     162            4 :         if (ret != 0) {
     163            2 :             aicpusd_err("aicpu bind tid by self, res[%d], error[%s]. type[%u]", ret, strerror(errno), type_);
     164            2 :             return AICPU_SCHEDULE_ERROR_INNER_ERROR;
     165              :         } else {
     166            2 :             aicpusd_run_info("aicpu bind by self success. type[%u]", type_);
     167            2 :             return AICPU_SCHEDULE_OK;
     168              :         }
     169              :     }
     170            8 : }
     171            3 : void AicpuCustMc2MaintenanceThread::StartProcessEvent()
     172              : {
     173            3 :     if (SetCustMc2MaintenanceThreadAffinity() != AICPU_SCHEDULE_OK) {
     174            1 :         aicpusd_err("CustMc2 Maintenance thread bind core failed. type[%u]", type_);
     175            1 :         sem_post(&workerSme_);
     176            1 :         return;
     177              :     }
     178            2 :     sem_post(&workerSme_);
     179            2 :     aicpusd_run_info("post work sem finish. type[%u]", type_);
     180            2 :     ProcessEventFunc();
     181            2 :     ClearCustMc2MaintenanceProcess();
     182            2 :     aicpusd_run_info("CustMc2 thread ProcessEventFunc finished. type[%u]", type_);
     183              : }
     184            3 : void AicpuCustMc2MaintenanceThread::ProcessEventFunc() const
     185              : {
     186            3 :     if (processEventFuncPtr_ == nullptr) {
     187            3 :         aicpusd_err("the processEventFuncPtr not register. type[%u]", type_);
     188            3 :         return;
     189              :     }
     190            0 :     processEventFuncPtr_(processEventFuncParam_);
     191              : }
     192              : 
     193            2 : void AicpuCustMc2MaintenanceThread::ClearCustMc2MaintenanceProcess()
     194              : {
     195            2 :     aicpusd_info("ClearCustMc2MaintenanceProcess start. type[%u]", type_);
     196            2 :     processEventFuncPtr_ = nullptr;
     197            2 :     processEventFuncParam_ = nullptr;
     198            2 :     stopProcessEventFuncPtr_ = nullptr;
     199            2 :     stopProcessEventFuncParam_ = nullptr;
     200            2 :     initFlag_ = false;
     201            2 :     aicpusd_info("ClearCustMc2MaintenanceProcess finish. type[%u]", type_);
     202            2 : }
     203              : 
     204            6 : void AicpuCustMc2MaintenanceThread::StopProcessEventFunc() const
     205              : {
     206              :     // 调用结束回调
     207            6 :     if (stopProcessEventFuncPtr_ == nullptr) {
     208            3 :         aicpusd_err("the stopProcessEventFuncPtr not register. type[%u]", type_);
     209            3 :         return;
     210              :     }
     211            3 :     stopProcessEventFuncPtr_(stopProcessEventFuncParam_);
     212              : }
     213              : 
     214            5 : void AicpuCustMc2MaintenanceThread::UnitCustMc2MaintenanceProcess()
     215              : {
     216            5 :     aicpusd_info("UnitCustMc2MaintenanceProcess start. type[%u]", type_);
     217            5 :     const std::lock_guard<std::mutex> lk(initMutex_);
     218            5 :     if (!initFlag_) {
     219            2 :         aicpusd_info("the thread is already stop");
     220            2 :         return;
     221              :     }
     222            3 :     StopProcessEventFunc();
     223            3 :     aicpusd_info("StopProcessEventFunc finished. type[%u]", type_);
     224            3 :     processEventFuncPtr_ = nullptr;
     225            3 :     processEventFuncParam_ = nullptr;
     226            3 :     stopProcessEventFuncPtr_ = nullptr;
     227            3 :     stopProcessEventFuncParam_ = nullptr;
     228            3 :     initFlag_ = false;
     229            3 :     aicpusd_info("UnitCustMc2MaintenanceProcess finish. type[%u]", type_);
     230            5 : }
     231            8 : int32_t AicpuCustMc2MaintenanceThread::RegisterProcessEventFunc(AicpuMC2MaintenanceFuncPtr funPtr, void* param)
     232              : {
     233            8 :     if (funPtr == nullptr) {
     234            3 :         aicpusd_err("the process funPtr is null. type[%u]", type_);
     235            3 :         return AICPU_SCHEDULE_PARAMETER_IS_NULL;
     236              :     }
     237            5 :     processEventFuncPtr_ = funPtr;
     238            5 :     processEventFuncParam_ = param;
     239            5 :     return AICPU_SCHEDULE_OK;
     240              : }
     241              : 
     242            5 : int32_t AicpuCustMc2MaintenanceThread::RegisterStopProcessEventFunc(AicpuMC2MaintenanceFuncPtr funPtr, void* param)
     243              : {
     244            5 :     if (funPtr == nullptr) {
     245            2 :         aicpusd_err("the stop funPtr is null. type[%u]", type_);
     246            2 :         return AICPU_SCHEDULE_PARAMETER_IS_NULL;
     247              :     }
     248            3 :     stopProcessEventFuncPtr_ = funPtr;
     249            3 :     stopProcessEventFuncParam_ = param;
     250            3 :     return AICPU_SCHEDULE_OK;
     251              : }
     252              : } // namespace AicpuSchedule
     253            2 : int32_t CreateCustMc2MaintenanceThread(const struct TsdSubEventInfo* const msg)
     254              : {
     255            2 :     if (msg == nullptr) {
     256            1 :         aicpusd_err("msg is null");
     257            1 :         return AicpuSchedule::AICPU_SCHEDULE_ERROR_INNER_ERROR;
     258              :     }
     259              :     const struct AicpuSchedule::CreateCtrlThreadArgs* createCtrlThreadArgsPtr =
     260            1 :         PtrToPtr<const char_t, const struct AicpuSchedule::CreateCtrlThreadArgs>(msg->priMsg);
     261            1 :     if (createCtrlThreadArgsPtr == nullptr) {
     262            0 :         aicpusd_err("args ptr is null");
     263            0 :         return AicpuSchedule::AICPU_SCHEDULE_ERROR_INNER_ERROR;
     264              :     }
     265              :     (void)msg;
     266            1 :     uint32_t type = createCtrlThreadArgsPtr->type;
     267            1 :     aicpusd_info("aicpu create ctrl thread type[%u]", type);
     268            1 :     int32_t ret = AicpuSchedule::AicpuCustMc2MaintenanceThread::GetInstance(type).CreateCustMc2MaintenanceThread();
     269            1 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     270            1 :         aicpusd_err("Create Cust Mc2 Maintenance Thread failed, ret[%d], type[%u]", ret, type);
     271            1 :         return ret;
     272              :     }
     273            0 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     274              : }
     275              : 
     276              : #ifdef __cplusplus
     277              : extern "C" {
     278              : #endif // __cplusplus
     279           13 : int32_t StartMC2MaintenanceThread(
     280              :     AicpuMC2MaintenanceFuncPtr loopFun, void* paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun,
     281              :     void* paramStopFun)
     282              : {
     283           13 :     int32_t ret = AicpuSchedule::AicpuCustMc2MaintenanceThread::GetInstance(THREAD_TYPE_HCOM)
     284           13 :                       .InitCustMc2MaintenanceProcess(loopFun, paramLoopFun, stopNotifyFun, paramStopFun);
     285           13 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     286           11 :         return ret;
     287              :     }
     288            2 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     289              : }
     290            0 : int32_t AicpuCreateCtrlThread(
     291              :     uint32_t type, AicpuMC2MaintenanceFuncPtr loopFun, void* paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun,
     292              :     void* paramStopFun)
     293              : {
     294            0 :     if ((type != THREAD_TYPE_HCOM) && (type != THREAD_TYPE_ASCPP_PROF)) {
     295            0 :         aicpusd_err("Aicpu create ctrl thread failed, type is [%u], only support [0-1]", type);
     296            0 :         return AICPU_SCHEDULE_NOT_SUPPORT;
     297              :     }
     298            0 :     int32_t ret = AicpuSchedule::AicpuCustMc2MaintenanceThread::GetInstance(type).InitCustMc2MaintenanceProcess(
     299              :         loopFun, paramLoopFun, stopNotifyFun, paramStopFun);
     300            0 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     301            0 :         return ret;
     302              :     }
     303            0 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     304              : }
     305              : #ifdef __cplusplus
     306              : }
     307              : #endif
        

Generated by: LCOV version 2.0-1