LCOV - code coverage report
Current view: top level - aicpu_cust_schedule/common - aicpusd_util.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.8 % 82 72
Test Date: 2026-07-28 10:54:05 Functions: 100.0 % 12 12

            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              : 
      11              : #ifndef COMMON_AICPUSD_UTIL_H
      12              : #define COMMON_AICPUSD_UTIL_H
      13              : 
      14              : #include <signal.h>
      15              : #include <sys/wait.h>
      16              : #include <functional>
      17              : #include <string.h>
      18              : #include "aicpusd_status.h"
      19              : #include "aicpusd_info.h"
      20              : #include "profiling_adp.h"
      21              : #include "aicpu_context.h"
      22              : #include "aicpusd_drv_manager.h"
      23              : 
      24              : namespace AicpuSchedule {
      25              : constexpr int32_t MAX_ENV_CHAR_NUM = 1024;
      26              : const std::string ENV_NAME_PROCMGR_AICPU_CPUSET = "PROCMGR_AICPU_CPUSET";
      27              : 
      28           22 : inline uint64_t TickInterval2Microsecond(const uint64_t tickStart,
      29              :                                          const uint64_t tickEnd,
      30              :                                          const uint64_t tickFreq)
      31              : {
      32           22 :     if ((tickFreq == 0UL) || (tickEnd <= tickStart)) {
      33           19 :         return 0UL;
      34              :     }
      35              :     // tickFreq is record by second, to microsecond need multiply 1000000
      36            3 :     return ((tickEnd - tickStart) * 1000000UL) / tickFreq;
      37              : }
      38              : 
      39              : class AicpuUtil {
      40              : public:
      41            2 :     static int32_t ExecuteCmd(const std::string &cmd)
      42              :     {
      43              :         /**
      44              :          * system() may fail due to  "No child processes".
      45              :          * if SIGCHLD is set to SIG_IGN, waitpid() may report ECHILD error because it cannot find the child process.
      46              :          * The reason is that the system() relies on a feature of the system, that is,
      47              :          * when the kernel initializes the process, the processing mode of SIGCHLD signal is SIG_IGN.
      48              :          */
      49            2 :         if (cmd.empty()) {
      50            1 :             return -1;
      51              :         }
      52              : 
      53            1 :         const sighandler_t oldHandler = signal(SIGCHLD, SIG_DFL);
      54            1 :         int32_t status = 0;
      55            1 :         int32_t pid = 0;
      56            1 :         if ((pid = vfork()) < 0) {
      57            1 :             status = -1;
      58            0 :         } else if (pid == 0) {
      59            0 :             (void)execl("/bin/sh", "sh", "-c", cmd.c_str(), nullptr);
      60            0 :             constexpr int32_t executeCmdErr = 127;
      61            0 :             _exit(executeCmdErr);
      62              :         } else {
      63            0 :             while (waitpid(pid, &status, 0) < 0) {
      64            0 :                 if (errno != EINTR) {
      65            0 :                     status = -1;
      66            0 :                     break;
      67              :                 }
      68              :             }
      69              :         }
      70            1 :         (void)signal(SIGCHLD, oldHandler);
      71            1 :         return status;
      72              :     }
      73           11 :     static void SetProfData(const std::shared_ptr<aicpu::ProfMessage> profMsg,
      74              :                             const aicpu::aicpuProfContext_t &aicpuProfCtx,
      75              :                             const uint32_t threadIndex,
      76              :                             const uint64_t streamId,
      77              :                             const uint64_t taskId)
      78              :     {
      79           11 :         if (profMsg == nullptr) {
      80            0 :             return;
      81              :         }
      82              : 
      83           11 :         const uint64_t tickAfterRun = aicpu::GetSystemTick();
      84           11 :         const uint64_t tickFreq = aicpu::GetSystemTickFreq();
      85           11 :         const uint64_t dispatchTime = TickInterval2Microsecond(aicpuProfCtx.drvSubmitTick,
      86           11 :                                                                aicpuProfCtx.tickBeforeRun,
      87              :                                                                tickFreq);
      88           11 :         const uint64_t totalTime = TickInterval2Microsecond(aicpuProfCtx.drvSubmitTick,
      89              :                                                             tickAfterRun,
      90              :                                                             tickFreq);
      91              : 
      92              :         (void)profMsg->SetAicpuMagicNumber(static_cast<uint16_t>(MSPROF_DATA_HEAD_MAGIC_NUM))
      93              :             ->SetAicpuDataTag(static_cast<uint16_t>(MSPROF_AICPU_DATA_TAG))
      94              :             ->SetStreamId(static_cast<uint16_t>(streamId))
      95              :             ->SetTaskId(static_cast<uint16_t>(taskId))
      96              :             ->SetThreadId(threadIndex)
      97           11 :             ->SetDeviceId(AicpuDrvManager::GetInstance().GetDeviceId())
      98           11 :             ->SetKernelType(aicpuProfCtx.kernelType)
      99           11 :             ->SetSubmitTick(aicpuProfCtx.drvSubmitTick)
     100           11 :             ->SetScheduleTick(aicpuProfCtx.drvSchedTick)
     101           11 :             ->SetTickBeforeRun(aicpuProfCtx.tickBeforeRun)
     102              :             ->SetTickAfterRun(tickAfterRun)
     103              :             ->SetDispatchTime(static_cast<uint32_t>(dispatchTime))
     104              :             ->SetTotalTime(static_cast<uint32_t>(totalTime))
     105           22 :             ->SetVersion(aicpu::AICPU_PROF_VERSION);
     106              : 
     107           11 :         (void)aicpu::SetProfHandle(nullptr);
     108              :     }
     109              :     /**
     110              :      * @ingroup AicpusdUtil
     111              :      * @brief it is used to uniformly normalized error code.
     112              :      * @param [in] errCode: original error code.
     113              :      * @return uniformly normalized error code
     114              :      */
     115           10 :     static int32_t TransformInnerErrCode(const int32_t errCode)
     116              :     {
     117           10 :         return ((errCode > AICPU_SCHEDULE_ERROR_RESERVED) || (errCode < AICPU_SCHEDULE_OK)) ?
     118           10 :             AICPU_SCHEDULE_ERROR_INNER_ERROR : errCode;
     119              :     }
     120              : 
     121              :     /**
     122              :      * @ingroup AicpuUtil
     123              :      * @brief it is used to check exception by read FPSR Register.
     124              :      * @param [out] result : exception type.
     125              :      * @return has any exception, true if has
     126              :      */
     127              :     static bool CheckOverflow(int32_t &result)
     128              :     {
     129              : #if (defined __ARM_ARCH) || (defined PLATFORM_AARCH64)
     130              :         int64_t regContent;
     131              :         __asm volatile(
     132              :           "MRS %0, FPSR"
     133              :           : "=r" (regContent)
     134              :           :
     135              :           : "memory"
     136              :         );
     137              :         aicpusd_info("Custom Scheduler Read FPSR:[%d].", regContent);
     138              :         if ((regContent & (1 << 3)) != 0) { // UFC(3)
     139              :             result = AICPU_SCHEDULE_ERROR_UNDERFLOW;
     140              :             return true;
     141              :         } else if ((regContent & (1 << 2)) != 0) { // OFC(2)
     142              :             result = AICPU_SCHEDULE_ERROR_OVERFLOW;
     143              :             return true;
     144              :         } else if ((regContent & (1 << 1)) != 0) { // DZC(1)
     145              :             result = AICPU_SCHEDULE_ERROR_DIVISIONZERO;
     146              :             return true;
     147              :         }
     148              : #endif
     149              :         return false;
     150              :     }
     151              : 
     152              :     /**
     153              :      * @ingroup AicpuUtil
     154              :      * @brief it is used to reset FPSR Register.
     155              :      */
     156            1 :     static void ResetFpsr()
     157              :     {
     158              : #if (defined __ARM_ARCH) || (defined PLATFORM_AARCH64)
     159              :         aicpusd_info("Custom Scheduler Reset FPSR.");
     160              :         __asm volatile(
     161              :               "BIC x0, x0, #0xffffffff \n\t"
     162              :               "MSR FPSR, x0":::"x0"
     163              :         );
     164              : #endif
     165            1 :     }
     166              : 
     167           67 :     static bool TransStrToUint(const std::string &para, uint32_t &value)
     168              :     {
     169              :         try {
     170           67 :             value = std::stoul(para);
     171            3 :         } catch (...) {
     172            3 :             return false;
     173            3 :         }
     174              : 
     175           64 :         return true;
     176              :     }
     177              : 
     178          206 :     static bool TransStrToInt(const std::string &para, int32_t &value)
     179              :     {
     180              :         try {
     181          206 :             value = std::stoi(para);
     182            9 :         } catch (...) {
     183            9 :             return false;
     184            9 :         }
     185              : 
     186          197 :         return true;
     187              :     }
     188              : 
     189           13 :     static bool GetEnvVal(const std::string &env, std::string &val)
     190              :     {
     191           13 :         if (env.empty()) {
     192            0 :             return false;
     193              :         }
     194              : 
     195           13 :         const char *const tmpVal = std::getenv(env.c_str());
     196           13 :         if ((tmpVal == nullptr) || (strnlen(tmpVal, MAX_ENV_CHAR_NUM) >= MAX_ENV_CHAR_NUM)) {
     197            2 :             val = "";
     198            2 :             return false;
     199              :         }
     200              : 
     201           11 :         val = tmpVal;
     202           11 :         return true;
     203              :     }
     204              : 
     205              :     /**
     206              :      * @ingroup AicpuUtil
     207              :      * @brief Is env value is same as expected value
     208              :      * @param [in] env : env name
     209              :      * @param [in] expectVal : expected env value
     210              :      * @return bool: true, if env val is same as expected value; otherwise, false
     211              :      */
     212           13 :     static bool IsEnvValEqual(const std::string &env, const std::string &expectVal)
     213              :     {
     214           13 :         std::string getedEnvVal;
     215           13 :         const bool ret = GetEnvVal(env, getedEnvVal);
     216           13 :         if (!ret) {
     217            2 :             return false;
     218              :         }
     219              : 
     220           11 :         return (getedEnvVal == expectVal) ? true : false;
     221           13 :     }
     222              : 
     223            9 :     static void GetProfilingInfo(uint32_t flag, ProfilingMode &profilingMode, bool &kernelFlag)
     224              :     {
     225              :         // set or unset mode
     226            9 :         const bool isStart = (flag & (1U << aicpu::PROFILING_FEATURE_SWITCH)) > 0U;
     227              :         // if set or unset kernel profiling mode
     228            9 :         kernelFlag = (flag & (1U << aicpu::PROFILING_FEATURE_KERNEL_MODE)) > 0U;
     229            9 :         if (isStart) {
     230            9 :             profilingMode = PROFILING_OPEN;
     231              :         }
     232            9 :     }
     233              : 
     234              : private:
     235              :     AicpuUtil() = default;
     236              :     ~AicpuUtil() = default;
     237              : 
     238              :     AicpuUtil(AicpuUtil const&) = delete;
     239              :     AicpuUtil& operator=(AicpuUtil const&) = delete;
     240              :     AicpuUtil(AicpuUtil&&) = delete;
     241              :     AicpuUtil& operator=(AicpuUtil&&) = delete;
     242              : };
     243              : 
     244              : /**
     245              :  * @ingroup aicpu_cust_schedule
     246              :  * @brief Pointer move
     247              :  * @param [in] T : type T, sizeof(T) mast be 1
     248              :  * @param [in] ptr : The pointer
     249              :  * @param [in] offset : Move offset
     250              :  * @return The pointer after move offset
     251              :  */
     252              : template <typename T, typename = typename std::enable_if<sizeof(T) == 1UL, void>::type>
     253              : inline T *MovePtrByOffset(const T * const ptr, const uint64_t offset)
     254              : {
     255              :     return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(ptr) + offset);
     256              : }
     257              : 
     258              : class ScopeGuard {
     259              : public:
     260            3 :     explicit ScopeGuard(const std::function<void()> exitScope)
     261            3 :         : exitScope_(exitScope)
     262            3 :     {}
     263              : 
     264            3 :     ~ScopeGuard()
     265              :     {
     266            3 :         exitScope_();
     267            3 :     }
     268              : 
     269              : private:
     270              :     ScopeGuard(ScopeGuard const&) = delete;
     271              :     ScopeGuard& operator=(ScopeGuard const&) = delete;
     272              :     ScopeGuard(ScopeGuard&&) = delete;
     273              :     ScopeGuard& operator=(ScopeGuard&&) = delete;
     274              : 
     275              : private:
     276              :     std::function<void()> exitScope_;
     277              : };
     278              : } // namespace aicpu
     279              : 
     280              : #endif // COMMON_AICPUSD_UTIL_H
        

Generated by: LCOV version 2.0-1