乐趣区

关于harmonyos:深度解读鸿蒙轻内核CPU占用率

摘要:CPUP(Central Processing Unit Percentage,CPU 占用率)分为零碎 CPU 占用率和工作 CPU 占用率。用户通过零碎级的 CPU 占用率,判断以后零碎负载是否超出设计规格。通过零碎中各个工作的 CPU 占用状况,判断各个工作的 CPU 占用率是否合乎设计的预期。

本文分享自华为云社区《鸿蒙轻内核 M 核源码剖析系列十五 CPU 使用率 CPUP(1)》,作者:zhushy。

CPUP(Central Processing Unit Percentage,CPU 占用率)分为零碎 CPU 占用率和工作 CPU 占用率。用户通过零碎级的 CPU 占用率,判断以后零碎负载是否超出设计规格。通过零碎中各个工作的 CPU 占用状况,判断各个工作的 CPU 占用率是否合乎设计的预期。

零碎 CPU 占用率是指周期时间内零碎的 CPU 占用率,用于示意零碎一段时间内的闲忙水平,也示意 CPU 的负载状况。零碎 CPU 占用率的无效示意范畴为 0~100,其精度(可通过配置调整)为百分比。100 示意零碎满负荷运行。

工作 CPU 占用率指单个工作的 CPU 占用率,用于示意单个工作在一段时间内的闲忙水平。工作 CPU 占用率的无效示意范畴为 0~100,其精度(可通过配置调整)为百分比。100 示意在一段时间内零碎始终在运行该工作。

本文通过剖析鸿蒙轻内核 CPUP 扩大模块的源码。本文中所波及的源码,以 OpenHarmony LiteOS- M 内核为例,均能够在开源站点 https://gitee.com/openharmony… 获取。

CPUP 模块用工作级记录的形式,在工作切换时,记录工作启动工夫,工作切出或者退出工夫,每次当工作退出时,零碎会累加整个工作的占用工夫。接下来,咱们看下 CPUP 模块反对的常见操作的源代码。

1、CPUP 构造体定义和罕用宏定义

1.1 CPUP 构造体定义

在文件 components\cpup\los_cpup.h 定义的 CPUP 管制块构造体为 OsCpupCB,构造体源代码如下,allTime 记录该工作自系统启动以来运行的 cycle 数,startTime 记录工作开始运行的工夫,historyTime[] 历史运行工夫数组的 10 个元素记录最近 10 秒中每一秒中每个工作自系统启动以来运行的 cycle 数,其余构造体成员的解释见正文局部。

typedef struct {
    UINT32 cpupID;                                        /**< 工作编号 */
    UINT16 status;                                        /**< 工作状态 */
    UINT64 allTime;                                       /**< 总共运行的工夫 */
    UINT64 startTime;                                     /**< 工作开始工夫 */
    UINT64 historyTime[OS_CPUP_HISTORY_RECORD_NUM];       /**< 历史运行工夫数组,其中 OS_CPUP_HISTORY_RECORD_NUM 为 10 */
} OsCpupCB;

另外,还定义了一个构造体 CPUP_INFO_S,如下:

typedef struct tagCpupInfo {
    UINT16 usStatus;            /**< 保留以后运行工作状态           */
    UINT32 uwUsage;             /**< 应用状况,值范畴为 [0,1000].   */
} CPUP_INFO_S;

1.2 CPUP 枚举定义

CPUP 头文件 components\cpup\los_cpup.h 中还提供了相干的枚举,CPUP 占用率类型 CPUP_TYPE_E,及 CPUP 统计工夫距离模式 CPUP_MODE_E。

typedef enum {
    SYS_CPU_USAGE = 0,   /* 零碎 CPUP */
    TASK_CPU_USAGE,      /* 工作 CPUP */
} CPUP_TYPE_E;

typedef enum {
    CPUP_IN_10S = 0,     /* CPUP 统计周期 10s */
    CPUP_IN_1S,          /* CPUP 统计周期 1s */
    CPUP_LESS_THAN_1S,   /* CPUP 统计周期 <1s */
} CPUP_MODE_E;

2、CPUP 初始化

