1/*
2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *          http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2009-12-22
13 * Description: 线程级CPU占用率模块初始化文件
14 */
15#include "prt_cpup_thread_internal.h"
16
17OS_SEC_L4_TEXT U32 OsCpupReg(struct CpupModInfo *modInfo)
18{
19    if (modInfo->cpupWarnFlag == TRUE) {
20        if (modInfo->sampleTime == 0) {
21            return OS_ERRNO_CPUP_SAMPLE_TIME_ZERO;
22        }
23    }
24
25    OsMhookReserve((U32)OS_HOOK_FIRST_TIME_SWH, 1);
26    OsMhookReserve((U32)OS_HOOK_TSK_SWITCH, 1);
27    OsMhookReserve((U32)OS_HOOK_HWI_ENTRY, 1);
28    OsMhookReserve((U32)OS_HOOK_HWI_EXIT, 1);
29    OsMhookReserve((U32)OS_HOOK_TICK_ENTRY, 1);
30    OsMhookReserve((U32)OS_HOOK_TICK_EXIT, 1);
31
32    g_ticksPerSample = modInfo->sampleTime;
33
34    return OS_OK;
35}
36/*
37 * 描述:tick统计所需要的函数变量初始化。
38 */
39OS_SEC_L4_TEXT void OsCpupGlobalInit(void)
40{
41    if (g_ticksPerSample != 0) {
42        g_tickTaskEntry = (TickEntryFunc)OsCpupThreadTickTask;
43    }
44
45    g_cpupNow = OsCpupThreadNow;
46}
47
48OS_SEC_L4_TEXT U32 OsCpupThreadHookAdd(void)
49{
50    U32 ret;
51
52    /* CPUP统计在第一次任务切换的时候 */
53    ret = OsMhookAdd((U32)OS_HOOK_FIRST_TIME_SWH, (OsVoidFunc)OsCpupFirstSwitch);
54    if (ret != OS_OK) {
55        return ret;
56    }
57
58    /* CPUP统计在任务切换的时候 */
59    ret = OsMhookAdd((U32)OS_HOOK_TSK_SWITCH, (OsVoidFunc)OsCpupTskSwitch);
60    if (ret != OS_OK) {
61        return ret;
62    }
63
64    /* CPUP统计在进入硬中断的时候 */
65    ret = OsMhookAdd((U32)OS_HOOK_HWI_ENTRY, (OsVoidFunc)OsNowTskCycleEnd);
66    if (ret != OS_OK) {
67        return ret;
68    }
69
70    /* CPUP统计在退出硬中断的时候 */
71    ret = OsMhookAdd((U32)OS_HOOK_HWI_EXIT, (OsVoidFunc)OsNowTskCycleStart);
72    if (ret != OS_OK) {
73        return ret;
74    }
75
76    /* CPUP统计在进入Tick的时候 */
77    ret = OsMhookAdd((U32)OS_HOOK_TICK_ENTRY, (OsVoidFunc)OsNowTskCycleEnd);
78    if (ret != OS_OK) {
79        return ret;
80    }
81
82    /* CPUP统计在退出Tick的时候 */
83    ret = OsMhookAdd((U32)OS_HOOK_TICK_EXIT, (OsVoidFunc)OsNowTskCycleStart);
84    if (ret != OS_OK) {
85        return ret;
86    }
87
88    return OS_OK;
89}
90
91/*
92 * 描述:线程级CPUP初始化接口,返回OS_OK或错误码
93 */
94OS_SEC_L4_TEXT U32 OsCpupInit(void)
95{
96    U32 ret;
97    U32 size;
98
99    /* 多申请一个任务线程CPUP信息结构体大小,预留给第一次任务切换时切出的无效任务使用,防止溢出 */
100    size = (OS_MAX_TCB_NUM) * sizeof(struct TagCpupThread);
101    g_cpup = (struct TagCpupThread *)OsMemAllocAlign((U32)OS_MID_CPUP, OS_MEM_DEFAULT_FSC_PT,
102                                                     size, MEM_ADDR_ALIGN_032);
103    if (g_cpup == NULL) {
104        return OS_ERRNO_CPUP_NO_MEMORY;
105    }
106
107    if (memset_s(g_cpup, size, 0, size) != EOK) {
108        OS_GOTO_SYS_ERROR1();
109    }
110
111    g_baseValue = (g_systemClock / g_tickModInfo.tickPerSecond) * (U64)g_ticksPerSample;
112
113    OsCpupGlobalInit();
114
115    ret = OsCpupThreadHookAdd();
116    return ret;
117}
118