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

Generated by: LCOV version 2.0-1