LCOV - code coverage report
Current view: top level - aicpu_cust_schedule/core - aicpusd_worker.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.4 % 255 228
Test Date: 2026-08-31 10:07:09 Functions: 100.0 % 18 18

            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_worker.h"
      11              : 
      12              : #include <csignal>
      13              : #include <cstring>
      14              : #include <fstream>
      15              : 
      16              : #include "aicpusd_status.h"
      17              : #include "aicpusd_drv_manager.h"
      18              : #include "aicpusd_monitor.h"
      19              : #include "aicpusd_event_manager.h"
      20              : #include "aicpu_context.h"
      21              : #include "aicpusd_common.h"
      22              : #include "aicpu_cust_sd_proc_mgr_sys_operator_agent.h"
      23              : #include "aicpusd_hal_interface_ref.h"
      24              : #include "aicpusd_util.h"
      25              : #include "feature_ctrl.h"
      26              : #ifndef _AOSCORE_
      27              : #include "seccomp.h"
      28              : #endif
      29              : 
      30              : namespace {
      31              : constexpr uint32_t EVENT_MASK = (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_RANDOM_KERNEL)) |
      32              :                                 (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_TS_HWTS_KERNEL)) |
      33              :                                 (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_AICPU_MSG)) |
      34              :                                 (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_TS_CTRL_MSG)) |
      35              :                                 (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_SPLIT_KERNEL)) |
      36              :                                 (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_FFTS_PLUS_MSG));
      37              : constexpr const char_t* SYSCALL_WHITE_LIST = "/var/aicpu_custom_syscall_whitelist";
      38              : constexpr size_t NO_AICPU_WORKER_NUM = 2UL;
      39              : constexpr uint32_t INVALID_CPU_ID = UINT32_MAX;
      40              : } // namespace
      41              : 
      42              : namespace AicpuSchedule {
      43           24 : ThreadPool& ThreadPool::Instance()
      44              : {
      45           24 :     static ThreadPool threadPool;
      46           24 :     return threadPool;
      47              : }
      48              : 
      49           32 : ThreadPool::ThreadPool() : semInitedNum_(0U) {}
      50              : 
      51           32 : ThreadPool::~ThreadPool()
      52              : {
      53           39 :     for (size_t i = 0UL; i < semInitedNum_; ++i) {
      54            7 :         (void)sem_destroy(&(sems_[i]));
      55              :     }
      56           32 : }
      57              : 
      58           21 : size_t ThreadPool::GetWorkerNum()
      59              : {
      60           21 :     const size_t aicpuNum = static_cast<size_t>(AicpuDrvManager::GetInstance().GetAicpuNum());
      61           21 :     return (aicpuNum == 0UL) ? NO_AICPU_WORKER_NUM : aicpuNum;
      62              : }
      63              : 
      64            7 : int32_t ThreadPool::CreateWorker()
      65              : {
      66            7 :     const size_t workerNum = GetWorkerNum();
      67            7 :     hasAicpu_ = AicpuDrvManager::GetInstance().GetAicpuNum() != 0U;
      68            7 :     if (!hasAicpu_) {
      69            2 :         aicpusd_run_info("aicpu num[0], create [%zu] aicpu workers", workerNum);
      70              :     }
      71              :     try {
      72           14 :         sems_ = std::move(std::vector<sem_t>(workerNum));
      73            0 :     } catch (std::exception& e) {
      74            0 :         aicpusd_err("create sems failed, %s", e.what());
      75            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      76            0 :     }
      77           15 :     for (size_t threadIndex = 0UL; threadIndex < workerNum; ++threadIndex) {
      78            9 :         const int32_t semInitRet = sem_init(&(sems_[threadIndex]), 0, 0U);
      79            9 :         if (semInitRet == -1) {
      80            1 :             aicpusd_err("sem[%zu] init failed, %s", threadIndex, strerror(errno));
      81            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      82              :         }
      83            8 :         semInitedNum_ = static_cast<uint32_t>(threadIndex + 1UL);
      84              :     }
      85              :     try {
      86           12 :         threadStatus_ = std::move(std::vector<ThreadStatus>(workerNum, ThreadStatus::THREAD_INIT));
      87            0 :     } catch (std::exception& e) {
      88            0 :         aicpusd_err("create ThreadStatus failed, %s", e.what());
      89            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
      90            0 :     }
      91            6 :     int32_t ret = AICPU_SCHEDULE_OK;
      92            6 :     const sighandler_t oldHandler = signal(SIGCHLD, SIG_DFL);
      93            6 :     aicpusd_info("Set SIGCHLD to %d, old sighandler[%d]", SIG_DFL, oldHandler);
      94            6 :     GetExpandedSysCalls(SYSCALL_WHITE_LIST);
      95           13 :     for (size_t threadIndex = 0UL; threadIndex < workerNum; ++threadIndex) {
      96            8 :         ret = CreateOneWorker(static_cast<uint32_t>(threadIndex));
      97            8 :         if (ret != AICPU_SCHEDULE_OK) {
      98            1 :             (void)signal(SIGCHLD, oldHandler);
      99            1 :             return ret;
     100              :         }
     101              :     }
     102            9 :     for (size_t threadIndex = 0UL; threadIndex < workerNum; ++threadIndex) {
     103            7 :         const int32_t semWaitRet = sem_wait(&(sems_[threadIndex]));
     104            7 :         if (semWaitRet == -1) {
     105            1 :             (void)signal(SIGCHLD, oldHandler);
     106            1 :             aicpusd_err("sem[%zu] wait failed, %s", threadIndex, strerror(errno));
     107            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     108              :         }
     109            6 :         if (threadStatus_[threadIndex] != ThreadStatus::THREAD_RUNNING) {
     110            2 :             (void)signal(SIGCHLD, oldHandler);
     111            2 :             aicpusd_err("create thread[%zu] failed, status[%d]", threadIndex, threadStatus_[threadIndex]);
     112            2 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     113              :         }
     114              :     }
     115            2 :     aicpusd_info("set SIGCHLD to old sighandler[%d]", oldHandler);
     116            2 :     (void)signal(SIGCHLD, oldHandler);
     117              :     // GetInstance is not null, checked in InitAICPUScheduler
     118            2 :     ret = AicpuSchedule::AicpuMonitor::GetInstance().Run();
     119            2 :     if (ret != AICPU_SCHEDULE_OK) {
     120            0 :         aicpusd_err("aicpu monitor run failed, ret[%d]", ret);
     121            0 :         return ret;
     122              :     }
     123              : 
     124            2 :     return AICPU_SCHEDULE_OK;
     125              : }
     126              : 
     127            3 : int32_t ThreadPool::CreateOneWorker(const uint32_t threadIndex)
     128              : {
     129            3 :     aicpusd_info("CreateOneWorker index[%d]", threadIndex);
     130              :     try {
     131            3 :         std::thread th(&ThreadPool::Work, threadIndex);
     132            6 :         workers_.emplace_back(std::move(th));
     133            3 :     } catch (std::exception& e) {
     134            0 :         aicpusd_err("create aicpu worker[%u] failed, %s", threadIndex, e.what());
     135            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     136            0 :     }
     137              :     try {
     138            3 :         workers_[static_cast<size_t>(threadIndex)].detach();
     139            0 :     } catch (std::exception& e) {
     140            0 :         aicpusd_err("thread[%u] detach failed, %s", threadIndex, e.what());
     141            0 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     142            0 :     }
     143              : 
     144            3 :     return AICPU_SCHEDULE_OK;
     145              : }
     146              : 
     147            8 : void ThreadPool::GetExpandedSysCalls(const char_t* const whitelist)
     148              : {
     149            8 :     std::ifstream inFile(whitelist);
     150            8 :     if ((access(whitelist, R_OK) != 0) || !inFile) {
     151            7 :         aicpusd_info("syscall file: %s is invalid", whitelist);
     152            7 :         return;
     153              :     }
     154            2 :     const ScopeGuard fileGuard([&inFile]() { inFile.close(); });
     155              : 
     156            1 :     std::string syscallStr;
     157            4 :     while (getline(inFile, syscallStr)) {
     158            3 :         aicpusd_info("read syscall: %s", syscallStr.c_str());
     159            3 :         const int32_t syscallNo = seccomp_syscall_resolve_name(syscallStr.c_str());
     160            3 :         if (syscallNo < 0) {
     161            1 :             aicpusd_run_warn("Unknown syscall: %s, ret is %d.", syscallStr.c_str(), syscallNo);
     162            1 :             continue;
     163              :         }
     164            2 :         aicpusd_info("syscall: %s, syscallNo: %d", syscallStr.c_str(), syscallNo);
     165            2 :         (void)expandedSystemCalls_.insert(syscallNo);
     166              :     }
     167            8 : }
     168              : 
     169            3 : void ThreadPool::ExpandSysCallList(std::unordered_set<int32_t>& filterSystemCalls)
     170              : {
     171            5 :     for (const auto expandedSystemCall : expandedSystemCalls_) {
     172            2 :         const auto insertRet = filterSystemCalls.insert(expandedSystemCall);
     173            2 :         if (insertRet.second) {
     174            1 :             aicpusd_run_info("Expand syscallNo: %d.", expandedSystemCall);
     175              :         }
     176              :     }
     177            3 : }
     178              : 
     179            5 : int32_t ThreadPool::SecureCompute(const uint32_t threadIndex)
     180              : {
     181            5 :     if ((FeatureCtrl::IsAosCore() || (!AicpuSchedule::AicpuDrvManager::GetInstance().GetSafeVerifyFlag()))) {
     182            3 :         threadStatus_[static_cast<size_t>(threadIndex)] = ThreadStatus::THREAD_RUNNING;
     183            3 :         aicpusd_info("Execute seccomp_load success.");
     184            3 :         return AICPU_SCHEDULE_OK;
     185              :     }
     186              :     std::unordered_set<int32_t> filterSystemCalls = {
     187              :         SCMP_SYS(open),
     188              :         SCMP_SYS(close),
     189              :         SCMP_SYS(faccessat),
     190              :         SCMP_SYS(fstat),
     191              :         SCMP_SYS(futex),
     192              :         SCMP_SYS(getpid),
     193              :         SCMP_SYS(gettid),
     194              :         SCMP_SYS(ioctl),
     195              :         SCMP_SYS(lseek),
     196              :         SCMP_SYS(nanosleep),
     197              :         SCMP_SYS(openat),
     198              :         SCMP_SYS(newfstatat),
     199              :         SCMP_SYS(pselect6),
     200              :         SCMP_SYS(read),
     201              :         SCMP_SYS(readlinkat),
     202              :         SCMP_SYS(rt_sigaction),
     203              :         SCMP_SYS(mmap),
     204              :         SCMP_SYS(mprotect),
     205              :         SCMP_SYS(exit),
     206              :         SCMP_SYS(exit_group),
     207              :         SCMP_SYS(madvise),
     208              :         SCMP_SYS(sched_getaffinity),
     209              :         SCMP_SYS(rt_sigprocmask),
     210              :         SCMP_SYS(set_robust_list),
     211              :         SCMP_SYS(munmap),
     212              :         SCMP_SYS(sysinfo),
     213              :         SCMP_SYS(clock_nanosleep),
     214              :         SCMP_SYS(uname),
     215              :         SCMP_SYS(getcpu),
     216              :         SCMP_SYS(write),
     217            4 :         SCMP_SYS(getrandom)};
     218            2 :     ExpandSysCallList(filterSystemCalls);
     219              : 
     220              :     // filter enable system calls
     221            2 :     const scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ERRNO(1U));
     222            2 :     int32_t ret = 0;
     223           64 :     for (auto filterSystemCall : filterSystemCalls) {
     224           62 :         ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, filterSystemCall, 0U);
     225           62 :         if (ret != 0) {
     226            0 :             threadStatus_[static_cast<size_t>(threadIndex)] = ThreadStatus::THREAD_EXIT;
     227            0 :             aicpusd_err(
     228              :                 "Add the system call failed, thread threadIndex[%u], ret[%d],"
     229              :                 " syscall number[%d].",
     230              :                 threadIndex, ret, filterSystemCall);
     231            0 :             return AICPU_SCHEDULE_ERROR_COMMON_ERROR;
     232              :         }
     233              :     }
     234              : 
     235            2 :     ret = seccomp_load(ctx);
     236            2 :     if (ret != 0) {
     237            0 :         threadStatus_[static_cast<size_t>(threadIndex)] = ThreadStatus::THREAD_EXIT;
     238            0 :         aicpusd_err("Execute seccomp_load failed, thread threadIndex[%u], ret[%d].", threadIndex, ret);
     239            0 :         return AICPU_SCHEDULE_ERROR_COMMON_ERROR;
     240              :     }
     241            2 :     threadStatus_[static_cast<size_t>(threadIndex)] = ThreadStatus::THREAD_RUNNING;
     242            2 :     aicpusd_info("Execute seccomp_load success.");
     243            2 :     return AICPU_SCHEDULE_OK;
     244            2 : }
     245              : 
     246            7 : void ThreadPool::Work(const uint32_t threadIndex)
     247              : {
     248            7 :     const uint32_t deviceId = AicpuSchedule::AicpuDrvManager::GetInstance().GetDeviceId();
     249              :     aicpu::aicpuContext_t context;
     250            7 :     context.tsId = 0U;
     251            7 :     context.deviceId = deviceId;
     252            7 :     context.hostPid = AicpuDrvManager::GetInstance().GetHostPid();
     253            7 :     context.vfId = AicpuDrvManager::GetInstance().GetVfId();
     254            7 :     aicpu::SetUniqueVfId(AicpuDrvManager::GetInstance().GetUniqueVfId());
     255            7 :     const auto aicpuRet = aicpu::aicpuSetContext(&context);
     256            7 :     if (aicpuRet != aicpu::AICPU_ERROR_NONE) {
     257            1 :         aicpusd_err("Set aicpu context failed, deviceId[%u], thread[%u].", deviceId, threadIndex);
     258            1 :         AicpuSchedule::ThreadPool::Instance().PostSem(threadIndex);
     259            3 :         return;
     260              :     }
     261            6 :     aicpusd_info("Aicpu device[%u]:thread[%u] started.", deviceId, threadIndex);
     262            6 :     const auto ret = halEschedSubscribeEvent(deviceId, DEFAULT_GROUP_ID, threadIndex, EVENT_MASK);
     263            6 :     if (ret != static_cast<int32_t>(DRV_ERROR_NONE)) {
     264            1 :         aicpusd_err(
     265              :             "halEschedSubscribeEvent failed, deviceId[%u], groupId[%u], threadIndex[%u] eventBitmap[%llu].", deviceId,
     266              :             DEFAULT_GROUP_ID, threadIndex, EVENT_MASK);
     267            1 :         AicpuSchedule::ThreadPool::Instance().PostSem(threadIndex);
     268            1 :         return;
     269              :     }
     270            5 :     aicpusd_info(
     271              :         "halEschedSubscribeEvent success, deviceId[%u], groupId[%u], threadIndex[%u] eventBitmap[%llu].", deviceId,
     272              :         DEFAULT_GROUP_ID, threadIndex, EVENT_MASK);
     273            5 :     if (AicpuSchedule::ThreadPool::Instance().SetAffinity(static_cast<size_t>(threadIndex), deviceId) !=
     274              :         AICPU_SCHEDULE_OK) {
     275            0 :         AicpuSchedule::ThreadPool::Instance().PostSem(threadIndex);
     276            0 :         return;
     277              :     }
     278            5 :     if (AicpuSchedule::ThreadPool::Instance().SecureCompute(threadIndex) != AICPU_SCHEDULE_OK) {
     279            1 :         AicpuSchedule::ThreadPool::Instance().PostSem(threadIndex);
     280            1 :         return;
     281              :     }
     282            4 :     AicpuSchedule::ThreadPool::Instance().PostSem(threadIndex);
     283            4 :     (void)aicpu::SetAicpuThreadIndex(threadIndex);
     284            4 :     AicpuSchedule::AicpuEventManager::GetInstance().LoopProcess(threadIndex);
     285            4 :     aicpusd_info("Aicpu device[%u]:thread[%u] stopped.", deviceId, threadIndex);
     286              : }
     287              : 
     288            9 : uint32_t ThreadPool::GetNoAicpuCcpuPhysIndex(const size_t threadIndex) const
     289              : {
     290            9 :     const uint32_t ccpuNum = AicpuDrvManager::GetInstance().GetCcpuNum();
     291            9 :     if (ccpuNum == 0U) {
     292            4 :         aicpusd_err("no ctrlcpu core available for no-aicpu worker[%zu]", threadIndex);
     293            4 :         return INVALID_CPU_ID;
     294              :     }
     295            5 :     uint32_t ccpuLogIndex = 0U;
     296            5 :     if (static_cast<size_t>(ccpuNum) > threadIndex) {
     297            4 :         ccpuLogIndex = ccpuNum - 1U - static_cast<uint32_t>(threadIndex);
     298              :     }
     299            5 :     const uint32_t physIndex = AicpuDrvManager::GetInstance().GetCcpuPhysIndex(ccpuLogIndex);
     300            5 :     aicpusd_info(
     301              :         "no aicpu worker[%zu] bind to ctrlcpu logIndex[%u], physIndex[%u]", threadIndex, ccpuLogIndex, physIndex);
     302            5 :     return physIndex;
     303              : }
     304              : 
     305            4 : int32_t ThreadPool::WriteTidForAffinity(const size_t threadIndex)
     306              : {
     307            4 :     if (threadIndex >= threadStatus_.size()) {
     308            1 :         aicpusd_err("threadIndex[%zu], out of rank[0, %zu]", threadIndex, threadStatus_.size());
     309            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     310              :     }
     311              : 
     312            6 :     std::string command = "sudo /var/add_aicpu_tid_to_tasks.sh";
     313            3 :     std::string pathStr = "/var/add_aicpu_tid_to_tasks.sh";
     314            3 :     if (access(pathStr.c_str(), F_OK) != 0) {
     315            2 :         aicpusd_info("Not find add_aicpu_tid_to_tasks.sh.");
     316            2 :         return AICPU_SCHEDULE_OK;
     317              :     }
     318            1 :     command = command + " " + std::to_string(GetTid());
     319              : 
     320              :     // system() may fail due to  "No child processes".
     321              :     // if SIGCHLD is set to SIG_IGN, waitpid() may report ECHILD error because it cannot find the child process.
     322              :     // The reason is that the system() relies on a feature of the system, that is,
     323              :     // when the kernel initializes the process, the processing mode of SIGCHLD signal is SIG_IGN.
     324            1 :     const int32_t ret = AicpuSchedule::AicpuUtil::ExecuteCmd(command);
     325            1 :     if (ret != 0) {
     326            1 :         threadStatus_[threadIndex] = ThreadStatus::THREAD_EXIT;
     327            1 :         aicpusd_err(
     328              :             "write tid[%lu] to /sys/fs/cgroup/cpuset/AICPU/tasks failed, ret[%d], strerror[%s]", GetTid(), ret,
     329              :             strerror(errno));
     330            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     331              :     }
     332            0 :     return AICPU_SCHEDULE_OK;
     333            3 : }
     334              : 
     335            7 : int32_t ThreadPool::AddPidToTask(const size_t threadIndex)
     336              : {
     337            7 :     if (FeatureCtrl::IsBindPidByHal()) {
     338            2 :         if (&halBindCgroup != nullptr) {
     339            2 :             aicpusd_info("Bind pid by hal index:%zu.", threadIndex);
     340            2 :             const drvError_t drvRet = halBindCgroup(BIND_AICPU_CGROUP);
     341            2 :             if (drvRet != DRV_ERROR_NONE) {
     342            1 :                 aicpusd_err("halBindCgroup failed, ret[%d]", drvRet);
     343            1 :                 return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     344              :             }
     345            1 :             aicpusd_info("halBindCgroup success");
     346              :         } else {
     347            0 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     348              :         }
     349              :     } else {
     350            5 :         aicpusd_run_info("AddPidToTask by WriteTidForAffinity");
     351            5 :         auto ret = WriteTidForAffinity(threadIndex);
     352            5 :         if (ret != static_cast<int32_t>(AICPU_SCHEDULE_OK)) {
     353            1 :             aicpusd_err("WriteTidForAffinity failed, ret[%d]", ret);
     354            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     355              :         }
     356            4 :         aicpusd_info("WriteTidForAffinity success");
     357              :     }
     358            5 :     return AICPU_SCHEDULE_OK;
     359              : }
     360              : 
     361            7 : int32_t ThreadPool::SetAffinityByPm(const size_t threadIndex)
     362              : {
     363              :     const uint32_t physIndex =
     364            7 :         hasAicpu_ ? AicpuDrvManager::GetInstance().GetAicpuPhysIndex(static_cast<uint32_t>(threadIndex)) :
     365            3 :                     GetNoAicpuCcpuPhysIndex(threadIndex);
     366            7 :     if (physIndex == INVALID_CPU_ID) {
     367            1 :         threadStatus_[threadIndex] = ThreadStatus::THREAD_RUNNING;
     368            1 :         return AICPU_SCHEDULE_OK;
     369              :     }
     370            6 :     const pid_t tid = static_cast<pid_t>(GetTid());
     371              : 
     372            6 :     std::vector<uint32_t> coreAffinity;
     373            6 :     coreAffinity.push_back(physIndex);
     374            6 :     const auto ret = ProcMgrBindThread(tid, coreAffinity);
     375            6 :     if (ret != 0U) {
     376            1 :         threadStatus_[threadIndex] = ThreadStatus::THREAD_EXIT;
     377            1 :         aicpusd_err(
     378              :             "set affinity failed ret[%d], aicpu logical threadIndex[%zu], "
     379              :             "aicpu physical threadIndex[%u],tid[%u], device id[%u]",
     380              :             ret, threadIndex, physIndex, tid, AicpuDrvManager::GetInstance().GetDeviceId());
     381            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     382              :     }
     383            5 :     threadStatus_[threadIndex] = ThreadStatus::THREAD_RUNNING;
     384            5 :     aicpusd_info(
     385              :         "set affinity success, aicpu logical threadIndex[%zu], aicpu physical threadIndex[%u], device id[%u]",
     386              :         threadIndex, physIndex, AicpuDrvManager::GetInstance().GetDeviceId());
     387            5 :     return AICPU_SCHEDULE_OK;
     388            6 : }
     389              : 
     390            8 : int32_t ThreadPool::SetAffinityBySelf(const size_t threadIndex)
     391              : {
     392            8 :     if (hasAicpu_ && (AddPidToTask(threadIndex) != AICPU_SCHEDULE_OK)) {
     393            1 :         aicpusd_err("AddPidToTask failed");
     394            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     395              :     }
     396              : 
     397              :     cpu_set_t mask;
     398            7 :     CPU_ZERO(&mask);
     399              : 
     400            7 :     uint32_t physIndex = 0;
     401            7 :     uint32_t devNum = 0U;
     402            7 :     if (hasAicpu_ && (&halGetVdevNum != nullptr)) {
     403            4 :         int32_t result = halGetVdevNum(&devNum);
     404            4 :         if (result != 0) {
     405            1 :             aicpusd_err("custom halGetVdevNum, failed result[%d]", result);
     406            1 :             return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     407              :         }
     408              :     }
     409            6 :     if (!hasAicpu_) {
     410            3 :         physIndex = GetNoAicpuCcpuPhysIndex(threadIndex);
     411            3 :     } else if (devNum > 0U) {
     412            2 :         physIndex = AicpuDrvManager::GetInstance().GetAicpuPhysIndexInVfMode(
     413            1 :             static_cast<uint32_t>(threadIndex), AicpuDrvManager::GetInstance().GetDeviceId());
     414              :     } else {
     415            2 :         physIndex = AicpuDrvManager::GetInstance().GetAicpuPhysIndex(static_cast<uint32_t>(threadIndex));
     416              :     }
     417            6 :     aicpusd_info(
     418              :         "[custom]SetAffinityBySelf, threadIndex[%u], physIndex[%u], devNum[%u]", static_cast<uint32_t>(threadIndex),
     419              :         physIndex, devNum);
     420              : 
     421            6 :     if (physIndex == INVALID_CPU_ID) {
     422            3 :         threadStatus_[threadIndex] = ThreadStatus::THREAD_RUNNING;
     423            3 :         return AICPU_SCHEDULE_OK;
     424              :     }
     425              : 
     426              :     // cannot overflow, aicpu num < 65535, max [64=4*16]
     427            3 :     CPU_SET(static_cast<int32_t>(physIndex), &mask);
     428            3 :     const int32_t ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mask);
     429            3 :     if (ret != 0) {
     430            1 :         threadStatus_[threadIndex] = ThreadStatus::THREAD_EXIT;
     431            1 :         aicpusd_err(
     432              :             "set affinity failed ret[%d], aicpu logical threadIndex[%u], aicpu physical threadIndex[%u], "
     433              :             "device id[%u]",
     434              :             ret, threadIndex, physIndex, AicpuDrvManager::GetInstance().GetDeviceId());
     435            1 :         return AICPU_SCHEDULE_ERROR_INIT_FAILED;
     436              :     }
     437            2 :     threadStatus_[threadIndex] = ThreadStatus::THREAD_RUNNING;
     438            2 :     aicpusd_info(
     439              :         "set affinity success, aicpu logical threadIndex[%u], aicpu physical threadIndex[%u], device id[%u]",
     440              :         threadIndex, physIndex, AicpuDrvManager::GetInstance().GetDeviceId());
     441            2 :     return AICPU_SCHEDULE_OK;
     442              : }
     443              : 
     444            7 : int32_t ThreadPool::SetAffinity(const size_t threadIndex, const uint32_t deviceId)
     445              : {
     446              :     (void)deviceId;
     447            7 :     std::string cpuSetFlag;
     448            7 :     const char_t* const envValue = std::getenv("PROCMGR_AICPU_CPUSET");
     449            7 :     if (envValue != nullptr) {
     450           10 :         cpuSetFlag = std::string(envValue);
     451              :     }
     452              : 
     453            7 :     int32_t res = AICPU_SCHEDULE_OK;
     454            7 :     if (cpuSetFlag == "1") {
     455            3 :         res = SetAffinityByPm(threadIndex);
     456            3 :         aicpusd_run_info(
     457              :             "aicpu bind tid by pm, cpuSetFlag:[%s], threadIndex[%zu], deviceId[%u], res[%d].", cpuSetFlag.c_str(),
     458              :             threadIndex, AicpuDrvManager::GetInstance().GetDeviceId(), res);
     459              :     } else {
     460            4 :         res = SetAffinityBySelf(threadIndex);
     461            4 :         aicpusd_run_info(
     462              :             "aicpu bind tid by self, cpuSetFlag:[%s], threadIndex[%zu], deviceId[%u], res[%d].", cpuSetFlag.c_str(),
     463              :             threadIndex, AicpuDrvManager::GetInstance().GetDeviceId(), res);
     464              :     }
     465            7 :     return res;
     466            7 : }
     467              : 
     468            3 : void ThreadPool::PostSem(const uint32_t threadIndex) { (void)sem_post(&(sems_[static_cast<size_t>(threadIndex)])); }
     469              : } // namespace AicpuSchedule
        

Generated by: LCOV version 2.0-1