更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_cpup.c
浏览该文件的文档.
1/*!
2 * @file los_cpup.c
3 * @brief
4 * @link kernel-small-debug-process-cpu http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-debug-process-cpu.html @endlink
5 @verbatim
6 基本概念
7 CPU(中央处理器,Central Processing Unit)占用率分为系统CPU占用率、进程CPU占用率、任务CPU占用率
8 和中断CPU占用率。用户通过系统级的CPU占用率,判断当前系统负载是否超出设计规格。通过系统中各个
9 进程/任务/中断的CPU占用情况,判断各个进程/任务/中断的CPU占用率是否符合设计的预期。
10
11 系统CPU占用率(CPU Percent)
12
13 指周期时间内系统的CPU占用率,用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。系统CPU占用率
14 的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示系统满负荷运转。
15
16 进程CPU占用率
17
18 指单个进程的CPU占用率,用于表示单个进程在一段时间内的闲忙程度。进程CPU占用率的有效表示范围为0~100,
19 其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该进程。
20
21 任务CPU占用率
22
23 指单个任务的CPU占用率,用于表示单个任务在一段时间内的闲忙程度。任务CPU占用率的有效表示范围为0~100,
24 其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该任务。
25
26 中断CPU占用率
27
28 指单个中断的CPU占用率,用于表示单个中断在一段时间内的闲忙程度。中断CPU占用率的有效表示范围为0~100,
29 其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该中断。
30
31 运行机制
32 OpenHarmony LiteOS-A内核CPUP(CPU Percent,CPU占用率)模块采用进程、任务和中断级记录的方式,在进程/任务切换时,
33 记录进程/任务启动时间,进程/任务切出或者退出时,系统会累加整个进程/任务的占用时间; 在执行中断时系统会累加记录
34 每个中断的执行时间。
35
36 OpenHarmony 提供以下四种CPU占用率的信息查询:
37
38 系统CPU占用率
39 进程CPU占用率
40 任务CPU占用率
41 中断CPU占用率
42
43 CPU占用率的计算方法:
44
45 系统CPU占用率=系统中除idle任务外其他任务运行总时间/系统运行总时间
46
47 进程CPU占用率=进程运行总时间/系统运行总时间
48
49 任务CPU占用率=任务运行总时间/系统运行总时间
50
51 中断CPU占用率=中断运行总时间/系统运行总时间
52
53 开发流程
54 CPU占用率的典型开发流程:
55
56 调用获取系统历史CPU占用率函数LOS_HistorySysCpuUsage。
57
58 调用获取指定进程历史CPU占用率函数LOS_HistoryProcessCpuUsage。
59
60 若进程已创建,则关中断,根据不同模式正常获取,恢复中断;
61 若进程未创建,则返回错误码;
62 调用获取所有进程CPU占用率函数LOS_GetAllProcessCpuUsage。
63
64 若CPUP已初始化,则关中断,根据不同模式正常获取,恢复中断;
65 若CPUP未初始化或有非法入参,则返回错误码;
66 调用获取指定任务历史CPU占用率函数LOS_HistoryTaskCpuUsage。
67
68 若任务已创建,则关中断,根据不同模式正常获取,恢复中断;
69 若任务未创建,则返回错误码;
70 调用获取所有中断CPU占用率函数LOS_GetAllIrqCpuUsage。
71
72 若CPUP已初始化,则关中断,根据不同模式正常获取,恢复中断;
73 若CPUP未初始化或有非法入参,则返回错误码;
74
75 @endverbatim
76 * @image html https://gitee.com/weharmonyos/resources/raw/master/27/mux.png
77 * @attention
78 * @version
79 * @author weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
80 * @date 2021-11-21
81 */
82
83/*
84 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
85 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
86 *
87 * Redistribution and use in source and binary forms, with or without modification,
88 * are permitted provided that the following conditions are met:
89 *
90 * 1. Redistributions of source code must retain the above copyright notice, this list of
91 * conditions and the following disclaimer.
92 *
93 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
94 * of conditions and the following disclaimer in the documentation and/or other materials
95 * provided with the distribution.
96 *
97 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
98 * to endorse or promote products derived from this software without specific prior written
99 * permission.
100 *
101 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
102 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
103 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
104 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
105 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
106 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
107 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
108 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
109 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
110 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
111 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
112 */
113
114#include "los_cpup_pri.h"
115#include "los_base.h"
116#include "los_init.h"
117#include "los_process_pri.h"
118#include "los_swtmr.h"
119
120
121#ifdef LOSCFG_KERNEL_CPUP
122
123LITE_OS_SEC_BSS STATIC UINT16 cpupSwtmrID; ///< 监测CPU使用情况定时器s
124LITE_OS_SEC_BSS STATIC UINT16 cpupInitFlg = 0;
125LITE_OS_SEC_BSS OsIrqCpupCB *g_irqCpup = NULL;
126LITE_OS_SEC_BSS STATIC UINT32 cpupMaxNum;
127LITE_OS_SEC_BSS STATIC UINT16 cpupHisPos = 0; /* current Sampling point of historyTime */
128LITE_OS_SEC_BSS STATIC UINT64 cpuHistoryTime[OS_CPUP_HISTORY_RECORD_NUM + 1];
129LITE_OS_SEC_BSS STATIC UINT32 runningTasks[LOSCFG_KERNEL_CORE_NUM];
130LITE_OS_SEC_BSS STATIC UINT64 cpupStartCycles = 0; ///< 记录
131#ifdef LOSCFG_CPUP_INCLUDE_IRQ
132LITE_OS_SEC_BSS UINT64 timeInIrqSwitch[LOSCFG_KERNEL_CORE_NUM];
133LITE_OS_SEC_BSS STATIC UINT64 cpupIntTimeStart[LOSCFG_KERNEL_CORE_NUM];
134#endif
135
136#define INVALID_ID ((UINT32)-1)
137
138#define OS_CPUP_UNUSED 0x0U
139#define OS_CPUP_USED 0x1U
140#define HIGH_BITS 32
141
142#define CPUP_PRE_POS(pos) (((pos) == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : ((pos) - 1))
143#define CPUP_POST_POS(pos) (((pos) == (OS_CPUP_HISTORY_RECORD_NUM - 1)) ? 0 : ((pos) + 1))
144///< 获取CPU周期
146{
147 UINT32 high;
148 UINT32 low;
149 UINT64 cycles;//周期数用 64位计算,读取分成高低位
150
151 LOS_GetCpuCycle(&high, &low);//将64位拆成两个32位
152 cycles = ((UINT64)high << HIGH_BITS) + low;
153 if (cpupStartCycles == 0) {
154 cpupStartCycles = cycles;
155 }
156
157 /*
158 * The cycles should keep growing, if the checking failed,
159 * it mean LOS_GetCpuCycle has the problem which should be fixed.
160 */
161 LOS_ASSERT(cycles >= cpupStartCycles);
162
163 return (cycles - cpupStartCycles);
164}
165
166LITE_OS_SEC_TEXT_INIT VOID OsCpupGuard(VOID)
167{
168 UINT16 prevPos;
169 UINT32 loop;
170 UINT32 runTaskID;
171 UINT32 intSave;
172 UINT64 cycle, cycleIncrement;
173 LosTaskCB *taskCB = NULL;
174 LosProcessCB *processCB = NULL;
175
176 SCHEDULER_LOCK(intSave);
177
178 cycle = OsGetCpuCycle();
179 prevPos = cpupHisPos;
180 cpupHisPos = CPUP_POST_POS(cpupHisPos);
181 cpuHistoryTime[prevPos] = cycle;
182
183#ifdef LOSCFG_CPUP_INCLUDE_IRQ
184 for (loop = 0; loop < cpupMaxNum; loop++) {
185 if (g_irqCpup[loop].status == OS_CPUP_UNUSED) {
186 continue;
187 }
188 g_irqCpup[loop].cpup.historyTime[prevPos] = g_irqCpup[loop].cpup.allTime;
189 }
190#endif
191
192 for (loop = 0; loop < g_processMaxNum; loop++) {
193 processCB = OS_PCB_FROM_PID(loop);
194 if (processCB->processCpup == NULL) {
195 continue;
196 }
197 processCB->processCpup->historyTime[prevPos] = processCB->processCpup->allTime;
198 }
199
200 for (loop = 0; loop < g_taskMaxNum; loop++) {
201 taskCB = OS_TCB_FROM_TID(loop);
202 taskCB->taskCpup.historyTime[prevPos] = taskCB->taskCpup.allTime;
203 }
204
205 for (loop = 0; loop < LOSCFG_KERNEL_CORE_NUM; loop++) {
206 runTaskID = runningTasks[loop];
207 if (runTaskID == INVALID_ID) {
208 continue;
209 }
210 taskCB = OS_TCB_FROM_TID(runTaskID);
211
212 /* reacquire the cycle to prevent flip */
213 cycle = OsGetCpuCycle();
214 cycleIncrement = cycle - taskCB->taskCpup.startTime;
215#ifdef LOSCFG_CPUP_INCLUDE_IRQ
216 cycleIncrement -= timeInIrqSwitch[loop];
217#endif
218 taskCB->taskCpup.historyTime[prevPos] += cycleIncrement;
219 processCB = OS_PCB_FROM_PID(taskCB->processID);
220 processCB->processCpup->historyTime[prevPos] += cycleIncrement;
221 }
222
223 SCHEDULER_UNLOCK(intSave);
224}
225///创建cpu使用统计定时器
226LITE_OS_SEC_TEXT_INIT UINT32 OsCpupGuardCreator(VOID)
227{
228 (VOID)LOS_SwtmrCreate(LOSCFG_BASE_CORE_TICK_PER_SECOND, LOS_SWTMR_MODE_PERIOD,
230
232
233 return LOS_OK;
234}
235
236LOS_MODULE_INIT(OsCpupGuardCreator, LOS_INIT_LEVEL_KMOD_TASK);
237
238/*
239 * Description: initialization of CPUP
240 * Return : LOS_OK or Error Information
241 */
242LITE_OS_SEC_TEXT_INIT UINT32 OsCpupInit(VOID)
243{
244 UINT16 loop;
245#ifdef LOSCFG_CPUP_INCLUDE_IRQ
246 UINT32 size;
247
248 cpupMaxNum = OS_HWI_MAX_NUM * LOSCFG_KERNEL_CORE_NUM;
249
250 /* every process has only one record, and it won't operated at the same time */
251 size = cpupMaxNum * sizeof(OsIrqCpupCB);
253 if (g_irqCpup == NULL) {
254 PRINT_ERR("OsCpupInit error\n");
255 return LOS_ERRNO_CPUP_NO_MEMORY;
256 }
257
258 (VOID)memset_s(g_irqCpup, size, 0, size);
259#endif
260
261 for (loop = 0; loop < LOSCFG_KERNEL_CORE_NUM; loop++) {
262 runningTasks[loop] = INVALID_ID;
263 }
264 cpupInitFlg = 1;
265 return LOS_OK;
266}
267
268LOS_MODULE_INIT(OsCpupInit, LOS_INIT_LEVEL_KMOD_EXTENDED);
269
270STATIC VOID OsResetCpup(OsCpupBase *cpup, UINT64 cycle)
271{
272 UINT16 loop;
273
274 cpup->startTime = cycle;
275 cpup->allTime = cycle;
276 for (loop = 0; loop < (OS_CPUP_HISTORY_RECORD_NUM + 1); loop++) {
277 cpup->historyTime[loop] = cycle;
278 }
279}
280
281LITE_OS_SEC_TEXT_INIT VOID LOS_CpupReset(VOID)
282{
283 LosProcessCB *processCB = NULL;
284 LosTaskCB *taskCB = NULL;
285 UINT32 index;
286 UINT64 cycle;
287 UINT32 intSave;
288
289 cpupInitFlg = 0;
290 intSave = LOS_IntLock();
292 cycle = OsGetCpuCycle();
293
294 for (index = 0; index < (OS_CPUP_HISTORY_RECORD_NUM + 1); index++) {
295 cpuHistoryTime[index] = cycle;
296 }
297
298 for (index = 0; index < g_processMaxNum; index++) {
299 processCB = OS_PCB_FROM_PID(index);
300 if (processCB->processCpup == NULL) {
301 continue;
302 }
303 OsResetCpup(processCB->processCpup, cycle);
304 }
305
306 for (index = 0; index < g_taskMaxNum; index++) {
307 taskCB = OS_TCB_FROM_TID(index);
308 OsResetCpup(&taskCB->taskCpup, cycle);
309 }
310
311#ifdef LOSCFG_CPUP_INCLUDE_IRQ
312 if (g_irqCpup != NULL) {
313 for (index = 0; index < cpupMaxNum; index++) {
314 OsResetCpup(&g_irqCpup[index].cpup, cycle);
315 g_irqCpup[index].timeMax = 0;
316 }
317
318 for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {
319 timeInIrqSwitch[index] = 0;
320 }
321 }
322#endif
323
325 LOS_IntRestore(intSave);
326 cpupInitFlg = 1;
327
328 return;
329}
330
331VOID OsCpupCycleEndStart(UINT32 runTaskID, UINT32 newTaskID)
332{
333 /* OsCurrTaskGet and OsCurrProcessGet are not allowed to be called. */
334 LosTaskCB *runTask = OS_TCB_FROM_TID(runTaskID);
335 OsCpupBase *runTaskCpup = &runTask->taskCpup;
336 OsCpupBase *newTaskCpup = (OsCpupBase *)&(OS_TCB_FROM_TID(newTaskID)->taskCpup);
337 OsCpupBase *processCpup = OS_PCB_FROM_PID(runTask->processID)->processCpup;
338 UINT64 cpuCycle, cycleIncrement;
339 UINT16 cpuid = ArchCurrCpuid();
340
341 if (cpupInitFlg == 0) {
342 return;
343 }
344
345 cpuCycle = OsGetCpuCycle();
346 if (runTaskCpup->startTime != 0) {
347 cycleIncrement = cpuCycle - runTaskCpup->startTime;
348#ifdef LOSCFG_CPUP_INCLUDE_IRQ
349 cycleIncrement -= timeInIrqSwitch[cpuid];
350 timeInIrqSwitch[cpuid] = 0;
351#endif
352 runTaskCpup->allTime += cycleIncrement;
353 if (processCpup != NULL) {
354 processCpup->allTime += cycleIncrement;
355 }
356 runTaskCpup->startTime = 0;
357 }
358
359 newTaskCpup->startTime = cpuCycle;
360 runningTasks[cpuid] = newTaskID;
361}
362
363LITE_OS_SEC_TEXT_MINOR STATIC VOID OsCpupGetPos(UINT16 mode, UINT16 *curPosPointer, UINT16 *prePosPointer)
364{
365 UINT16 curPos;
366 UINT16 tmpPos;
367 UINT16 prePos;
368
369 tmpPos = cpupHisPos;
370 curPos = CPUP_PRE_POS(tmpPos);
371
372 /*
373 * The current postion has nothing to do with the CPUP modes,
374 * however, the previous postion differs.
375 */
376 switch (mode) {
378 prePos = CPUP_PRE_POS(curPos);
379 break;
381 prePos = tmpPos;
382 break;
383 case CPUP_ALL_TIME:
384 /* fall-through */
385 default:
386 prePos = OS_CPUP_HISTORY_RECORD_NUM;
387 break;
388 }
389
390 *curPosPointer = curPos;
391 *prePosPointer = prePos;
392
393 return;
394}
395
396STATIC INLINE UINT32 OsCalculateCpupUsage(const OsCpupBase *cpup, UINT16 pos, UINT16 prePos, UINT64 allCycle)
397{
398 UINT32 usage = 0;
399 UINT64 cpuCycle = cpup->historyTime[pos] - cpup->historyTime[prePos];
400
401 if (allCycle) {
402 usage = (UINT32)((LOS_CPUP_SINGLE_CORE_PRECISION * cpuCycle) / allCycle);
403 }
404 return usage;
405}
406
408{
409 UINT64 cpuAllCycle;
410 UINT16 pos;
411 UINT16 prePos;
412 UINT32 idleProcessID;
413 OsCpupBase *processCpup = NULL;
414
415 if (cpupInitFlg == 0) {
416 return LOS_ERRNO_CPUP_NO_INIT;
417 }
418
419 OsCpupGetPos(mode, &pos, &prePos);
420 cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos];
421
422 idleProcessID = OsGetIdleProcessID();
423 processCpup = OS_PCB_FROM_PID(idleProcessID)->processCpup;
424 return (LOS_CPUP_PRECISION - OsCalculateCpupUsage(processCpup, pos, prePos, cpuAllCycle));
425}
426
427/**
428 * \brief 获取系统历史CPU占用率
429 * 指周期时间内系统的CPU占用率,用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。系统CPU
430 * 占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示系统满负荷运转。
431 * \param mode
432 *
433 * \return
434 */
435LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistorySysCpuUsage(UINT16 mode)
436{
437 UINT32 cpup;
438 UINT32 intSave;
439
440 /* get end time of current process */
441 SCHEDULER_LOCK(intSave);
442 cpup = OsHistorySysCpuUsageUnsafe(mode);
443 SCHEDULER_UNLOCK(intSave);
444 return cpup;
445}
446
448{
449 LosProcessCB *processCB = NULL;
450 UINT64 cpuAllCycle;
451 UINT16 pos, prePos;
452
453 if (cpupInitFlg == 0) {
454 return LOS_ERRNO_CPUP_NO_INIT;
455 }
456
457 if (OS_PID_CHECK_INVALID(pid)) {
458 return LOS_ERRNO_CPUP_ID_INVALID;
459 }
460
461 processCB = OS_PCB_FROM_PID(pid);
462 if (OsProcessIsUnused(processCB)) {
463 return LOS_ERRNO_CPUP_NO_CREATED;
464 }
465
466 if (processCB->processCpup == NULL) {
467 return LOS_ERRNO_CPUP_ID_INVALID;
468 }
469
470 OsCpupGetPos(mode, &pos, &prePos);
471 cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos];
472
473 return OsCalculateCpupUsage(processCB->processCpup, pos, prePos, cpuAllCycle);
474}
475
476/**
477 * \brief 获取指定进程历史CPU占用率
478 * 指单个进程的CPU占用率,用于表示单个进程在一段时间内的闲忙程度。进程CPU占用率的有效表示范围为0~100,
479 * 其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该进程。
480 * \param pid
481 * \param mode
482 *
483 * \return
484 */
485LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryProcessCpuUsage(UINT32 pid, UINT16 mode)
486{
487 UINT32 cpup;
488 UINT32 intSave;
489
490 SCHEDULER_LOCK(intSave);
491 cpup = OsHistoryProcessCpuUsageUnsafe(pid, mode);
492 SCHEDULER_UNLOCK(intSave);
493 return cpup;
494}
495
497{
498 LosTaskCB *taskCB = NULL;
499 UINT64 cpuAllCycle;
500 UINT16 pos, prePos;
501
502 if (cpupInitFlg == 0) {
503 return LOS_ERRNO_CPUP_NO_INIT;
504 }
505
506 if (OS_TID_CHECK_INVALID(tid)) {
507 return LOS_ERRNO_CPUP_ID_INVALID;
508 }
509
510 taskCB = OS_TCB_FROM_TID(tid);
511 if (OsTaskIsUnused(taskCB)) {
512 return LOS_ERRNO_CPUP_NO_CREATED;
513 }
514
515 OsCpupGetPos(mode, &pos, &prePos);
516 cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos];
517
518 return OsCalculateCpupUsage(&taskCB->taskCpup, pos, prePos, cpuAllCycle);
519}
520
521/**
522 * \brief 获取指定任务历史CPU占用率
523 * 指单个任务的CPU占用率,用于表示单个任务在一段时间内的闲忙程度。任务CPU占用率的有效表示范围为0~100,
524 * 其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该任务。
525 * \param tid
526 * \param mode
527 *
528 * \return
529 */
530LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryTaskCpuUsage(UINT32 tid, UINT16 mode)
531{
532 UINT32 intSave;
533 UINT32 cpup;
534
535 SCHEDULER_LOCK(intSave);
536 cpup = OsHistoryTaskCpuUsageUnsafe(tid, mode);
537 SCHEDULER_UNLOCK(intSave);
538 return cpup;
539}
540
542{
543 if (cpupInitFlg == 0) {
544 return LOS_ERRNO_CPUP_NO_INIT;
545 }
546
547 if ((cpupInfo == NULL) || (len < (sizeof(CPUP_INFO_S) * number))) {
548 return LOS_ERRNO_CPUP_PTR_ERR;
549 }
550
551 (VOID)memset_s(cpupInfo, len, 0, len);
552 return LOS_OK;
553}
554
555LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllProcessCpuUsageUnsafe(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len)
556{
557 LosProcessCB *processCB = NULL;
558 UINT64 cpuAllCycle;
559 UINT16 pos, prePos;
560 UINT32 processID;
561 UINT32 ret;
562
564 if (ret != LOS_OK) {
565 return ret;
566 }
567
568 OsCpupGetPos(mode, &pos, &prePos);
569 cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos];
570
571 for (processID = 0; processID < g_processMaxNum; processID++) {
572 processCB = OS_PCB_FROM_PID(processID);
573 if (OsProcessIsUnused(processCB) || (processCB->processCpup == NULL)) {
574 continue;
575 }
576
577 cpupInfo[processID].usage = OsCalculateCpupUsage(processCB->processCpup, pos, prePos, cpuAllCycle);
578 cpupInfo[processID].status = OS_CPUP_USED;
579 }
580
581 return LOS_OK;
582}
583/// 获取系统所有进程的历史CPU占用率
584LITE_OS_SEC_TEXT_MINOR UINT32 LOS_GetAllProcessCpuUsage(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len)
585{
586 UINT32 intSave;
587 UINT32 ret;
588
589 SCHEDULER_LOCK(intSave);
590 ret = OsGetAllProcessCpuUsageUnsafe(mode, cpupInfo, len);
591 SCHEDULER_UNLOCK(intSave);
592 return ret;
593}
594
595LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllProcessAndTaskCpuUsageUnsafe(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len)
596{
597 UINT64 cpuAllCycle;
598 UINT16 pos, prePos;
599 UINT32 taskID;
600 UINT32 ret;
601 LosTaskCB *taskCB = NULL;
602 OsCpupBase *processCpupBase = NULL;
603 CPUP_INFO_S *processCpup = cpupInfo;
604 CPUP_INFO_S *taskCpup = (CPUP_INFO_S *)((UINTPTR)cpupInfo + sizeof(CPUP_INFO_S) * g_processMaxNum);
605
607 if (ret != LOS_OK) {
608 return ret;
609 }
610
611 OsCpupGetPos(mode, &pos, &prePos);
612 cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos];
613
614 for (taskID = 0; taskID < g_taskMaxNum; taskID++) {
615 taskCB = OS_TCB_FROM_TID(taskID);
616 if (OsTaskIsUnused(taskCB)) {
617 continue;
618 }
619
620 taskCpup[taskID].usage = OsCalculateCpupUsage(&taskCB->taskCpup, pos, prePos, cpuAllCycle);
621 taskCpup[taskID].status = OS_CPUP_USED;
622 if (processCpup[taskCB->processID].status == OS_CPUP_UNUSED) {
623 processCpupBase = OS_PCB_FROM_PID(taskCB->processID)->processCpup;
624 if (processCpupBase != NULL) {
625 processCpup[taskCB->processID].usage = OsCalculateCpupUsage(processCpupBase, pos, prePos, cpuAllCycle);
626 processCpup[taskCB->processID].status = OS_CPUP_USED;
627 }
628 }
629 }
630
631 return LOS_OK;
632}
633
634#ifdef LOSCFG_CPUP_INCLUDE_IRQ
635LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqStart(UINT16 cpuid)
636{
637 UINT32 high;
638 UINT32 low;
639
640 LOS_GetCpuCycle(&high, &low);
641 cpupIntTimeStart[cpuid] = ((UINT64)high << HIGH_BITS) + low;
642 return;
643}
644
645LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqEnd(UINT16 cpuid, UINT32 intNum)
646{
647 UINT32 high;
648 UINT32 low;
649 UINT64 intTimeEnd;
650 UINT64 usedTime;
651
652 LOS_GetCpuCycle(&high, &low);
653 intTimeEnd = ((UINT64)high << HIGH_BITS) + low;
654 OsIrqCpupCB *irqCb = &g_irqCpup[(intNum * LOSCFG_KERNEL_CORE_NUM) + cpuid];
655 irqCb->id = intNum;
656 irqCb->status = OS_CPUP_USED;
657 usedTime = intTimeEnd - cpupIntTimeStart[cpuid];
658 timeInIrqSwitch[cpuid] += usedTime;
659 irqCb->cpup.allTime += usedTime;
660 if (irqCb->count <= 100) { /* Take 100 samples */
661 irqCb->allTime += usedTime;
662 irqCb->count++;
663 } else {
664 irqCb->allTime = 0;
665 irqCb->count = 0;
666 }
667 if (usedTime > irqCb->timeMax) {
668 irqCb->timeMax = usedTime;
669 }
670 return;
671}
672
673LITE_OS_SEC_TEXT_MINOR OsIrqCpupCB *OsGetIrqCpupArrayBase(VOID)
674{
675 return g_irqCpup;
676}
677
678LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllIrqCpuUsageUnsafe(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len)
679{
680 UINT16 pos, prePos;
681 UINT64 cpuAllCycle;
682 UINT32 loop;
683 UINT32 ret;
684
685 ret = OsCpupUsageParamCheckAndReset(cpupInfo, len, cpupMaxNum);
686 if (ret != LOS_OK) {
687 return ret;
688 }
689
690 OsCpupGetPos(mode, &pos, &prePos);
691 cpuAllCycle = cpuHistoryTime[pos] - cpuHistoryTime[prePos];
692
693 for (loop = 0; loop < cpupMaxNum; loop++) {
694 if (g_irqCpup[loop].status == OS_CPUP_UNUSED) {
695 continue;
696 }
697
698 cpupInfo[loop].usage = OsCalculateCpupUsage(&g_irqCpup[loop].cpup, pos, prePos, cpuAllCycle);
699 cpupInfo[loop].status = g_irqCpup[loop].status;
700 }
701
702 return LOS_OK;
703}
704
705/**
706 * \brief 获取系统所有中断的历史CPU占用率
707 * 指单个中断的CPU占用率,用于表示单个中断在一段时间内的闲忙程度。中断CPU占用率的有效表示范围为0~100,
708 * 其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该中断。
709 * \param mode
710 * \param cpupInfo
711 * \param len
712 *
713 * \return
714 */
715LITE_OS_SEC_TEXT_MINOR UINT32 LOS_GetAllIrqCpuUsage(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len)
716{
717 UINT32 intSave;
718 UINT32 ret;
719
720 SCHEDULER_LOCK(intSave);
721 ret = OsGetAllIrqCpuUsageUnsafe(mode, cpupInfo, len);
722 SCHEDULER_UNLOCK(intSave);
723 return ret;
724}
725#endif
726
727#endif /* LOSCFG_KERNEL_CPUP */
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryTaskCpuUsage(UINT32 tid, UINT16 mode)
获取指定任务历史CPU占用率 指单个任务的CPU占用率,用于表示单个任务在一段时间内的闲忙程度。任务CPU占用率的有效表示范围为0~100, 其精度(可通过配置调整)为百分比。100表示在一段时间内系统...
Definition: los_cpup.c:530
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_GetAllIrqCpuUsage(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len)
获取系统所有中断的历史CPU占用率 指单个中断的CPU占用率,用于表示单个中断在一段时间内的闲忙程度。中断CPU占用率的有效表示范围为0~100, 其精度(可通过配置调整)为百分比。100表示在一段时间...
Definition: los_cpup.c:715
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_GetAllProcessCpuUsage(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len)
获取系统所有进程的历史CPU占用率
Definition: los_cpup.c:584
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistorySysCpuUsage(UINT16 mode)
获取系统历史CPU占用率 指周期时间内系统的CPU占用率,用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。系统CPU 占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100...
Definition: los_cpup.c:435
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryProcessCpuUsage(UINT32 pid, UINT16 mode)
获取指定进程历史CPU占用率 指单个进程的CPU占用率,用于表示单个进程在一段时间内的闲忙程度。进程CPU占用率的有效表示范围为0~100, 其精度(可通过配置调整)为百分比。100表示在一段时间内系统...
Definition: los_cpup.c:485
LITE_OS_SEC_TEXT_INIT VOID LOS_CpupReset(VOID)
Reset the data of CPU usage.
Definition: los_cpup.c:281
struct tagCpupInfo CPUP_INFO_S
@ CPUP_LAST_TEN_SECONDS
Definition: los_cpup.h:132
@ CPUP_ALL_TIME
Definition: los_cpup.h:134
@ CPUP_LAST_ONE_SECONDS
Definition: los_cpup.h:133
STATIC INLINE VOID LOS_IntRestore(UINT32 intSave)
Restore interrupts. | 恢复到使用LOS_IntLock关闭所有中断之前的状态
Definition: los_hwi.h:337
STATIC INLINE UINT32 LOS_IntLock(VOID)
Disable all interrupts. | 关闭当前处理器所有中断响应
Definition: los_hwi.h:286
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
Definition: los_memory.c:1123
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
Definition: los_memory.c:107
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
接口函数 停止定时器 参数定时任务ID
Definition: los_swtmr.c:808
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
接口函数 启动定时器 参数定时任务ID
Definition: los_swtmr.c:764
VOID(* SWTMR_PROC_FUNC)(UINTPTR arg)
Define the type of a callback function that handles software timer timeout.
Definition: los_swtmr.h:260
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, UINT16 *swtmrID, UINTPTR arg)
创建定时器,设置定时器的定时时长、定时器模式、回调函数,并返回定时器ID
Definition: los_swtmr.c:712
@ LOS_SWTMR_MODE_PERIOD
Definition: los_swtmr.h:233
LITE_OS_SEC_BSS UINT32 g_taskMaxNum
任务最大数量 默认128个
Definition: los_task.c:150
LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *highCnt, UINT32 *lowCnt)
获取自系统启动以来的Cycle数
Definition: los_hw_tick.c:54
LITE_OS_SEC_TEXT_INIT VOID OsCpupGuard(VOID)
Definition: los_cpup.c:166
STATIC VOID OsResetCpup(OsCpupBase *cpup, UINT64 cycle)
Definition: los_cpup.c:270
LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllProcessCpuUsageUnsafe(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len)
Definition: los_cpup.c:555
STATIC UINT64 OsGetCpuCycle(VOID)
Definition: los_cpup.c:145
STATIC UINT32 OsCpupUsageParamCheckAndReset(CPUP_INFO_S *cpupInfo, UINT32 len, UINT32 number)
Definition: los_cpup.c:541
LITE_OS_SEC_BSS STATIC UINT16 cpupInitFlg
Definition: los_cpup.c:124
LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllProcessAndTaskCpuUsageUnsafe(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len)
Definition: los_cpup.c:595
LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqStart(UINT16 cpuid)
Definition: los_cpup.c:635
LITE_OS_SEC_BSS STATIC UINT64 cpupIntTimeStart[LOSCFG_KERNEL_CORE_NUM]
Definition: los_cpup.c:133
LITE_OS_SEC_BSS STATIC UINT32 cpupMaxNum
Definition: los_cpup.c:126
LITE_OS_SEC_BSS STATIC UINT64 cpuHistoryTime[OS_CPUP_HISTORY_RECORD_NUM+1]
Definition: los_cpup.c:128
LITE_OS_SEC_BSS STATIC UINT16 cpupSwtmrID
监测CPU使用情况定时器s
Definition: los_cpup.c:123
STATIC UINT32 OsHistorySysCpuUsageUnsafe(UINT16 mode)
Definition: los_cpup.c:407
LITE_OS_SEC_TEXT_MINOR OsIrqCpupCB * OsGetIrqCpupArrayBase(VOID)
Definition: los_cpup.c:673
VOID OsCpupCycleEndStart(UINT32 runTaskID, UINT32 newTaskID)
Definition: los_cpup.c:331
LOS_MODULE_INIT(OsCpupGuardCreator, LOS_INIT_LEVEL_KMOD_TASK)
LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllIrqCpuUsageUnsafe(UINT16 mode, CPUP_INFO_S *cpupInfo, UINT32 len)
Definition: los_cpup.c:678
STATIC INLINE UINT32 OsCalculateCpupUsage(const OsCpupBase *cpup, UINT16 pos, UINT16 prePos, UINT64 allCycle)
Definition: los_cpup.c:396
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsCpupGetPos(UINT16 mode, UINT16 *curPosPointer, UINT16 *prePosPointer)
Definition: los_cpup.c:363
LITE_OS_SEC_BSS STATIC UINT16 cpupHisPos
Definition: los_cpup.c:127
STATIC UINT32 OsHistoryTaskCpuUsageUnsafe(UINT32 tid, UINT16 mode)
Definition: los_cpup.c:496
LITE_OS_SEC_BSS STATIC UINT64 cpupStartCycles
记录
Definition: los_cpup.c:130
LITE_OS_SEC_BSS STATIC UINT32 runningTasks[LOSCFG_KERNEL_CORE_NUM]
Definition: los_cpup.c:129
STATIC UINT32 OsHistoryProcessCpuUsageUnsafe(UINT32 pid, UINT16 mode)
Definition: los_cpup.c:447
LITE_OS_SEC_TEXT_INIT UINT32 OsCpupGuardCreator(VOID)
创建cpu使用统计定时器
Definition: los_cpup.c:226
LITE_OS_SEC_BSS UINT64 timeInIrqSwitch[LOSCFG_KERNEL_CORE_NUM]
Definition: los_cpup.c:132
LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqEnd(UINT16 cpuid, UINT32 intNum)
Definition: los_cpup.c:645
LITE_OS_SEC_BSS OsIrqCpupCB * g_irqCpup
Definition: los_cpup.c:125
LITE_OS_SEC_TEXT_INIT UINT32 OsCpupInit(VOID)
Definition: los_cpup.c:242
STATIC INLINE UINT32 ArchCurrCpuid(VOID)
Definition: los_hw_cpu.h:168
LITE_OS_SEC_TEXT UINT32 OsGetIdleProcessID(VOID)
获取内核态空闲进程
Definition: los_process.c:2254
LITE_OS_SEC_BSS UINT32 g_processMaxNum
进程最大数量,默认64个
Definition: los_process.c:86
STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB)
STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB)
任务是否在使用
Definition: los_task_pri.h:255
unsigned short UINT16
Definition: los_typedef.h:56
long unsigned int UINT64
Definition: los_typedef.h:66
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
UINT64 allTime
Definition: los_cpup_pri.h:50
UINT64 startTime
Definition: los_cpup_pri.h:51
UINT64 historyTime[OS_CPUP_HISTORY_RECORD_NUM+1]
Definition: los_cpup_pri.h:52
UINT64 count
Definition: los_cpup_pri.h:64
OsCpupBase cpup
Definition: los_cpup_pri.h:65
UINT64 allTime
Definition: los_cpup_pri.h:62
UINT64 timeMax
Definition: los_cpup_pri.h:63
UINT16 status
Definition: los_cpup_pri.h:61
OsCpupBase * processCpup
OsCpupBase taskCpup
UINT32 processID
UINT32 usage
Definition: los_cpup.h:124
UINT16 status
Definition: los_cpup.h:123