CPUP 默认敞开,用户能够通过宏 LOSCFG_BASE_CORE_CPUP 进行开启。开启 CPUP 的状况下,在系统启动时,在 kernel\src\los_init.c 中调用 OsCpupInit() 进行 CPUP 模块初始化。上面,咱们剖析下 CPUP 初始化的代码。

⑴处计算 CPUP 构造体池须要的内存大小,而后为 CPUP 申请内存,如果申请失败,则返回谬误。⑵处初始化胜利后,设置初始化标记 g_cpupInitFlg。

LITE_OS_SEC_TEXT_INIT UINT32 OsCpupInit()
{
    UINT32 size;

    size = g_taskMaxNum * sizeof(OsCpupCB);
⑴  g_cpup = (OsCpupCB *)LOS_MemAlloc(m_aucSysMem0, size);

    if (g_cpup == NULL) {return LOS_ERRNO_CPUP_NO_MEMORY;}

    (VOID)memset_s(g_cpup, size, 0, size);
⑵  g_cpupInitFlg = 1;

    return LOS_OK;
}

3、CPUP 罕用操作

3.1 CPUP 外部接口

咱们先剖析下外部接口,这些接口会被 LOS_结尾的内部接口调用。

3.1.1 OsTskCycleStart 记录工作开始工夫

CPUP 模块对外接口执行前期会调用该外部接口,设置下一个工作的开始运行工夫。

⑴处先判断 CPUP 是否曾经初始化,如果没有初始化过,退出该函数的执行。⑵处获取新工作的工作编号。⑶处设置该工作对应的 CPUP 构造体的工作编号和开始工夫。

LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleStart(VOID)
{
    UINT32 taskID;

⑴  if (g_cpupInitFlg == 0) {return;}

⑵  taskID = g_losTask.newTask->taskID;
⑶  g_cpup[taskID].cpupID = taskID;
    g_cpup[taskID].startTime = LOS_SysCycleGet();

    return;
}

3.1.2 OsTskCycleEnd 记录工作完结工夫

CPUP 模块对外接口执行后期会调用该外部接口,获取当前任务的完结工夫,并统计当前任务的运行总工夫。

⑴处先判断 CPUP 是否曾经初始化,如果没有初始化过,退出该函数的执行。⑵处获取当前任务的工作编号。⑶处如果该工作的开始工夫为 0,退出函数执行。⑷处获取零碎的以后 cycle 数。⑸如果获取的小于工作 CPUP 开始工夫,则把获取的 cycle 数加上每个 tick 的 cycle 数。⑹处计算当前任务的运行的总工夫,而后把开始工夫置 0。

LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleEnd(VOID)
{
    UINT32 taskID;
    UINT64 cpuCycle;

⑴  if (g_cpupInitFlg == 0) {return;}

⑵  taskID = g_losTask.runTask->taskID;

⑶  if (g_cpup[taskID].startTime == 0) {return;}

⑷  cpuCycle = LOS_SysCycleGet();

⑸  if (cpuCycle < g_cpup[taskID].startTime) {cpuCycle += g_cyclesPerTick;}

⑹  g_cpup[taskID].allTime += (cpuCycle - g_cpup[taskID].startTime);
    g_cpup[taskID].startTime = 0;

    return;
}

3.1.3 OsTskCycleEndStart 工作切换时更新工作历史运行工夫

该函数在任务调度切换时会被执行,计算以后运行工作的运行总工夫,记录新工作的开始工夫,并更新所有工作的历史运行工夫。函数的示意图如下:

⑴处先判断 CPUP 是否曾经初始化,如果没有初始化过,退出该函数的执行。⑵处获取当前任务的工作编号,而后获取零碎的以后 cycle 数。⑶处如果当前任务的开始工夫不为 0,则计算当前任务的运行的总工夫,而后把开始工夫置 0。

⑷处获取新工作的工作编号,⑸处设置该工作对应的 CPUP 构造体的工作编号和开始工夫。⑹处如果记录距离大于零碎时钟(即每秒的 cycle 数),更新上次记录时间。这意味着每个工作的 historyTime[] 数组中的每个元素示意 1s 多的周期内该工作的运行 cycle 数量,并不是十分准确的。而后执行⑺,记录每一个工作对应的 CPUP 的历史运行工夫。⑻处更新历史运行工夫数组的以后索引值。

LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleEndStart(VOID)
{
    UINT32 taskID;
    UINT64 cpuCycle;
    UINT16 loopNum;

⑴  if (g_cpupInitFlg == 0) {return;}

⑵  taskID = g_losTask.runTask->taskID;
    cpuCycle = LOS_SysCycleGet();

⑶  if (g_cpup[taskID].startTime != 0) {if (cpuCycle < g_cpup[taskID].startTime) {cpuCycle += g_cyclesPerTick;}

        g_cpup[taskID].allTime += (cpuCycle - g_cpup[taskID].startTime);
        g_cpup[taskID].startTime = 0;
    }

⑷  taskID = g_losTask.newTask->taskID;
⑸  g_cpup[taskID].cpupID = taskID;
    g_cpup[taskID].startTime = cpuCycle;

⑹  if ((cpuCycle - g_lastRecordTime) > OS_CPUP_RECORD_PERIOD) {
        g_lastRecordTime = cpuCycle;

        for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {⑺          g_cpup[loopNum].historyTime[g_hisPos] = g_cpup[loopNum].allTime;
        }

⑻      if (g_hisPos == (OS_CPUP_HISTORY_RECORD_NUM - 1)) {g_hisPos = 0;} else {g_hisPos++;}
    }

    return;
}

3.1.4 OsGetPrePos 获取历史运行工夫数组上一索引地位

代码比较简单,如果传入参数 curPos 为 0,则返回数组的最初一个索引地位 OS_CPUP_HISTORY_RECORD_NUM – 1。否则返回减 1 返回。

