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