154568cb3Sopenharmony_ci/* 254568cb3Sopenharmony_ci * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved. 354568cb3Sopenharmony_ci * 454568cb3Sopenharmony_ci * UniProton is licensed under Mulan PSL v2. 554568cb3Sopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2. 654568cb3Sopenharmony_ci * You may obtain a copy of Mulan PSL v2 at: 754568cb3Sopenharmony_ci * http://license.coscl.org.cn/MulanPSL2 854568cb3Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 954568cb3Sopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 1054568cb3Sopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 1154568cb3Sopenharmony_ci * See the Mulan PSL v2 for more details. 1254568cb3Sopenharmony_ci * Create: 2009-12-22 1354568cb3Sopenharmony_ci * Description: 线程级CPU占用率模块的C文件 1454568cb3Sopenharmony_ci */ 1554568cb3Sopenharmony_ci#include "prt_cpup_thread_internal.h" 1654568cb3Sopenharmony_ci 1754568cb3Sopenharmony_ci/* 1854568cb3Sopenharmony_ci * 描述:任务切入,中断结束时,统计任务的startTime 1954568cb3Sopenharmony_ci */ 2054568cb3Sopenharmony_ciOS_SEC_L2_TEXT void OsNowTskCycleStart(void) 2154568cb3Sopenharmony_ci{ 2254568cb3Sopenharmony_ci uintptr_t intSave; 2354568cb3Sopenharmony_ci 2454568cb3Sopenharmony_ci intSave = OsIntLock(); 2554568cb3Sopenharmony_ci 2654568cb3Sopenharmony_ci /* 处理硬中断、Tick退出钩子时判断是否需要统计CPUP */ 2754568cb3Sopenharmony_ci if (CPUP_FLAG == OS_CPUP_EXIT_FLAG) { 2854568cb3Sopenharmony_ci OS_TASK_CYCLE_START(RUNNING_TASK->taskPid, OsCurCycleGet64()); 2954568cb3Sopenharmony_ci } 3054568cb3Sopenharmony_ci CPUP_FLAG--; 3154568cb3Sopenharmony_ci 3254568cb3Sopenharmony_ci OsIntRestore(intSave); 3354568cb3Sopenharmony_ci} 3454568cb3Sopenharmony_ci 3554568cb3Sopenharmony_ci/* 3654568cb3Sopenharmony_ci * 描述:任务切出,中断开始时,统计任务的allTime 3754568cb3Sopenharmony_ci */ 3854568cb3Sopenharmony_ciOS_SEC_L2_TEXT void OsNowTskCycleEnd(void) 3954568cb3Sopenharmony_ci{ 4054568cb3Sopenharmony_ci uintptr_t intSave; 4154568cb3Sopenharmony_ci 4254568cb3Sopenharmony_ci intSave = OsIntLock(); 4354568cb3Sopenharmony_ci 4454568cb3Sopenharmony_ci /* 处理硬中断、Tick进入钩子时判断是否需要统计CPUP */ 4554568cb3Sopenharmony_ci if (CPUP_FLAG == OS_CPUP_ENTRY_FLAG) { 4654568cb3Sopenharmony_ci OS_TASK_CYCLE_END(RUNNING_TASK->taskPid, OsCurCycleGet64()); 4754568cb3Sopenharmony_ci } 4854568cb3Sopenharmony_ci CPUP_FLAG++; 4954568cb3Sopenharmony_ci 5054568cb3Sopenharmony_ci OsIntRestore(intSave); 5154568cb3Sopenharmony_ci} 5254568cb3Sopenharmony_ci 5354568cb3Sopenharmony_ci/* 5454568cb3Sopenharmony_ci * 描述:第一次任务切换时候CPUP设初始值 5554568cb3Sopenharmony_ci */ 5654568cb3Sopenharmony_ciOS_SEC_L2_TEXT void OsCpupFirstSwitch(void) 5754568cb3Sopenharmony_ci{ 5854568cb3Sopenharmony_ci g_cpuWinStart = OsCurCycleGet64(); 5954568cb3Sopenharmony_ci OS_TASK_CYCLE_START(g_highestTask->taskPid, g_cpuWinStart); 6054568cb3Sopenharmony_ci} 6154568cb3Sopenharmony_ci 6254568cb3Sopenharmony_ci/* 6354568cb3Sopenharmony_ci * 描述:任务结束和开始,对任务的CPUP计时 6454568cb3Sopenharmony_ci * 备注:lastTaskId 结束的任务ID;nextTaskId 开始的任务ID;curCycle 结束和开始的Cycle 6554568cb3Sopenharmony_ci */ 6654568cb3Sopenharmony_ciOS_SEC_L2_TEXT void OsCpupStartEnd(U32 lastTaskId, U32 nextTaskId, U64 curCycle) 6754568cb3Sopenharmony_ci{ 6854568cb3Sopenharmony_ci /* 切出任务 */ 6954568cb3Sopenharmony_ci OS_TASK_CYCLE_END(lastTaskId, curCycle); 7054568cb3Sopenharmony_ci 7154568cb3Sopenharmony_ci /* 切入任务 */ 7254568cb3Sopenharmony_ci OS_TASK_CYCLE_START(nextTaskId, curCycle); 7354568cb3Sopenharmony_ci} 7454568cb3Sopenharmony_ci 7554568cb3Sopenharmony_ci/* 7654568cb3Sopenharmony_ci * 描述:任务切换时候CPUP设初始值 7754568cb3Sopenharmony_ci */ 7854568cb3Sopenharmony_ciOS_SEC_L2_TEXT void OsCpupTskSwitch(U32 lastTaskId, U32 nextTaskId) 7954568cb3Sopenharmony_ci{ 8054568cb3Sopenharmony_ci uintptr_t intSave; 8154568cb3Sopenharmony_ci 8254568cb3Sopenharmony_ci intSave = OsIntLock(); 8354568cb3Sopenharmony_ci /* CPUP统计 */ 8454568cb3Sopenharmony_ci OsCpupStartEnd(lastTaskId, nextTaskId, OsCurCycleGet64()); 8554568cb3Sopenharmony_ci 8654568cb3Sopenharmony_ci OsIntRestore(intSave); 8754568cb3Sopenharmony_ci} 8854568cb3Sopenharmony_ci/* 8954568cb3Sopenharmony_ci * 描述:获取输入线程个数的cpup 9054568cb3Sopenharmony_ci */ 9154568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 OsCpupTask(U32 intNum, struct CpupThread *cpup) 9254568cb3Sopenharmony_ci{ 9354568cb3Sopenharmony_ci U32 index; 9454568cb3Sopenharmony_ci U32 maxNum = 0; 9554568cb3Sopenharmony_ci cpup[maxNum].id = OS_CPUP_INT_ID; 9654568cb3Sopenharmony_ci cpup[maxNum].usage = OsCpupIntGet(); 9754568cb3Sopenharmony_ci maxNum++; 9854568cb3Sopenharmony_ci 9954568cb3Sopenharmony_ci for (index = 0; index < (OS_MAX_TCB_NUM - 1); index++) { 10054568cb3Sopenharmony_ci if (intNum == maxNum) { 10154568cb3Sopenharmony_ci break; 10254568cb3Sopenharmony_ci } 10354568cb3Sopenharmony_ci 10454568cb3Sopenharmony_ci /* 判断该任务是否被创建 */ 10554568cb3Sopenharmony_ci if (g_tskCbArray[index].taskStatus == OS_TSK_UNUSED) { 10654568cb3Sopenharmony_ci continue; 10754568cb3Sopenharmony_ci } 10854568cb3Sopenharmony_ci 10954568cb3Sopenharmony_ci cpup[maxNum].id = g_tskCbArray[index].taskPid; 11054568cb3Sopenharmony_ci cpup[maxNum].usage = g_cpup[index].usage; 11154568cb3Sopenharmony_ci 11254568cb3Sopenharmony_ci maxNum++; 11354568cb3Sopenharmony_ci } 11454568cb3Sopenharmony_ci return maxNum; 11554568cb3Sopenharmony_ci} 11654568cb3Sopenharmony_ci 11754568cb3Sopenharmony_ciOS_SEC_ALW_INLINE INLINE U32 OsCpupParaCheck(U32 intNum, struct CpupThread *cpup, const U32 *outNum) 11854568cb3Sopenharmony_ci{ 11954568cb3Sopenharmony_ci if (cpup == NULL || outNum == NULL) { 12054568cb3Sopenharmony_ci return OS_ERRNO_CPUP_PTR_NULL; 12154568cb3Sopenharmony_ci } 12254568cb3Sopenharmony_ci 12354568cb3Sopenharmony_ci if (intNum == 0) { 12454568cb3Sopenharmony_ci return OS_ERRNO_CPUP_THREAD_INNUM_INVALID; 12554568cb3Sopenharmony_ci } 12654568cb3Sopenharmony_ci 12754568cb3Sopenharmony_ci return OS_OK; 12854568cb3Sopenharmony_ci} 12954568cb3Sopenharmony_ci 13054568cb3Sopenharmony_ci/* 13154568cb3Sopenharmony_ci * 描述:获取所有任务线程的运行时间 13254568cb3Sopenharmony_ci */ 13354568cb3Sopenharmony_ciOS_SEC_L2_TEXT U64 OsCpupAllTaskTimeGet(void) 13454568cb3Sopenharmony_ci{ 13554568cb3Sopenharmony_ci U32 index; 13654568cb3Sopenharmony_ci U64 allTime = 0; 13754568cb3Sopenharmony_ci 13854568cb3Sopenharmony_ci for (index = 0; index < (OS_MAX_TCB_NUM - 1); index++) { 13954568cb3Sopenharmony_ci allTime += g_cpup[index].allTime; 14054568cb3Sopenharmony_ci } 14154568cb3Sopenharmony_ci 14254568cb3Sopenharmony_ci return (allTime + g_cpuTimeDelTask); 14354568cb3Sopenharmony_ci} 14454568cb3Sopenharmony_ci 14554568cb3Sopenharmony_ci/* 14654568cb3Sopenharmony_ci * 描述:清空所有任务运行时间和CPU占用率大小 14754568cb3Sopenharmony_ci */ 14854568cb3Sopenharmony_ciOS_SEC_L2_TEXT void OsCpupTimeClear(void) 14954568cb3Sopenharmony_ci{ 15054568cb3Sopenharmony_ci U32 index; 15154568cb3Sopenharmony_ci 15254568cb3Sopenharmony_ci for (index = 0; index < (OS_MAX_TCB_NUM - 1); index++) { 15354568cb3Sopenharmony_ci g_cpup[index].allTime = 0; 15454568cb3Sopenharmony_ci } 15554568cb3Sopenharmony_ci 15654568cb3Sopenharmony_ci g_cpuTimeDelTask = 0; 15754568cb3Sopenharmony_ci} 15854568cb3Sopenharmony_ci/* 15954568cb3Sopenharmony_ci * 描述:清空所有任务运行时间和CPU占用率大小 16054568cb3Sopenharmony_ci */ 16154568cb3Sopenharmony_ciOS_SEC_L2_TEXT void OsCpupTickCal(void) 16254568cb3Sopenharmony_ci{ 16354568cb3Sopenharmony_ci U32 index; 16454568cb3Sopenharmony_ci 16554568cb3Sopenharmony_ci for (index = 0; index < (OS_MAX_TCB_NUM - 1); index++) { 16654568cb3Sopenharmony_ci g_cpup[index].usage = (U16)DIV64(g_cpup[index].allTime * CPUP_USE_RATE, g_baseValue); 16754568cb3Sopenharmony_ci if (g_cpup[index].usage > CPUP_USE_RATE) { 16854568cb3Sopenharmony_ci g_cpup[index].usage = CPUP_USE_RATE; 16954568cb3Sopenharmony_ci } 17054568cb3Sopenharmony_ci } 17154568cb3Sopenharmony_ci 17254568cb3Sopenharmony_ci OsMcCpupSet(OsGetHwThreadId(), (U32)(CPUP_USE_RATE - g_cpup[TSK_GET_INDEX(IDLE_TASK_ID)].usage)); 17354568cb3Sopenharmony_ci 17454568cb3Sopenharmony_ci g_cpupDelTask = (U16)DIV64(g_cpuTimeDelTask * CPUP_USE_RATE, g_baseValue); 17554568cb3Sopenharmony_ci} 17654568cb3Sopenharmony_ci 17754568cb3Sopenharmony_ci/* 17854568cb3Sopenharmony_ci * 描述:获取中断线程的占用率接口 17954568cb3Sopenharmony_ci */ 18054568cb3Sopenharmony_ciOS_SEC_L2_TEXT U16 OsCpupIntGet(void) 18154568cb3Sopenharmony_ci{ 18254568cb3Sopenharmony_ci U32 index; 18354568cb3Sopenharmony_ci U16 usage = 0; 18454568cb3Sopenharmony_ci 18554568cb3Sopenharmony_ci for (index = 0; index < (OS_MAX_TCB_NUM - 1); index++) { 18654568cb3Sopenharmony_ci usage += g_cpup[index].usage; 18754568cb3Sopenharmony_ci } 18854568cb3Sopenharmony_ci 18954568cb3Sopenharmony_ci usage += g_cpupDelTask; 19054568cb3Sopenharmony_ci 19154568cb3Sopenharmony_ci if (usage >= CPUP_USE_RATE) { 19254568cb3Sopenharmony_ci usage = CPUP_USE_RATE; 19354568cb3Sopenharmony_ci } 19454568cb3Sopenharmony_ci 19554568cb3Sopenharmony_ci return (U16)(CPUP_USE_RATE - usage); 19654568cb3Sopenharmony_ci} 19754568cb3Sopenharmony_ci 19854568cb3Sopenharmony_ci/* 19954568cb3Sopenharmony_ci * 描述:获取当前线程级cpu占用率接口 20054568cb3Sopenharmony_ci */ 20154568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 OsCpupThreadNow(void) 20254568cb3Sopenharmony_ci{ 20354568cb3Sopenharmony_ci U64 cpuCycleAll; 20454568cb3Sopenharmony_ci uintptr_t intSave; 20554568cb3Sopenharmony_ci U32 cpup = 0; 20654568cb3Sopenharmony_ci U64 curCycle; 20754568cb3Sopenharmony_ci 20854568cb3Sopenharmony_ci if ((UNI_FLAG & OS_FLG_BGD_ACTIVE) == 0) { 20954568cb3Sopenharmony_ci OS_REPORT_ERROR(OS_ERRNO_CPUP_OS_NOT_STARTED); 21054568cb3Sopenharmony_ci return (U32)OS_INVALID; 21154568cb3Sopenharmony_ci } 21254568cb3Sopenharmony_ci 21354568cb3Sopenharmony_ci intSave = OsIntLock(); 21454568cb3Sopenharmony_ci 21554568cb3Sopenharmony_ci if (g_ticksPerSample != 0) { 21654568cb3Sopenharmony_ci cpup = (U32)(CPUP_USE_RATE - g_cpup[TSK_GET_INDEX(IDLE_TASK_ID)].usage); 21754568cb3Sopenharmony_ci 21854568cb3Sopenharmony_ci OsIntRestore(intSave); 21954568cb3Sopenharmony_ci return cpup; 22054568cb3Sopenharmony_ci } 22154568cb3Sopenharmony_ci 22254568cb3Sopenharmony_ci /* 统计当前系统运行总时间 */ 22354568cb3Sopenharmony_ci curCycle = OsCurCycleGet64(); 22454568cb3Sopenharmony_ci 22554568cb3Sopenharmony_ci if (OS_INT_INACTIVE) { 22654568cb3Sopenharmony_ci OsCpupStartEnd(RUNNING_TASK->taskPid, RUNNING_TASK->taskPid, curCycle); 22754568cb3Sopenharmony_ci } 22854568cb3Sopenharmony_ci 22954568cb3Sopenharmony_ci cpuCycleAll = OsCpupGetWinCycles(curCycle); 23054568cb3Sopenharmony_ci g_cpuWinStart = curCycle; 23154568cb3Sopenharmony_ci 23254568cb3Sopenharmony_ci cpup = (U32)(CPUP_USE_RATE - DIV64(CPUP_USE_RATE * g_cpup[TSK_GET_INDEX(IDLE_TASK_ID)].allTime, cpuCycleAll)); 23354568cb3Sopenharmony_ci OsMcCpupSet(OsGetHwThreadId(), cpup); 23454568cb3Sopenharmony_ci 23554568cb3Sopenharmony_ci OsCpupTimeClear(); 23654568cb3Sopenharmony_ci 23754568cb3Sopenharmony_ci OsIntRestore(intSave); 23854568cb3Sopenharmony_ci 23954568cb3Sopenharmony_ci return cpup; 24054568cb3Sopenharmony_ci} 24154568cb3Sopenharmony_ci 24254568cb3Sopenharmony_ci/* 24354568cb3Sopenharmony_ci * 描述:获取所有线程的占用率接口 24454568cb3Sopenharmony_ci */ 24554568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 PRT_CpupThread(U32 inNum, struct CpupThread *cpup, U32 *outNum) 24654568cb3Sopenharmony_ci{ 24754568cb3Sopenharmony_ci U32 index; 24854568cb3Sopenharmony_ci U32 ret; 24954568cb3Sopenharmony_ci uintptr_t intSave; 25054568cb3Sopenharmony_ci U32 maxNum = 1; // 默认中断占用一个 25154568cb3Sopenharmony_ci 25254568cb3Sopenharmony_ci U64 cpuCycleAll; 25354568cb3Sopenharmony_ci U64 allTime; 25454568cb3Sopenharmony_ci U64 curCycle; 25554568cb3Sopenharmony_ci 25654568cb3Sopenharmony_ci ret = OsCpupPreCheck(); 25754568cb3Sopenharmony_ci if (ret != OS_OK) { 25854568cb3Sopenharmony_ci return ret; 25954568cb3Sopenharmony_ci } 26054568cb3Sopenharmony_ci 26154568cb3Sopenharmony_ci ret = OsCpupParaCheck(inNum, cpup, outNum); 26254568cb3Sopenharmony_ci if (ret != OS_OK) { 26354568cb3Sopenharmony_ci return ret; 26454568cb3Sopenharmony_ci } 26554568cb3Sopenharmony_ci 26654568cb3Sopenharmony_ci /* 获取当前采样周期内,所有线程运行的总时间 */ 26754568cb3Sopenharmony_ci intSave = OsIntLock(); 26854568cb3Sopenharmony_ci 26954568cb3Sopenharmony_ci if (g_ticksPerSample != 0) { 27054568cb3Sopenharmony_ci maxNum = OsCpupTask(inNum, cpup); 27154568cb3Sopenharmony_ci OsIntRestore(intSave); 27254568cb3Sopenharmony_ci *outNum = maxNum; 27354568cb3Sopenharmony_ci 27454568cb3Sopenharmony_ci return OS_OK; 27554568cb3Sopenharmony_ci } 27654568cb3Sopenharmony_ci 27754568cb3Sopenharmony_ci curCycle = OsCurCycleGet64(); 27854568cb3Sopenharmony_ci 27954568cb3Sopenharmony_ci if (OS_INT_INACTIVE) { 28054568cb3Sopenharmony_ci OsCpupStartEnd(RUNNING_TASK->taskPid, RUNNING_TASK->taskPid, curCycle); 28154568cb3Sopenharmony_ci } 28254568cb3Sopenharmony_ci /* 统计当前系统运行总时间 */ 28354568cb3Sopenharmony_ci cpuCycleAll = OsCpupGetWinCycles(curCycle); 28454568cb3Sopenharmony_ci g_cpuWinStart = curCycle; 28554568cb3Sopenharmony_ci 28654568cb3Sopenharmony_ci /* 28754568cb3Sopenharmony_ci * 配置g_cpup[].iD线程ID 28854568cb3Sopenharmony_ci */ 28954568cb3Sopenharmony_ci cpup[0].id = OS_CPUP_INT_ID; 29054568cb3Sopenharmony_ci cpup[0].usage = (U16)DIV64(CPUP_USE_RATE * (cpuCycleAll - OsCpupAllTaskTimeGet()), cpuCycleAll); 29154568cb3Sopenharmony_ci 29254568cb3Sopenharmony_ci for (index = 0; index < (OS_MAX_TCB_NUM - 1) && maxNum < inNum; index++) { 29354568cb3Sopenharmony_ci /* 判断该任务是否被创建 */ 29454568cb3Sopenharmony_ci if (g_tskCbArray[index].taskStatus == OS_TSK_UNUSED) { 29554568cb3Sopenharmony_ci continue; 29654568cb3Sopenharmony_ci } 29754568cb3Sopenharmony_ci 29854568cb3Sopenharmony_ci allTime = g_cpup[index].allTime; 29954568cb3Sopenharmony_ci 30054568cb3Sopenharmony_ci cpup[maxNum].id = g_tskCbArray[index].taskPid; 30154568cb3Sopenharmony_ci cpup[maxNum].usage = (U16)DIV64(CPUP_USE_RATE * allTime, cpuCycleAll); 30254568cb3Sopenharmony_ci 30354568cb3Sopenharmony_ci maxNum++; 30454568cb3Sopenharmony_ci } 30554568cb3Sopenharmony_ci 30654568cb3Sopenharmony_ci OsMcCpupSet(OsGetHwThreadId(), 30754568cb3Sopenharmony_ci (U32)DIV64(CPUP_USE_RATE * (cpuCycleAll - g_cpup[TSK_GET_INDEX(IDLE_TASK_ID)].allTime), cpuCycleAll)); 30854568cb3Sopenharmony_ci 30954568cb3Sopenharmony_ci OsCpupTimeClear(); 31054568cb3Sopenharmony_ci 31154568cb3Sopenharmony_ci OsIntRestore(intSave); 31254568cb3Sopenharmony_ci *outNum = maxNum; 31354568cb3Sopenharmony_ci 31454568cb3Sopenharmony_ci return OS_OK; 31554568cb3Sopenharmony_ci} 316