LITE_OS_SEC_TEXT_MINOR static inline UINT16 OsGetPrePos(UINT16 curPos)
{return (curPos == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : (curPos - 1);
}

3.1.5 OsGetPositions 获取历史运行工夫数组的以后及上一索引地位

依据 CPUP 统计工夫距离模式,获取历史运行工夫数组的以后及上一索引地位。

⑴处获取历史运行工夫数组的以后索引地位,⑵如果工夫距离模式为 1 秒,以后索引 curPos 地位为 g_hisPos 的上一索引地位,上一索引地位 prePos 须要持续上前一位。⑶如果工夫距离模式小于 1 秒,以后索引 curPos 地位为 g_hisPos 的上一索引地位,上一索引地位 prePos 为 0。如果工夫距离模式是 10 秒,以后索引 curPos 地位就等于 g_hisPos,上一索引地位 prePos 为 0。⑷处设置传出参数。

LITE_OS_SEC_TEXT_MINOR static VOID OsGetPositions(UINT16 mode, UINT16* curPosAddr, UINT16* prePosAddr)
{
    UINT16 curPos;
    UINT16 prePos = 0;

⑴  curPos = g_hisPos;

⑵  if (mode == CPUP_IN_1S) {curPos = OsGetPrePos(curPos);
        prePos = OsGetPrePos(curPos);
⑶  } else if (mode == CPUP_LESS_THAN_1S) {curPos = OsGetPrePos(curPos);
    }

⑷  *curPosAddr = curPos;
    *prePosAddr = prePos;
}

3.2 CPUP 对外接口

咱们先剖析下内部接口,接口阐明如下:

3.2.1 LOS_SysCpuUsage

该函数会统计以后零碎 CPU 占用率,返回值基于千分率计算,取值范畴为 [0,1000]。函数的示意图如下:

⑴处先判断 CPUP 是否曾经初始化,如果没有初始化过,返回错误码。⑵处调用函数 OsTskCycleEnd() 获取当前任务的完结工夫,并计算出运行总工夫。⑶处统计所有工作的运行总工夫,如果总工夫不为 0,执行⑷计算出零碎的工作 CPU 占用率。⑸处调用函数 OsTskCycleStart() 设置新工作的 CPUP 统计的开始工夫。

LITE_OS_SEC_TEXT_MINOR UINT32 LOS_SysCpuUsage(VOID)
{
    UINT64  cpuCycleAll = 0;
    UINT32  cpupRet = 0;
    UINT16  loopNum;
    UINT32 intSave;

⑴  if (g_cpupInitFlg == 0) {return LOS_ERRNO_CPUP_NO_INIT;}

    intSave = LOS_IntLock();
⑵  OsTskCycleEnd();

⑶  for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {cpuCycleAll += g_cpup[loopNum].allTime;
    }

⑷  if (cpuCycleAll) {cpupRet = LOS_CPUP_PRECISION -  (UINT32)((LOS_CPUP_PRECISION *
            g_cpup[g_idleTaskID].allTime) / cpuCycleAll);
    }

⑸  OsTskCycleStart();
    LOS_IntRestore(intSave);

    return cpupRet;
}

3.2.2 LOS_HistorySysCpuUsage

该函数获取零碎历史 CPU 占用率,对于历史 CPU 占用率,须要传入工夫距离模式参数,反对 10 秒、1 秒、小于 1 秒三种。

⑴处先判断 CPUP 是否曾经初始化,如果没有初始化过,返回错误码。⑵处调用函数 OsTskCycleEnd() 获取当前任务的完结工夫,并计算出运行总工夫。⑶处调用函数 OsGetPositions() 计算出历史运行工夫数组索引地位。⑷处计算出各个工作的周期内运行总工夫,如果工夫距离模式为 1 秒,取值两个历史运行工夫之差,即为 1 秒内工作的运行工夫数。对于工夫距离模式为 10 秒,historyTime[curPos] 示意 10 秒前的自系统启动以来的工作运行的工夫数,计算出来的差值即为 10 秒内工作的运行工夫数。对于工夫距离模式为小于 1 秒,historyTime[curPos] 示意上一秒前的自系统启动以来的工作运行的工夫数,计算出来的差值即为小于 1 秒内工作的运行工夫数。⑸处计算闲暇工作周期内运行总工夫。⑹处如果总工夫不为 0,计算出零碎的工作历史 CPU 占用率。最初,调用函数 OsTskCycleStart() 设置新工作的 CPUP 统计的开始工夫。能够参考示意图进行了解:

LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistorySysCpuUsage(UINT16 mode)
{
    UINT64  cpuCycleAll = 0;
    UINT64  idleCycleAll = 0;
    UINT32  cpupRet = 0;
    UINT16  loopNum;
    UINT16  curPos;
    UINT16  prePos = 0;
    UINT32 intSave;

⑴  if (g_cpupInitFlg == 0) {return LOS_ERRNO_CPUP_NO_INIT;}

    // get end time of current task
    intSave = LOS_IntLock();
⑵  OsTskCycleEnd();

⑶  OsGetPositions(mode, &curPos, &prePos);

    for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {⑷      if (mode == CPUP_IN_1S) {cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
        } else {cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
        }
    }

⑸  if (mode == CPUP_IN_1S) {idleCycleAll += g_cpup[g_idleTaskID].historyTime[curPos] -
                           g_cpup[g_idleTaskID].historyTime[prePos];
    } else {idleCycleAll += g_cpup[g_idleTaskID].allTime - g_cpup[g_idleTaskID].historyTime[curPos];
    }

⑹  if (cpuCycleAll) {cpupRet = (LOS_CPUP_PRECISION -  (UINT32)((LOS_CPUP_PRECISION * idleCycleAll) / cpuCycleAll));
    }

    OsTskCycleStart();
    LOS_IntRestore(intSave);

    return cpupRet;
}

3.2.3 LOS_TaskCpuUsage

该函数会统计指定工作的 CPU 占用率,和函数 LOS_SysCpuUsage() 代码类似度高,能够参考上文对该函数的解说。

LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuUsage(UINT32 taskID)
{
    UINT64  cpuCycleAll = 0;
    UINT16  loopNum;
    UINT32 intSave;
    UINT32  cpupRet = 0;

    if (g_cpupInitFlg == 0) {return LOS_ERRNO_CPUP_NO_INIT;}
    if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) {return LOS_ERRNO_CPUP_TSK_ID_INVALID;}
    if (g_cpup[taskID].cpupID != taskID) {return LOS_ERRNO_CPUP_THREAD_NO_CREATED;}
    if ((g_cpup[taskID].status & OS_TASK_STATUS_UNUSED) || (g_cpup[taskID].status == 0)) {return LOS_ERRNO_CPUP_THREAD_NO_CREATED;}
    intSave = LOS_IntLock();
    OsTskCycleEnd();

    for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || (g_cpup[loopNum].status == 0)) {continue;}
        cpuCycleAll += g_cpup[loopNum].allTime;
    }

    if (cpuCycleAll) {cpupRet = (UINT32)((LOS_CPUP_PRECISION * g_cpup[taskID].allTime) / cpuCycleAll);
    }

    OsTskCycleStart();
    LOS_IntRestore(intSave);

    return cpupRet;
}

