LCOV - code coverage report
Current view: top level - aicpu_schedule/mc2_maintenance - aicpusd_mc2_maintenance_thread.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.5 % 189 173
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 "aicpusd_mc2_maintenance_thread.h"
      11              : #include <string.h>
      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 "aicpusd_proc_mgr_sys_operator_agent.h"
      19              : #include "aicpusd_interface_process.h"
      20              : #include "tsd.h"
      21              : #include "aicpusd_mc2_maintenance_thread_api.h"
      22              : 
      23              : namespace AicpuSchedule {
      24              : const uint32_t DEFAULT_GROUP_ID_TO_TSD_CLIENT = 30U;
      25          106 : AicpuMc2MaintenanceThread& AicpuMc2MaintenanceThread::GetInstance(uint32_t type)
      26              : {
      27          106 :     if (type == 0) { // mc2
      28           81 :         static AicpuMc2MaintenanceThread mc2Instance(type);
      29           81 :         return mc2Instance;
      30              :     }
      31              :     // profiling
      32           25 :     static AicpuMc2MaintenanceThread profInstance(type);
      33           25 :     return profInstance;
      34              : }
      35              : 
      36            5 : AicpuMc2MaintenanceThread::~AicpuMc2MaintenanceThread()
      37              : {
      38            5 :     UnitMc2MantenanceProcess();
      39            5 :     if (processThread_.joinable()) {
      40            1 :         processThread_.join();
      41              :     }
      42            5 : }
      43              : 
      44            4 : AicpuMc2MaintenanceThread::AicpuMc2MaintenanceThread(uint32_t type)
      45            4 :     : initFlag_(false),
      46            4 :       threadId_(0LU),
      47            4 :       processEventFuncPtr_(nullptr),
      48            4 :       processEventFuncParam_(nullptr),
      49            4 :       stopProcessEventFuncPtr_(nullptr),
      50            4 :       stopProcessEventFuncParam_(nullptr),
      51            4 :       type_(type)
      52            4 : {}
      53            2 : void AicpuMc2MaintenanceThread::SendMc2CreateThreadMsgToMain() const
      54              : {
      55            2 :     TsdSubEventInfo msg = {};
      56            2 :     event_summary eventInfo = {};
      57            2 :     eventInfo.pid = static_cast<pid_t>(getpid());
      58            2 :     eventInfo.grp_id = DEFAULT_GROUP_ID_TO_TSD_CLIENT;
      59            2 :     eventInfo.dst_engine = CCPU_DEVICE;
      60            2 :     eventInfo.event_id = EVENT_CCPU_CTRL_MSG;
      61            2 :     eventInfo.subevent_id = TSD_EVENT_START_MC2_THREAD;
      62            2 :     eventInfo.msg_len = sizeof(TsdSubEventInfo);
      63            2 :     eventInfo.msg = PtrToPtr<TsdSubEventInfo, char_t>(&msg);
      64            2 :     struct CreateCtrlThreadArgs* createCtrlThreadArgsPtr = PtrToPtr<char_t, struct CreateCtrlThreadArgs>(msg.priMsg);
      65            2 :     createCtrlThreadArgsPtr->type = type_;
      66              : 
      67            2 :     uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
      68            2 :     const drvError_t ret = halEschedSubmitEvent(deviceId, &eventInfo);
      69            2 :     if (ret != DRV_ERROR_NONE) {
      70            1 :         aicpusd_err("Failed to submit, eventId: [%d], ret: [%d].", TSD_EVENT_START_MC2_THREAD, ret);
      71              :     }
      72              : 
      73            4 :     return;
      74              : }
      75              : 
      76            3 : int32_t AicpuMc2MaintenanceThread::CreateMc2MantenanceThread()
      77              : {
      78            3 :     if (initFlag_) {
      79            1 :         aicpusd_info("the thread no need to multiple init, threadId[%llu]", threadId_);
      80            1 :         return AICPU_SCHEDULE_OK;
      81              :     }
      82              :     try {
      83            2 :         if (processThread_.joinable()) {
      84            1 :             aicpusd_run_info("processThread join begin, threadId[%llu]", threadId_);
      85            1 :             processThread_.join();
      86            1 :             aicpusd_run_info("processThread join end, threadId[%llu]", threadId_);
      87              :         }
      88            2 :         processThread_ = std::thread(&AicpuMc2MaintenanceThread::StartProcessEvent, this);
      89            0 :     } catch (std::exception& e) {
      90            0 :         aicpusd_err("create thread file:%s", e.what());
      91            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      92            0 :     }
      93            2 :     return AICPU_SCHEDULE_OK;
      94              : }
      95              : 
      96           13 : int32_t AicpuMc2MaintenanceThread::InitMc2MaintenanceProcess(
      97              :     AicpuMC2MaintenanceFuncPtr loopFun, void* paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun,
      98              :     void* paramStopFun)
      99              : {
     100           13 :     aicpusd_info("type[%u]", type_);
     101              :     uint32_t runMode;
     102           13 :     const aicpu::status_t status = aicpu::GetAicpuRunMode(runMode);
     103           13 :     if (status != aicpu::AICPU_ERROR_NONE) {
     104            1 :         aicpusd_err("Get current aicpu ctx failed. type[%u]", type_);
     105            1 :         return AICPU_SCHEDULE_ERROR_INNER_ERROR;
     106              :     }
     107           12 :     if (runMode != aicpu::AicpuRunMode::PROCESS_PCIE_MODE) {
     108            2 :         aicpusd_info("not pcie mode no need this thread. type[%u]", type_);
     109            2 :         return AICPU_SCHEDULE_NOT_SUPPORT;
     110              :     }
     111           10 :     const std::lock_guard<std::mutex> lk(initMutex_);
     112           10 :     if (initFlag_) {
     113            2 :         aicpusd_info("the thread is already init, threadId[%llu], type[%u]", threadId_, type_);
     114            2 :         return AICPU_SCHEDULE_THREAD_ALREADY_EXISTS;
     115              :     }
     116            8 :     int32_t ret = 0;
     117            8 :     ret = RegisterProcessEventFunc(loopFun, paramLoopFun);
     118            8 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     119            3 :         return ret;
     120              :     }
     121            5 :     ret = RegisterStopProcessEventFunc(stopNotifyFun, paramStopFun);
     122            5 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     123            2 :         return ret;
     124              :     }
     125            3 :     const int32_t semRet = sem_init(&workerSme_, 0, 0U);
     126            3 :     if (semRet == -1) {
     127            0 :         aicpusd_err("workerSme_ init failed, %s, type[%u]", strerror(errno), type_);
     128            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     129              :     }
     130            3 :     SendMc2CreateThreadMsgToMain();
     131            3 :     const int32_t semWaitRet = sem_wait(&workerSme_);
     132            3 :     if (semWaitRet == -1) {
     133            1 :         sem_destroy(&workerSme_);
     134            1 :         aicpusd_err("workerSme wait failed, %s, type[%u]", strerror(errno), type_);
     135            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     136              :     }
     137            2 :     sem_destroy(&workerSme_);
     138            2 :     initFlag_ = true;
     139            2 :     return AICPU_SCHEDULE_OK;
     140           10 : }
     141              : 
     142            8 : int32_t AicpuMc2MaintenanceThread::SetMc2MantenanceThreadAffinity()
     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. type[%u]", type_);
     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           14 :         for (const auto cpuId : ccpuIds) {
     157           10 :             CPU_SET(cpuId, &cpuset);
     158           10 :             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 AicpuMc2MaintenanceThread::StartProcessEvent()
     172              : {
     173            3 :     if (SetMc2MantenanceThreadAffinity() != AICPU_SCHEDULE_OK) {
     174            1 :         aicpusd_err("Mc2 Maintenance thread bind core failed. type[%u]", type_);
     175            1 :         sem_post(&workerSme_);
     176            1 :         return;
     177              :     }
     178            2 :     aicpusd_info("StartProcessEvent type[%u]", type_);
     179            2 :     sem_post(&workerSme_);
     180            2 :     aicpusd_run_info("post work sem finish. type[%u]", type_);
     181            2 :     ProcessEventFunc();
     182            2 :     ClearMc2MantenanceProcess();
     183            2 :     aicpusd_run_info("mc2 thread ProcessEventFunc finished. type[%u]", type_);
     184              : }
     185            3 : void AicpuMc2MaintenanceThread::ProcessEventFunc() const
     186              : {
     187            3 :     if (processEventFuncPtr_ == nullptr) {
     188            3 :         aicpusd_err("the processEventFuncPtr not register. type[%u]", type_);
     189            3 :         return;
     190              :     }
     191            0 :     processEventFuncPtr_(processEventFuncParam_);
     192              : }
     193              : 
     194            2 : void AicpuMc2MaintenanceThread::ClearMc2MantenanceProcess()
     195              : {
     196            2 :     aicpusd_info("ClearMc2MantenanceProcess start. type[%u]", type_);
     197            2 :     processEventFuncPtr_ = nullptr;
     198            2 :     processEventFuncParam_ = nullptr;
     199            2 :     stopProcessEventFuncPtr_ = nullptr;
     200            2 :     stopProcessEventFuncParam_ = nullptr;
     201            2 :     initFlag_ = false;
     202            2 :     aicpusd_info("ClearMc2MantenanceProcess finish. type[%u]", type_);
     203            2 : }
     204              : 
     205            6 : void AicpuMc2MaintenanceThread::StopProcessEventFunc() const
     206              : {
     207              :     // 调用结束回调
     208            6 :     if (stopProcessEventFuncPtr_ == nullptr) {
     209            3 :         aicpusd_err("the stopProcessEventFuncPtr not register. type[%u]", type_);
     210            3 :         return;
     211              :     }
     212            3 :     stopProcessEventFuncPtr_(stopProcessEventFuncParam_);
     213              : }
     214              : 
     215           55 : void AicpuMc2MaintenanceThread::UnitMc2MantenanceProcess()
     216              : {
     217           55 :     aicpusd_info("UnitMc2MantenanceProcess start. type[%u]", type_);
     218           55 :     const std::lock_guard<std::mutex> lk(initMutex_);
     219           55 :     if (!initFlag_) {
     220           52 :         aicpusd_info("the thread is already stop");
     221           52 :         return;
     222              :     }
     223            3 :     StopProcessEventFunc();
     224            3 :     aicpusd_info("StopProcessEventFunc finished. type[%u]", type_);
     225            3 :     processEventFuncPtr_ = nullptr;
     226            3 :     processEventFuncParam_ = nullptr;
     227            3 :     stopProcessEventFuncPtr_ = nullptr;
     228            3 :     stopProcessEventFuncParam_ = nullptr;
     229            3 :     initFlag_ = false;
     230            3 :     aicpusd_info("UnitMc2MantenanceProcess finish. type[%u]", type_);
     231           55 : }
     232            8 : int32_t AicpuMc2MaintenanceThread::RegisterProcessEventFunc(AicpuMC2MaintenanceFuncPtr funPtr, void* param)
     233              : {
     234            8 :     if (funPtr == nullptr) {
     235            3 :         aicpusd_err("the process funPtr is null. type[%u]", type_);
     236            3 :         return AICPU_SCHEDULE_PARAMETER_IS_NULL;
     237              :     }
     238            5 :     processEventFuncPtr_ = funPtr;
     239            5 :     processEventFuncParam_ = param;
     240            5 :     return AICPU_SCHEDULE_OK;
     241              : }
     242              : 
     243            5 : int32_t AicpuMc2MaintenanceThread::RegisterStopProcessEventFunc(AicpuMC2MaintenanceFuncPtr funPtr, void* param)
     244              : {
     245            5 :     if (funPtr == nullptr) {
     246            2 :         aicpusd_err("the stop funPtr is null. type[%u]", type_);
     247            2 :         return AICPU_SCHEDULE_PARAMETER_IS_NULL;
     248              :     }
     249            3 :     stopProcessEventFuncPtr_ = funPtr;
     250            3 :     stopProcessEventFuncParam_ = param;
     251            3 :     return AICPU_SCHEDULE_OK;
     252              : }
     253              : } // namespace AicpuSchedule
     254            2 : int32_t CreateMc2MantenanceThread(const struct TsdSubEventInfo* const msg)
     255              : {
     256            2 :     AICPUSD_CHECK((msg != nullptr), AicpuSchedule::AICPU_SCHEDULE_ERROR_INNER_ERROR, "msg is nulll");
     257              :     const struct AicpuSchedule::CreateCtrlThreadArgs* createCtrlThreadArgsPtr =
     258            1 :         PtrToPtr<const char_t, const struct AicpuSchedule::CreateCtrlThreadArgs>(msg->priMsg);
     259            1 :     AICPUSD_CHECK(
     260              :         (createCtrlThreadArgsPtr != nullptr), AicpuSchedule::AICPU_SCHEDULE_ERROR_INNER_ERROR, "args ptr is nulll");
     261            1 :     uint32_t type = createCtrlThreadArgsPtr->type;
     262            1 :     aicpusd_info("aicpu create ctrl thread type[%u]", type);
     263            1 :     int32_t ret = AicpuSchedule::AicpuMc2MaintenanceThread::GetInstance(type).CreateMc2MantenanceThread();
     264            1 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     265            1 :         aicpusd_err("Create Mc2 Maintenance Thread failed, ret[%d] type[%u]", ret, type);
     266            1 :         return ret;
     267              :     }
     268            0 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     269              : }
     270           13 : int32_t StartMC2MaintenanceThread(
     271              :     AicpuMC2MaintenanceFuncPtr loopFun, void* paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun,
     272              :     void* paramStopFun)
     273              : {
     274           13 :     int32_t ret = AicpuSchedule::AicpuMc2MaintenanceThread::GetInstance(THREAD_TYPE_HCOM)
     275           13 :                       .InitMc2MaintenanceProcess(loopFun, paramLoopFun, stopNotifyFun, paramStopFun);
     276           13 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     277           11 :         return ret;
     278              :     }
     279            2 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     280              : }
     281              : 
     282            0 : int32_t AicpuCreateCtrlThread(
     283              :     uint32_t type, AicpuMC2MaintenanceFuncPtr loopFun, void* paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun,
     284              :     void* paramStopFun)
     285              : {
     286            0 :     if ((type != THREAD_TYPE_HCOM) && (type != THREAD_TYPE_ASCPP_PROF)) {
     287            0 :         aicpusd_err("Aicpu create ctrl thread failed, type is [%u], only support [0-1]", type);
     288            0 :         return AICPU_SCHEDULE_NOT_SUPPORT;
     289              :     }
     290            0 :     int32_t ret = AicpuSchedule::AicpuMc2MaintenanceThread::GetInstance(type).InitMc2MaintenanceProcess(
     291              :         loopFun, paramLoopFun, stopNotifyFun, paramStopFun);
     292            0 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     293            0 :         return ret;
     294              :     }
     295            0 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     296              : }
        

Generated by: LCOV version 2.0-1