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 % 188 172
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 "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              : 
      24              : namespace AicpuSchedule {
      25              :     const uint32_t DEFAULT_GROUP_ID_TO_TSD_CLIENT = 30U;
      26          106 :     AicpuMc2MaintenanceThread &AicpuMc2MaintenanceThread::GetInstance(uint32_t type)
      27              :     {
      28          106 :         if (type == 0) { // mc2
      29           81 :             static AicpuMc2MaintenanceThread mc2Instance(type);
      30           81 :             return mc2Instance;
      31              :         } 
      32              :         // profiling
      33           25 :         static AicpuMc2MaintenanceThread profInstance(type);
      34           25 :         return profInstance;
      35              :     }
      36              : 
      37            5 :     AicpuMc2MaintenanceThread::~AicpuMc2MaintenanceThread()
      38              :     {
      39            5 :         UnitMc2MantenanceProcess();
      40            5 :         if (processThread_.joinable()) {
      41            1 :             processThread_.join();
      42              :         }
      43            5 :     }
      44              : 
      45            4 :     AicpuMc2MaintenanceThread::AicpuMc2MaintenanceThread(uint32_t type)
      46            4 :         : initFlag_(false),
      47            4 :           threadId_(0LU),
      48            4 :           processEventFuncPtr_(nullptr),
      49            4 :           processEventFuncParam_(nullptr),
      50            4 :           stopProcessEventFuncPtr_(nullptr),
      51            4 :           stopProcessEventFuncParam_(nullptr),
      52            4 :           type_(type)
      53              :     {
      54            4 :     }
      55            2 :     void AicpuMc2MaintenanceThread::SendMc2CreateThreadMsgToMain() const
      56              :     {
      57            2 :         TsdSubEventInfo msg = {};
      58            2 :         event_summary eventInfo = {};
      59            2 :         eventInfo.pid = static_cast<pid_t>(getpid());
      60            2 :         eventInfo.grp_id = DEFAULT_GROUP_ID_TO_TSD_CLIENT;
      61            2 :         eventInfo.dst_engine = CCPU_DEVICE;
      62            2 :         eventInfo.event_id = EVENT_CCPU_CTRL_MSG;
      63            2 :         eventInfo.subevent_id = TSD_EVENT_START_MC2_THREAD;
      64            2 :         eventInfo.msg_len = sizeof(TsdSubEventInfo);
      65            2 :         eventInfo.msg = PtrToPtr<TsdSubEventInfo, char_t>(&msg);
      66            2 :         struct CreateCtrlThreadArgs *createCtrlThreadArgsPtr = PtrToPtr<char_t, struct CreateCtrlThreadArgs>(msg.priMsg);
      67            2 :         createCtrlThreadArgsPtr->type = type_;
      68              : 
      69            2 :         uint32_t deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
      70            2 :         const drvError_t ret = halEschedSubmitEvent(deviceId, &eventInfo);
      71            2 :         if (ret != DRV_ERROR_NONE) {
      72            1 :             aicpusd_err("Failed to submit, eventId: [%d], ret: [%d].", TSD_EVENT_START_MC2_THREAD, ret);
      73              :         }
      74              : 
      75            4 :         return;
      76              :     }
      77              : 
      78            3 :     int32_t AicpuMc2MaintenanceThread::CreateMc2MantenanceThread()
      79              :     {
      80            3 :         if (initFlag_) {
      81            1 :             aicpusd_info("the thread no need to multiple init, threadId[%llu]", threadId_);
      82            1 :             return AICPU_SCHEDULE_OK;
      83              :         }
      84              :         try {
      85            2 :             if (processThread_.joinable()) {
      86            1 :                 aicpusd_run_info("processThread join begin, threadId[%llu]", threadId_);
      87            1 :                 processThread_.join();
      88            1 :                 aicpusd_run_info("processThread join end, threadId[%llu]", threadId_);
      89              :             }
      90            2 :             processThread_ = std::thread(&AicpuMc2MaintenanceThread::StartProcessEvent, this);
      91            0 :         } catch (std::exception &e) {
      92            0 :             aicpusd_err("create thread file:%s", e.what());
      93            0 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      94            0 :         }
      95            2 :         return AICPU_SCHEDULE_OK;
      96              :     }
      97              : 
      98           13 :     int32_t AicpuMc2MaintenanceThread::InitMc2MaintenanceProcess(AicpuMC2MaintenanceFuncPtr loopFun,
      99              :         void *paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun, void *paramStopFun)
     100              :     {
     101           13 :         aicpusd_info("type[%u]", type_);
     102              :         uint32_t runMode;
     103           13 :         const aicpu::status_t status = aicpu::GetAicpuRunMode(runMode);
     104           13 :         if (status != aicpu::AICPU_ERROR_NONE) {
     105            1 :             aicpusd_err("Get current aicpu ctx failed. type[%u]", type_);
     106            1 :             return AICPU_SCHEDULE_ERROR_INNER_ERROR;
     107              :         }
     108           12 :         if (runMode != aicpu::AicpuRunMode::PROCESS_PCIE_MODE) {
     109            2 :             aicpusd_info("not pcie mode no need this thread. type[%u]", type_);
     110            2 :             return AICPU_SCHEDULE_NOT_SUPPORT;
     111              :         }
     112           10 :         const std::lock_guard<std::mutex> lk(initMutex_);
     113           10 :         if (initFlag_) {
     114            2 :             aicpusd_info("the thread is already init, threadId[%llu], type[%u]", threadId_, type_);
     115            2 :             return AICPU_SCHEDULE_THREAD_ALREADY_EXISTS;
     116              :         }
     117            8 :         int32_t ret = 0;
     118            8 :         ret = RegisterProcessEventFunc(loopFun, paramLoopFun);
     119            8 :         if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     120            3 :             return ret;
     121              :         }
     122            5 :         ret = RegisterStopProcessEventFunc(stopNotifyFun, paramStopFun);
     123            5 :         if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     124            2 :             return ret;
     125              :         }
     126            3 :         const int32_t semRet = sem_init(&workerSme_, 0, 0U);
     127            3 :         if (semRet == -1) {
     128            0 :             aicpusd_err("workerSme_ init failed, %s, type[%u]", strerror(errno), type_);
     129            0 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     130              :         }
     131            3 :         SendMc2CreateThreadMsgToMain();
     132            3 :         const int32_t semWaitRet = sem_wait(&workerSme_);
     133            3 :         if (semWaitRet == -1) {
     134            1 :             sem_destroy(&workerSme_);
     135            1 :             aicpusd_err("workerSme wait failed, %s, type[%u]", strerror(errno), type_);
     136            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     137              :         }
     138            2 :         sem_destroy(&workerSme_);
     139            2 :         initFlag_ = true;
     140            2 :         return AICPU_SCHEDULE_OK;
     141           10 :     }
     142              : 
     143            8 :     int32_t AicpuMc2MaintenanceThread::SetMc2MantenanceThreadAffinity()
     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. type[%u]", type_);
     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           14 :             for (const auto cpuId: ccpuIds) {
     158           10 :                 CPU_SET(cpuId, &cpuset);
     159           10 :                 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 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              : }
     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            1 :     const struct AicpuSchedule::CreateCtrlThreadArgs *createCtrlThreadArgsPtr = PtrToPtr<const char_t, const struct AicpuSchedule::CreateCtrlThreadArgs>(msg->priMsg);
     258            1 :     AICPUSD_CHECK((createCtrlThreadArgsPtr != nullptr), AicpuSchedule::AICPU_SCHEDULE_ERROR_INNER_ERROR, "args ptr is nulll");
     259            1 :     uint32_t type = createCtrlThreadArgsPtr->type;
     260            1 :     aicpusd_info("aicpu create ctrl thread type[%u]", type);
     261            1 :     int32_t ret = AicpuSchedule::AicpuMc2MaintenanceThread::GetInstance(type).CreateMc2MantenanceThread();
     262            1 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     263            1 :         aicpusd_err("Create Mc2 Maintenance Thread failed, ret[%d] type[%u]", ret, type);
     264            1 :         return ret;
     265              :     }
     266            0 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     267              : }
     268           13 : int32_t StartMC2MaintenanceThread(AicpuMC2MaintenanceFuncPtr loopFun,
     269              :     void *paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun, void *paramStopFun)
     270              : {
     271           13 :     int32_t ret = AicpuSchedule::AicpuMc2MaintenanceThread::GetInstance(THREAD_TYPE_HCOM).InitMc2MaintenanceProcess(loopFun,
     272              :         paramLoopFun, stopNotifyFun, paramStopFun);
     273           13 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     274           11 :         return ret;
     275              :     }
     276            2 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     277              : }
     278              : 
     279            0 : int32_t AicpuCreateCtrlThread(uint32_t type, AicpuMC2MaintenanceFuncPtr loopFun,
     280              :     void *paramLoopFun, AicpuMC2MaintenanceFuncPtr stopNotifyFun, void *paramStopFun)
     281              : {
     282            0 :     if ((type != THREAD_TYPE_HCOM) && (type != THREAD_TYPE_ASCPP_PROF)) {
     283            0 :         aicpusd_err("Aicpu create ctrl thread failed, type is [%u], only support [0-1]", type);
     284            0 :         return AICPU_SCHEDULE_NOT_SUPPORT;
     285              :     }
     286            0 :     int32_t ret = AicpuSchedule::AicpuMc2MaintenanceThread::GetInstance(type).InitMc2MaintenanceProcess(loopFun,
     287              :         paramLoopFun, stopNotifyFun, paramStopFun);
     288            0 :     if (ret != AicpuSchedule::AICPU_SCHEDULE_OK) {
     289            0 :         return ret;
     290              :     }
     291            0 :     return AicpuSchedule::AICPU_SCHEDULE_OK;
     292              : }
        

Generated by: LCOV version 2.0-1