3.2.4 LOS_HistoryTaskCpuUsage

该函数获取指定工作的历史 CPU 占用率,和函数 LOS_HistorySysCpuUsage() 代码类似度高,能够参考上文对该函数的解说。

LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskID, UINT16 mode)
{
    UINT64  cpuCycleAll = 0;
    UINT64  cpuCycleCurTsk = 0;
    UINT16  loopNum, curPos;
    UINT16  prePos = 0;
    UINT32 intSave;
    UINT32  cpupRet = 0;

   if (g_cpupInitFlg == 0) {return LOS_ERRNO_CPUP_NO_INIT;}
    if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) {return LOS_ERRNO_CPUP_TSK_ID_INVALID;}
    if (g_cpup[taskID].cpupID != taskID) {return LOS_ERRNO_CPUP_THREAD_NO_CREATED;}
    if ((g_cpup[taskID].status & OS_TASK_STATUS_UNUSED) || (g_cpup[taskID].status == 0)) {return LOS_ERRNO_CPUP_THREAD_NO_CREATED;}
    intSave = LOS_IntLock();
    OsTskCycleEnd();

    OsGetPositions(mode, &curPos, &prePos);

    for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || (g_cpup[loopNum].status == 0)) {continue;}

        if (mode == CPUP_IN_1S) {cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
        } else {cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
        }
    }

    if (mode == CPUP_IN_1S) {cpuCycleCurTsk += g_cpup[taskID].historyTime[curPos] - g_cpup[taskID].historyTime[prePos];
    } else {cpuCycleCurTsk += g_cpup[taskID].allTime - g_cpup[taskID].historyTime[curPos];
    }
    if (cpuCycleAll) {cpupRet = (UINT32)((LOS_CPUP_PRECISION * cpuCycleCurTsk) / cpuCycleAll);
    }

    OsTskCycleStart();
    LOS_IntRestore(intSave);

    return cpupRet;
}

3.2.5 LOS_AllTaskCpuUsage

该函数获取全副工作的 CPU 占用率,获取的 CPU 占用率信息保留在传出参数构造体 CPUP_INFO_S cpupInfo 指向的内存区域里,须要留神这个内存区域的大小须要等于 sizeof(CPUP_INFO_S) g_taskMaxNum。还须要传入工夫距离模式参数,反对 10 秒、1 秒、小于 1 秒三种。

⑴处先判断 CPUP 是否曾经初始化,如果没有初始化过,返回错误码。传出参数 cpupInfo 指针不能为空,否则返回错误码。⑵处调用函数 OsTskCycleEnd() 获取当前任务的完结工夫,并计算出运行总工夫。⑶处调用函数 OsGetPositions() 计算出历史运行工夫数组索引地位。⑷处计算出各个工作的周期内运行总工夫,如果工夫距离模式为 1 秒,取值两个历史运行工夫之差,否则取值 XX。⑸处设置每一个工作的状态,而后计算出每一个工作的 CPU 占用率。最初,调用函数 OsTskCycleStart() 设置新工作的 CPUP 统计的开始工夫。

