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占用率模块初始化文件
1454568cb3Sopenharmony_ci */
1554568cb3Sopenharmony_ci#include "prt_cpup_thread_internal.h"
1654568cb3Sopenharmony_ci
1754568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsCpupReg(struct CpupModInfo *modInfo)
1854568cb3Sopenharmony_ci{
1954568cb3Sopenharmony_ci    if (modInfo->cpupWarnFlag == TRUE) {
2054568cb3Sopenharmony_ci        if (modInfo->sampleTime == 0) {
2154568cb3Sopenharmony_ci            return OS_ERRNO_CPUP_SAMPLE_TIME_ZERO;
2254568cb3Sopenharmony_ci        }
2354568cb3Sopenharmony_ci    }
2454568cb3Sopenharmony_ci
2554568cb3Sopenharmony_ci    OsMhookReserve((U32)OS_HOOK_FIRST_TIME_SWH, 1);
2654568cb3Sopenharmony_ci    OsMhookReserve((U32)OS_HOOK_TSK_SWITCH, 1);
2754568cb3Sopenharmony_ci    OsMhookReserve((U32)OS_HOOK_HWI_ENTRY, 1);
2854568cb3Sopenharmony_ci    OsMhookReserve((U32)OS_HOOK_HWI_EXIT, 1);
2954568cb3Sopenharmony_ci    OsMhookReserve((U32)OS_HOOK_TICK_ENTRY, 1);
3054568cb3Sopenharmony_ci    OsMhookReserve((U32)OS_HOOK_TICK_EXIT, 1);
3154568cb3Sopenharmony_ci
3254568cb3Sopenharmony_ci    g_ticksPerSample = modInfo->sampleTime;
3354568cb3Sopenharmony_ci
3454568cb3Sopenharmony_ci    return OS_OK;
3554568cb3Sopenharmony_ci}
3654568cb3Sopenharmony_ci/*
3754568cb3Sopenharmony_ci * 描述:tick统计所需要的函数变量初始化。
3854568cb3Sopenharmony_ci */
3954568cb3Sopenharmony_ciOS_SEC_L4_TEXT void OsCpupGlobalInit(void)
4054568cb3Sopenharmony_ci{
4154568cb3Sopenharmony_ci    if (g_ticksPerSample != 0) {
4254568cb3Sopenharmony_ci        g_tickTaskEntry = (TickEntryFunc)OsCpupThreadTickTask;
4354568cb3Sopenharmony_ci    }
4454568cb3Sopenharmony_ci
4554568cb3Sopenharmony_ci    g_cpupNow = OsCpupThreadNow;
4654568cb3Sopenharmony_ci}
4754568cb3Sopenharmony_ci
4854568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsCpupThreadHookAdd(void)
4954568cb3Sopenharmony_ci{
5054568cb3Sopenharmony_ci    U32 ret;
5154568cb3Sopenharmony_ci
5254568cb3Sopenharmony_ci    /* CPUP统计在第一次任务切换的时候 */
5354568cb3Sopenharmony_ci    ret = OsMhookAdd((U32)OS_HOOK_FIRST_TIME_SWH, (OsVoidFunc)OsCpupFirstSwitch);
5454568cb3Sopenharmony_ci    if (ret != OS_OK) {
5554568cb3Sopenharmony_ci        return ret;
5654568cb3Sopenharmony_ci    }
5754568cb3Sopenharmony_ci
5854568cb3Sopenharmony_ci    /* CPUP统计在任务切换的时候 */
5954568cb3Sopenharmony_ci    ret = OsMhookAdd((U32)OS_HOOK_TSK_SWITCH, (OsVoidFunc)OsCpupTskSwitch);
6054568cb3Sopenharmony_ci    if (ret != OS_OK) {
6154568cb3Sopenharmony_ci        return ret;
6254568cb3Sopenharmony_ci    }
6354568cb3Sopenharmony_ci
6454568cb3Sopenharmony_ci    /* CPUP统计在进入硬中断的时候 */
6554568cb3Sopenharmony_ci    ret = OsMhookAdd((U32)OS_HOOK_HWI_ENTRY, (OsVoidFunc)OsNowTskCycleEnd);
6654568cb3Sopenharmony_ci    if (ret != OS_OK) {
6754568cb3Sopenharmony_ci        return ret;
6854568cb3Sopenharmony_ci    }
6954568cb3Sopenharmony_ci
7054568cb3Sopenharmony_ci    /* CPUP统计在退出硬中断的时候 */
7154568cb3Sopenharmony_ci    ret = OsMhookAdd((U32)OS_HOOK_HWI_EXIT, (OsVoidFunc)OsNowTskCycleStart);
7254568cb3Sopenharmony_ci    if (ret != OS_OK) {
7354568cb3Sopenharmony_ci        return ret;
7454568cb3Sopenharmony_ci    }
7554568cb3Sopenharmony_ci
7654568cb3Sopenharmony_ci    /* CPUP统计在进入Tick的时候 */
7754568cb3Sopenharmony_ci    ret = OsMhookAdd((U32)OS_HOOK_TICK_ENTRY, (OsVoidFunc)OsNowTskCycleEnd);
7854568cb3Sopenharmony_ci    if (ret != OS_OK) {
7954568cb3Sopenharmony_ci        return ret;
8054568cb3Sopenharmony_ci    }
8154568cb3Sopenharmony_ci
8254568cb3Sopenharmony_ci    /* CPUP统计在退出Tick的时候 */
8354568cb3Sopenharmony_ci    ret = OsMhookAdd((U32)OS_HOOK_TICK_EXIT, (OsVoidFunc)OsNowTskCycleStart);
8454568cb3Sopenharmony_ci    if (ret != OS_OK) {
8554568cb3Sopenharmony_ci        return ret;
8654568cb3Sopenharmony_ci    }
8754568cb3Sopenharmony_ci
8854568cb3Sopenharmony_ci    return OS_OK;
8954568cb3Sopenharmony_ci}
9054568cb3Sopenharmony_ci
9154568cb3Sopenharmony_ci/*
9254568cb3Sopenharmony_ci * 描述:线程级CPUP初始化接口,返回OS_OK或错误码
9354568cb3Sopenharmony_ci */
9454568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsCpupInit(void)
9554568cb3Sopenharmony_ci{
9654568cb3Sopenharmony_ci    U32 ret;
9754568cb3Sopenharmony_ci    U32 size;
9854568cb3Sopenharmony_ci
9954568cb3Sopenharmony_ci    /* 多申请一个任务线程CPUP信息结构体大小,预留给第一次任务切换时切出的无效任务使用,防止溢出 */
10054568cb3Sopenharmony_ci    size = (OS_MAX_TCB_NUM) * sizeof(struct TagCpupThread);
10154568cb3Sopenharmony_ci    g_cpup = (struct TagCpupThread *)OsMemAllocAlign((U32)OS_MID_CPUP, OS_MEM_DEFAULT_FSC_PT,
10254568cb3Sopenharmony_ci                                                     size, MEM_ADDR_ALIGN_032);
10354568cb3Sopenharmony_ci    if (g_cpup == NULL) {
10454568cb3Sopenharmony_ci        return OS_ERRNO_CPUP_NO_MEMORY;
10554568cb3Sopenharmony_ci    }
10654568cb3Sopenharmony_ci
10754568cb3Sopenharmony_ci    if (memset_s(g_cpup, size, 0, size) != EOK) {
10854568cb3Sopenharmony_ci        OS_GOTO_SYS_ERROR1();
10954568cb3Sopenharmony_ci    }
11054568cb3Sopenharmony_ci
11154568cb3Sopenharmony_ci    g_baseValue = (g_systemClock / g_tickModInfo.tickPerSecond) * (U64)g_ticksPerSample;
11254568cb3Sopenharmony_ci
11354568cb3Sopenharmony_ci    OsCpupGlobalInit();
11454568cb3Sopenharmony_ci
11554568cb3Sopenharmony_ci    ret = OsCpupThreadHookAdd();
11654568cb3Sopenharmony_ci    return ret;
11754568cb3Sopenharmony_ci}
118