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.6 % 192 174
Test Date: 2026-07-28 10:54:05 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              : 
      24              : namespace AicpuSchedule {
      25              :     const uint32_t DEFAULT_GROUP_ID_TO_TSD_CLIENT = 30U;
      26           59 :     AicpuCustMc2MaintenanceThread &AicpuCustMc2MaintenanceThread::GetInstance(uint32_t type)
      27              :     {
      28           59 :         if (type == 0) {
      29           58 :             static AicpuCustMc2MaintenanceThread instance(type);
      30           58 :             return instance;
      31              :         }
      32            1 :         static AicpuCustMc2MaintenanceThread instance(type);
      33            1 :         return instance;
      34              :     }
      35              : 
      36            3 :     AicpuCustMc2MaintenanceThread::~AicpuCustMc2MaintenanceThread()
      37              :     {
      38            3 :         UnitCustMc2MaintenanceProcess();
      39            3 :         if (processThread_.joinable()) {
      40            1 :             processThread_.join();
      41              :         }
      42            3 :     }
      43              : 
      44            2 :     AicpuCustMc2MaintenanceThread::AicpuCustMc2MaintenanceThread(uint32_t type)
      45            2 :         : initFlag_(false),
      46            2 :           threadId_(0LU),
      47            2 :           processEventFuncPtr_(nullptr),
      48            2 :           processEventFuncParam_(nullptr),
      49            2 :           stopProcessEventFuncPtr_(nullptr),
      50            2 :           stopProcessEventFuncParam_(nullptr),
      51            2 :           type_(type)
      52              :     {
      53            2 :     }
      54            2 :     void AicpuCustMc2MaintenanceThread::SendCustMc2CreateThreadMsgToMain() const
      55              :     {
      56            2 :         TsdSubEventInfo msg = {};
      57            2 :         event_summary eventInfo = {};
      58            2 :         eventInfo.pid = static_cast<pid_t>(getpid());
      59            2 :         eventInfo.grp_id = DEFAULT_GROUP_ID_TO_TSD_CLIENT;
      60            2 :         eventInfo.dst_engine = CCPU_DEVICE;
      61            2 :         eventInfo.event_id = EVENT_CCPU_CTRL_MSG;
      62            2 :         eventInfo.subevent_id = TSD_EVENT_START_MC2_THREAD;
      63            2 :         eventInfo.msg_len = sizeof(TsdSubEventInfo);
      64            2 :         eventInfo.msg = PtrToPtr<TsdSubEventInfo, char_t>(&msg);
      65            2 :         struct CreateCtrlThreadArgs *createCtrlThreadArgsPtr = PtrToPtr<char_t, struct CreateCtrlThreadArgs>(msg.priMsg);
      66            2 :         createCtrlThreadArgsPtr->type = type_;
      67              : 
      68            2 :         uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
      69            2 :         const drvError_t ret = halEschedSubmitEvent(deviceId, &eventInfo);
      70            2 :         if (ret != DRV_ERROR_NONE) {
      71            1 :             aicpusd_err("Failed to submit, eventId: [%d], ret: [%d].", TSD_EVENT_START_MC2_THREAD, ret);
      72              :         }
      73              : 
      74            4 :         return;
      75              :     }
      76              : 
      77            3 :     int32_t AicpuCustMc2MaintenanceThread::CreateCustMc2MaintenanceThread()
      78              :     {
      79            3 :         if (initFlag_) {
      80            1 :             aicpusd_info("the thread no need to multiple init, threadId[%llu]", threadId_);
      81            1 :             return AICPU_SCHEDULE_OK;
      82              :         }
      83              :         try {
      84            2 :             if (processThread_.joinable()) {
      85            1 :                 aicpusd_run_info("processThread join begin, threadId[%llu]", threadId_);
      86            1 :                 processThread_.join();
      87            1 :                 aicpusd_run_info("processThread join end, threadId[%llu]", threadId_);
      88              :             }
      89            2 :             processThread_ = std::thread(&AicpuCustMc2MaintenanceThread::StartProcessEvent, this);
      90            0 :         } catch (std::exception &e) {
      91            0 :             aicpusd_err("create thread file:%s", e.what());
      92            0 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      93            0 :         }
      94            2 :         return AICPU_SCHEDULE_OK;
      95              :     }
      96              : 
      97           13 :     int32_t AicpuCustMc2MaintenanceThread::InitCustMc2MaintenanceProcess(AicpuMC2MaintenanceFuncPtr loopFun,
      98              :         void *paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun, void *paramStopFun)
      99              :     {
     100           13 :         aicpusd_info("init cust mc2 maintenance process start, 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, type[%u], %s", type_, strerror(errno));
     128            0 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     129              :         }
     130            3 :         SendCustMc2CreateThreadMsgToMain();
     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, type[%u], %s", type_, strerror(errno));
     135            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     136              :         }
     137            2 :         sem_destroy(&workerSme_);
     138            2 :         initFlag_ = true;
     139            2 :         aicpusd_info("init cust mc2 maintenance process finish. type[%u]", type_);
     140            2 :         return AICPU_SCHEDULE_OK;
     141           10 :     }
     142              : 
     143            8 :     int32_t AicpuCustMc2MaintenanceThread::SetCustMc2MaintenanceThreadAffinity()
     144              :     {
     145            8 :         std::vector<uint32_t> ccpuIds = AicpuDrvManager::GetInstance().GetCcpuList();
     146            8 :         if (ccpuIds.empty()) {
     147            3 :             aicpusd_run_info("ccpu list is empty no need bind core");
     148            3 :             return AICPU_SCHEDULE_OK;
     149              :         }
     150           10 :         if (AicpuUtil::IsEnvValEqual(ENV_NAME_PROCMGR_AICPU_CPUSET, "1")) {
     151            1 :             aicpusd_err("the chip is not supported, please check. type[%u]", type_);
     152            1 :             return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
     153              :         } else {
     154            4 :             pthread_t threadId = pthread_self();
     155            4 :             threadId_ = GetTid();
     156              :             cpu_set_t cpuset;
     157           20 :             for (const auto cpuId: ccpuIds) {
     158           16 :                 CPU_SET(cpuId, &cpuset);
     159           16 :                 aicpusd_info("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              : }
     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            1 :     const struct AicpuSchedule::CreateCtrlThreadArgs *createCtrlThreadArgsPtr = PtrToPtr<const char_t, const struct AicpuSchedule::CreateCtrlThreadArgs>(msg->priMsg);
     260            1 :     if (createCtrlThreadArgsPtr == nullptr) {
     261            0 :         aicpusd_err("args ptr is null");
     262            0 :         return AicpuSchedule::AICPU_SCHEDULE_ERROR_INNER_ERROR;
     263              :     }
     264              :     (void)msg;
     265            1 :     uint32_t type = createCtrlThreadArgsPtr->type;
     266            1 :     aicpusd_info("aicpu create ctrl thread type[%u]", type);
     267            1 :     int32_t ret = AicpuSchedule::AicpuCustMc2MaintenanceThread::GetInstance(type).CreateCustMc2MaintenanceThread();
     268            1 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     269            1 :         aicpusd_err("Create Cust Mc2 Maintenance Thread failed, ret[%d], type[%u]", ret, type);
     270            1 :         return ret;
     271              :     }
     272            0 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     273              : }
     274              : 
     275              : #ifdef __cplusplus
     276              : extern "C" {
     277              : #endif // __cplusplus
     278           13 : int32_t StartMC2MaintenanceThread(AicpuMC2MaintenanceFuncPtr loopFun,
     279              :     void *paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun, void *paramStopFun)
     280              : {
     281           13 :     int32_t ret = AicpuSchedule::AicpuCustMc2MaintenanceThread::GetInstance(THREAD_TYPE_HCOM).InitCustMc2MaintenanceProcess(loopFun,
     282              :         paramLoopFun, stopNotifyFun, paramStopFun);
     283           13 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     284           11 :         return ret;
     285              :     }
     286            2 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     287              : }
     288            0 : int32_t AicpuCreateCtrlThread(uint32_t type, AicpuMC2MaintenanceFuncPtr loopFun,
     289              :     void *paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun, void *paramStopFun)
     290              : {
     291            0 :     if ((type != THREAD_TYPE_HCOM) && (type != THREAD_TYPE_ASCPP_PROF)) {
     292            0 :         aicpusd_err("Aicpu create ctrl thread failed, type is [%u], only support [0-1]", type);
     293            0 :         return AICPU_SCHEDULE_NOT_SUPPORT;
     294              :     }
     295            0 :     int32_t ret = AicpuSchedule::AicpuCustMc2MaintenanceThread::GetInstance(type).InitCustMc2MaintenanceProcess(loopFun,
     296              :         paramLoopFun, stopNotifyFun, paramStopFun);
     297            0 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     298            0 :         return ret;
     299              :     }
     300            0 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     301              : }
     302              : #ifdef __cplusplus
     303              : }
     304              : #endif
        

Generated by: LCOV version 2.0-1