LITE_OS_SEC_TEXT_MINOR UINT32 LOS_AllTaskCpuUsage(CPUP_INFO_S *cpupInfo, UINT16 mode)
{
    UINT16  loopNum;
    UINT16  curPos;
    UINT16  prePos = 0;
    UINT32 intSave;
    UINT64  cpuCycleAll = 0;
    UINT64  cpuCycleCurTsk = 0;

⑴  if (g_cpupInitFlg == 0) {return  LOS_ERRNO_CPUP_NO_INIT;}

    if (cpupInfo == NULL) {return LOS_ERRNO_CPUP_TASK_PTR_NULL;}

    intSave = LOS_IntLock();
⑵  OsTskCycleEnd();

⑶  OsGetPositions(mode, &curPos, &prePos);

    for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) ||
            (g_cpup[loopNum].status == 0)) {continue;}

        if (mode == CPUP_IN_1S) {cpuCycleAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
        } else {cpuCycleAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
        }
    }

⑷  for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) ||
            (g_cpup[loopNum].status == 0)) {continue;}

        if (mode == CPUP_IN_1S) {cpuCycleCurTsk += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
        } else {cpuCycleCurTsk += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
        }
⑸      cpupInfo[loopNum].usStatus = g_cpup[loopNum].status;
        if (cpuCycleAll) {cpupInfo[loopNum].uwUsage = (UINT32)((LOS_CPUP_PRECISION * cpuCycleCurTsk) / cpuCycleAll);
        }

        cpuCycleCurTsk = 0;
    }

    OsTskCycleStart();
    LOS_IntRestore(intSave);

    return LOS_OK;
}

3.2.6 LOS_CpupUsageMonitor

该函数获取历史 CPU 占用率并打印输出,传入参数有三个:CPU 占用率类型,CPUP 工夫周期模式,指定的工作编号。对于工作 CPU 占用率,才须要指定无效的工作编号。

⑴处解决 CPU 占用率类型为零碎 CPU 占用率的状况,⑵处打印应用的 CPUP 工夫周期模式。⑶处通过调用函数 LOS_HistorySysCpuUsage() 获取零碎历史 CPU 占用率,而后执行⑷打印输出 CPU 占用率后果,输入后果范畴为 [0,100]。

⑸处解决 CPU 占用率类型为指定工作 CPU 占用率的状况,首先判断下工作编号的有效性,校验工作是否创立等。⑹处打印应用的 CPUP 工夫周期模式。⑺处通过调用函数 LOS_HistoryTaskCpuUsage() 获取指定工作的历史 CPU 占用率,而后执行⑻打印输出 CPU 占用率后果,输入后果范畴为 [0,100]。

LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E mode, UINT32 taskID)
{
    UINT32 ret;
    LosTaskCB *taskCB = NULL;

    switch (type) {
⑴      case SYS_CPU_USAGE:
⑵          if (mode == CPUP_IN_10S) {PRINTK("\nSysCpuUsage in 10s:");
            } else if (mode == CPUP_IN_1S) {PRINTK("\nSysCpuUsage in 1s:");
            } else {PRINTK("\nSysCpuUsage in <1s:");
            }
⑶          ret = LOS_HistorySysCpuUsage(mode);
⑷          PRINTK("%d.%d", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
            break;

⑸      case TASK_CPU_USAGE:
            if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) {PRINT_ERR("\nThe taskid is invalid.\n");
                return OS_ERROR;
            }
            taskCB = OS_TCB_FROM_TID(taskID);
            if ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED)) {PRINT_ERR("\nThe taskid is invalid.\n");
                return OS_ERROR;
            }
⑹          if (mode == CPUP_IN_10S) {PRINTK("\nCPUusage of taskID %d in 10s:", taskID);
            } else if (mode == CPUP_IN_1S) {PRINTK("\nCPUusage of taskID %d in 1s:", taskID);
            } else {PRINTK("\nCPUusage of taskID %d in <1s:", taskID);
            }
⑺          ret = LOS_HistoryTaskCpuUsage(taskID, mode);
⑻          PRINTK("%u.%u", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
            break;

        default:
            PRINT_ERR("\nThe type is invalid.\n");
            return OS_ERROR;
    }

    return LOS_OK;
}

小结

本文率领大家一起分析了鸿蒙轻内核的 CPUP 扩大模块的源代码。感激浏览,如有任何问题、倡议,都能够博客下留言给我,谢谢。

点击关注,第一工夫理解华为云陈腐技术~

退出移动版