1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "los_cpup.h"
33 #include "securec.h"
34 #include "los_memory.h"
35 #include "los_debug.h"
36 #include "los_tick.h"
37
38 #if (LOSCFG_BASE_CORE_SWTMR == 1)
39 #include "los_swtmr.h"
40 #endif
41
42 #if (LOSCFG_CPUP_INCLUDE_IRQ == 1)
43 #include "los_arch_interrupt.h"
44 #endif
45
46 #if (LOSCFG_BASE_CORE_CPUP == 1)
47 /**
48 * @ingroup los_cpup
49 * CPU usage-type macro: used for tasks.
50 */
51 #define OS_THREAD_TYPE_TASK 0
52
53 /**
54 * @ingroup los_cpup
55 * CPU usage-type macro: used for hardware interrupts.
56 */
57 #define OS_THREAD_TYPE_HWI 1
58
59 #define OS_CPUP_RECORD_PERIOD (g_sysClock)
60
61 #define OS_SYS_CYCLE_TO_US(cycle) ((cycle) / (g_sysClock)) * OS_SYS_US_PER_SECOND + \
62 ((cycle) % (g_sysClock) * OS_SYS_US_PER_SECOND / (g_sysClock))
63
64 LITE_OS_SEC_BSS UINT16 g_cpupInitFlg = 0;
65 LITE_OS_SEC_BSS OsCpupCB *g_cpup = NULL;
66 LITE_OS_SEC_BSS UINT64 g_lastRecordTime;
67 LITE_OS_SEC_BSS UINT16 g_hisPos; /* current Sampling point of historyTime */
68
69 #if (LOSCFG_CPUP_INCLUDE_IRQ == 1)
70 LITE_OS_SEC_BSS UINT16 g_irqCpupInitFlg = 0;
71 LITE_OS_SEC_BSS UINT16 g_irqHisPos = 0; /* current Sampling point of historyTime */
72 LITE_OS_SEC_BSS UINT64 g_irqLastRecordTime;
73 LITE_OS_SEC_BSS OsIrqCpupCB *g_irqCpup = NULL;
74 LITE_OS_SEC_BSS STATIC UINT64 g_cpuHistoryTime[OS_CPUP_HISTORY_RECORD_NUM];
75 #define OS_CPUP_USED 0x1U
76
77 #if (LOSCFG_BASE_CORE_SWTMR == 1)
OsCpupGuard(VOID)78 LITE_OS_SEC_TEXT_INIT VOID OsCpupGuard(VOID)
79 {
80 UINT16 prevPos;
81 UINT32 loop;
82 UINT32 intSave;
83
84 intSave = LOS_IntLock();
85 prevPos = g_irqHisPos;
86
87 if (g_irqHisPos == OS_CPUP_HISTORY_RECORD_NUM - 1) {
88 g_irqHisPos = 0;
89 } else {
90 g_irqHisPos++;
91 }
92
93 g_cpuHistoryTime[prevPos] = 0;
94 for (loop = 0; loop < LOSCFG_PLATFORM_HWI_LIMIT; loop++) {
95 if (g_irqCpup[loop].status != OS_CPUP_USED) {
96 continue;
97 }
98 g_irqCpup[loop].historyTime[prevPos] = g_irqCpup[loop].allTime;
99 g_cpuHistoryTime[prevPos] += g_irqCpup[loop].allTime;
100 }
101 LOS_IntRestore(intSave);
102
103 return;
104 }
105
OsCpupGuardCreator(VOID)106 LITE_OS_SEC_TEXT_INIT UINT32 OsCpupGuardCreator(VOID)
107 {
108 UINT32 cpupSwtmrID;
109 #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
110 (VOID)LOS_SwtmrCreate(LOSCFG_BASE_CORE_TICK_PER_SECOND, LOS_SWTMR_MODE_PERIOD,
111 (SWTMR_PROC_FUNC)OsCpupGuard, &cpupSwtmrID, 0,
112 OS_SWTMR_ROUSES_ALLOW, OS_SWTMR_ALIGN_INSENSITIVE);
113 #else
114 (VOID)LOS_SwtmrCreate(LOSCFG_BASE_CORE_TICK_PER_SECOND, LOS_SWTMR_MODE_PERIOD,
115 (SWTMR_PROC_FUNC)OsCpupGuard, &cpupSwtmrID, 0);
116 #endif
117
118 (VOID)LOS_SwtmrStart(cpupSwtmrID);
119
120 return LOS_OK;
121 }
122 #endif
123
124 /*****************************************************************************
125 Function : OsCpupDaemonInit
126 Description: initialization of CPUP Daemon
127 Input : None
128 Return : LOS_OK or Error Information
129 *****************************************************************************/
OsCpupDaemonInit()130 LITE_OS_SEC_TEXT_INIT UINT32 OsCpupDaemonInit()
131 {
132 #if (LOSCFG_BASE_CORE_SWTMR == 1)
133 (VOID)OsCpupGuardCreator();
134 g_irqCpupInitFlg = 1;
135 #endif
136
137 return LOS_OK;
138 }
139 #endif
140
141 /*****************************************************************************
142 Function : OsCpupInit
143 Description: initialization of CPUP
144 Input : None
145 Return : LOS_OK or Error Information
146 *****************************************************************************/
OsCpupInit()147 LITE_OS_SEC_TEXT_INIT UINT32 OsCpupInit()
148 {
149 UINT32 size;
150 CHAR *cpupMem = NULL;
151
152 size = g_taskMaxNum * sizeof(OsCpupCB);
153 #if (LOSCFG_CPUP_INCLUDE_IRQ == 1)
154 size += LOSCFG_PLATFORM_HWI_LIMIT * sizeof(OsIrqCpupCB);
155 #endif
156
157 cpupMem = LOS_MemAlloc(m_aucSysMem0, size);
158 if (cpupMem == NULL) {
159 return LOS_ERRNO_CPUP_NO_MEMORY;
160 }
161 (VOID)memset_s(cpupMem, size, 0, size);
162
163 g_cpup = (OsCpupCB *)cpupMem;
164 #if (LOSCFG_CPUP_INCLUDE_IRQ == 1)
165 g_irqCpup = (OsIrqCpupCB *)(cpupMem + g_taskMaxNum * sizeof(OsCpupCB));
166 #endif
167
168 g_cpupInitFlg = 1;
169
170 return LOS_OK;
171 }
172
173 /* The calculation time unit is changed to us to decouple the influence of
174 * system frequency modulation on CPUP
175 */
CpupTimeUsGet(VOID)176 STATIC UINT64 CpupTimeUsGet(VOID)
177 {
178 UINT64 time = LOS_SysCycleGet();
179 return OS_SYS_CYCLE_TO_US(time);
180 }
181
182 /*****************************************************************************
183 Function : OsTskCycleStart
184 Description: start task to get cycles count in current task beginning
185 Input : None
186 Return : None
187 *****************************************************************************/
OsTskCycleStart(VOID)188 LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleStart(VOID)
189 {
190 UINT32 taskID;
191
192 if (g_cpupInitFlg == 0) {
193 return;
194 }
195
196 taskID = g_losTask.newTask->taskID;
197 g_cpup[taskID].cpupID = taskID;
198 g_cpup[taskID].startTime = CpupTimeUsGet();
199
200 return;
201 }
202
203 /*****************************************************************************
204 Function : OsTskCycleEnd
205 Description: quit task and get cycle count
206 Input : None
207 Return : None
208 *****************************************************************************/
OsTskCycleEnd(VOID)209 LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleEnd(VOID)
210 {
211 UINT32 taskID;
212 UINT64 cpuTime;
213
214 if (g_cpupInitFlg == 0) {
215 return;
216 }
217
218 taskID = g_losTask.runTask->taskID;
219
220 if (g_cpup[taskID].startTime == 0) {
221 return;
222 }
223
224 cpuTime = CpupTimeUsGet();
225 if (cpuTime < g_cpup[taskID].startTime) {
226 cpuTime += OS_US_PER_TICK;
227 }
228
229 g_cpup[taskID].allTime += (cpuTime - g_cpup[taskID].startTime);
230 g_cpup[taskID].startTime = 0;
231
232 return;
233 }
234
235 /*****************************************************************************
236 Function : OsTskCycleEndStart
237 Description: start task to get cycles count in current task ending
238 Input : None
239 Return : None
240 *****************************************************************************/
OsTskCycleEndStart(VOID)241 LITE_OS_SEC_TEXT_MINOR VOID OsTskCycleEndStart(VOID)
242 {
243 UINT32 taskID;
244 UINT64 cpuTime;
245 UINT16 loopNum;
246
247 if (g_cpupInitFlg == 0) {
248 return;
249 }
250
251 taskID = g_losTask.runTask->taskID;
252 cpuTime = CpupTimeUsGet();
253
254 if (g_cpup[taskID].startTime != 0) {
255 if (cpuTime < g_cpup[taskID].startTime) {
256 cpuTime += OS_US_PER_TICK;
257 }
258
259 g_cpup[taskID].allTime += (cpuTime - g_cpup[taskID].startTime);
260 g_cpup[taskID].startTime = 0;
261 }
262
263 taskID = g_losTask.newTask->taskID;
264 g_cpup[taskID].cpupID = taskID;
265 g_cpup[taskID].startTime = cpuTime;
266
267 if ((cpuTime - g_lastRecordTime) > OS_CPUP_RECORD_PERIOD) {
268 g_lastRecordTime = cpuTime;
269
270 for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
271 g_cpup[loopNum].historyTime[g_hisPos] = g_cpup[loopNum].allTime;
272 }
273
274 if (g_hisPos == (OS_CPUP_HISTORY_RECORD_NUM - 1)) {
275 g_hisPos = 0;
276 } else {
277 g_hisPos++;
278 }
279 }
280
281 return;
282 }
283
OsGetPrePos(UINT16 curPos)284 LITE_OS_SEC_TEXT_MINOR STATIC INLINE UINT16 OsGetPrePos(UINT16 curPos)
285 {
286 return (curPos == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : (curPos - 1);
287 }
288
OsGetPositions(UINT16 mode,UINT16 * curPosAddr,UINT16 * prePosAddr)289 LITE_OS_SEC_TEXT_MINOR STATIC VOID OsGetPositions(UINT16 mode, UINT16* curPosAddr, UINT16* prePosAddr)
290 {
291 UINT16 curPos;
292 UINT16 prePos = 0;
293
294 curPos = g_hisPos;
295
296 if (mode == CPUP_IN_1S) {
297 curPos = OsGetPrePos(curPos);
298 prePos = OsGetPrePos(curPos);
299 } else if (mode == CPUP_LESS_THAN_1S) {
300 curPos = OsGetPrePos(curPos);
301 }
302
303 *curPosAddr = curPos;
304 *prePosAddr = prePos;
305 }
306
307 /*****************************************************************************
308 Function : LOS_SysCpuUsage
309 Description: get current CPU usage
310 Input : None
311 Return : cpupRet:current CPU usage
312 *****************************************************************************/
LOS_SysCpuUsage(VOID)313 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_SysCpuUsage(VOID)
314 {
315 UINT64 cpuTimeAll = 0;
316 UINT32 cpupRet = 0;
317 UINT16 loopNum;
318 UINT32 intSave;
319
320 if (g_cpupInitFlg == 0) {
321 return LOS_ERRNO_CPUP_NO_INIT;
322 }
323
324 // get end time of current task
325 intSave = LOS_IntLock();
326 OsTskCycleEnd();
327
328 for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
329 cpuTimeAll += g_cpup[loopNum].allTime;
330 }
331
332 if (cpuTimeAll) {
333 cpupRet = LOS_CPUP_PRECISION - (UINT32)((LOS_CPUP_PRECISION *
334 g_cpup[g_idleTaskID].allTime) / cpuTimeAll);
335 }
336
337 OsTskCycleStart();
338 LOS_IntRestore(intSave);
339
340 return cpupRet;
341 }
342
343 /*****************************************************************************
344 Function : LOS_HistorySysCpuUsage
345 Description: get CPU usage history
346 Input : mode: mode,0 = usage in 10s,1 = usage in last 1s, else = less than 1s
347 Return : cpupRet:CPU usage history
348 *****************************************************************************/
LOS_HistorySysCpuUsage(UINT16 mode)349 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistorySysCpuUsage(UINT16 mode)
350 {
351 UINT64 cpuTimeAll = 0;
352 UINT64 idleCycleAll = 0;
353 UINT32 cpupRet = 0;
354 UINT16 loopNum;
355 UINT16 curPos;
356 UINT16 prePos = 0;
357 UINT32 intSave;
358
359 if (g_cpupInitFlg == 0) {
360 return LOS_ERRNO_CPUP_NO_INIT;
361 }
362
363 // get end time of current task
364 intSave = LOS_IntLock();
365 OsTskCycleEnd();
366
367 OsGetPositions(mode, &curPos, &prePos);
368
369 for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
370 if (mode == CPUP_IN_1S) {
371 cpuTimeAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
372 } else {
373 cpuTimeAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
374 }
375 }
376
377 if (mode == CPUP_IN_1S) {
378 idleCycleAll += g_cpup[g_idleTaskID].historyTime[curPos] -
379 g_cpup[g_idleTaskID].historyTime[prePos];
380 } else {
381 idleCycleAll += g_cpup[g_idleTaskID].allTime - g_cpup[g_idleTaskID].historyTime[curPos];
382 }
383
384 if (cpuTimeAll) {
385 cpupRet = (LOS_CPUP_PRECISION - (UINT32)((LOS_CPUP_PRECISION * idleCycleAll) / cpuTimeAll));
386 }
387
388 OsTskCycleStart();
389 LOS_IntRestore(intSave);
390
391 return cpupRet;
392 }
393
394 /*****************************************************************************
395 Function : LOS_TaskCpuUsage
396 Description: get CPU usage of certain task
397 Input : taskID : task ID
398 Return : cpupRet:CPU usage of certain task
399 *****************************************************************************/
LOS_TaskCpuUsage(UINT32 taskID)400 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuUsage(UINT32 taskID)
401 {
402 UINT64 cpuTimeAll = 0;
403 UINT16 loopNum;
404 UINT32 intSave;
405 UINT32 cpupRet = 0;
406
407 if (g_cpupInitFlg == 0) {
408 return LOS_ERRNO_CPUP_NO_INIT;
409 }
410 if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) {
411 return LOS_ERRNO_CPUP_TSK_ID_INVALID;
412 }
413 if (g_cpup[taskID].cpupID != taskID) {
414 return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
415 }
416 if ((g_cpup[taskID].status & OS_TASK_STATUS_UNUSED) || (g_cpup[taskID].status == 0)) {
417 return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
418 }
419 intSave = LOS_IntLock();
420 OsTskCycleEnd();
421
422 /* get total Cycle */
423 for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
424 if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || (g_cpup[loopNum].status == 0)) {
425 continue;
426 }
427 cpuTimeAll += g_cpup[loopNum].allTime;
428 }
429
430 if (cpuTimeAll) {
431 cpupRet = (UINT32)((LOS_CPUP_PRECISION * g_cpup[taskID].allTime) / cpuTimeAll);
432 }
433
434 OsTskCycleStart();
435 LOS_IntRestore(intSave);
436
437 return cpupRet;
438 }
439
440 /*****************************************************************************
441 Function : LOS_HistoryTaskCpuUsage
442 Description: get CPU usage history of certain task
443 Input : taskID : task ID
444 : mode: mode,0 = usage in 10s,1 = usage in last 1s, else = less than 1s
445 Return : cpupRet:CPU usage history of task
446 *****************************************************************************/
LOS_HistoryTaskCpuUsage(UINT32 taskID,UINT16 mode)447 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskID, UINT16 mode)
448 {
449 UINT64 cpuTimeAll = 0;
450 UINT64 cpuTimeCurTsk = 0;
451 UINT16 loopNum, curPos;
452 UINT16 prePos = 0;
453 UINT32 intSave;
454 UINT32 cpupRet = 0;
455
456 if (g_cpupInitFlg == 0) {
457 return LOS_ERRNO_CPUP_NO_INIT;
458 }
459 if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) {
460 return LOS_ERRNO_CPUP_TSK_ID_INVALID;
461 }
462 if (g_cpup[taskID].cpupID != taskID) {
463 return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
464 }
465 if ((g_cpup[taskID].status & OS_TASK_STATUS_UNUSED) || (g_cpup[taskID].status == 0)) {
466 return LOS_ERRNO_CPUP_THREAD_NO_CREATED;
467 }
468 intSave = LOS_IntLock();
469 OsTskCycleEnd();
470
471 OsGetPositions(mode, &curPos, &prePos);
472
473 /* get total Cycle in history */
474 for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
475 if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) || (g_cpup[loopNum].status == 0)) {
476 continue;
477 }
478
479 if (mode == CPUP_IN_1S) {
480 cpuTimeAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
481 } else {
482 cpuTimeAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
483 }
484 }
485
486 if (mode == CPUP_IN_1S) {
487 cpuTimeCurTsk += g_cpup[taskID].historyTime[curPos] - g_cpup[taskID].historyTime[prePos];
488 } else {
489 cpuTimeCurTsk += g_cpup[taskID].allTime - g_cpup[taskID].historyTime[curPos];
490 }
491 if (cpuTimeAll) {
492 cpupRet = (UINT32)((LOS_CPUP_PRECISION * cpuTimeCurTsk) / cpuTimeAll);
493 }
494
495 OsTskCycleStart();
496 LOS_IntRestore(intSave);
497
498 return cpupRet;
499 }
500
LOS_AllTaskCpuUsage(CPUP_INFO_S * cpupInfo,UINT16 mode)501 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_AllTaskCpuUsage(CPUP_INFO_S *cpupInfo, UINT16 mode)
502 {
503 UINT16 loopNum;
504 UINT16 curPos;
505 UINT16 prePos = 0;
506 UINT32 intSave;
507 UINT64 cpuTimeAll = 0;
508 UINT64 cpuTimeCurTsk = 0;
509
510 if (g_cpupInitFlg == 0) {
511 return LOS_ERRNO_CPUP_NO_INIT;
512 }
513
514 if (cpupInfo == NULL) {
515 return LOS_ERRNO_CPUP_TASK_PTR_NULL;
516 }
517
518 intSave = LOS_IntLock();
519 OsTskCycleEnd();
520
521 OsGetPositions(mode, &curPos, &prePos);
522
523 for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
524 if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) ||
525 (g_cpup[loopNum].status == 0)) {
526 continue;
527 }
528
529 if (mode == CPUP_IN_1S) {
530 cpuTimeAll += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
531 } else {
532 cpuTimeAll += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
533 }
534 }
535
536 for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
537 if ((g_cpup[loopNum].status & OS_TASK_STATUS_UNUSED) ||
538 (g_cpup[loopNum].status == 0)) {
539 continue;
540 }
541
542 if (mode == CPUP_IN_1S) {
543 cpuTimeCurTsk += g_cpup[loopNum].historyTime[curPos] - g_cpup[loopNum].historyTime[prePos];
544 } else {
545 cpuTimeCurTsk += g_cpup[loopNum].allTime - g_cpup[loopNum].historyTime[curPos];
546 }
547 cpupInfo[loopNum].usStatus = g_cpup[loopNum].status;
548 if (cpuTimeAll) {
549 cpupInfo[loopNum].uwUsage = (UINT32)((LOS_CPUP_PRECISION * cpuTimeCurTsk) / cpuTimeAll);
550 }
551
552 cpuTimeCurTsk = 0;
553 }
554
555 OsTskCycleStart();
556 LOS_IntRestore(intSave);
557
558 return LOS_OK;
559 }
560
561 /*****************************************************************************
562 Function : LOS_CpupUsageMonitor
563 Description: Get CPU usage history of certain task.
564 Input : type: cpup type, SYS_CPU_USAGE and TASK_CPU_USAGE
565 : taskID: task ID, Only in SYS_CPU_USAGE type, taskID is invalid
566 : mode: mode, CPUP_IN_10S = usage in 10s, CPUP_IN_1S = usage in last 1s, CPUP_LESS_THAN_1S = less than 1s
567 Return : LOS_OK on success, or OS_ERROR on failure
568 *****************************************************************************/
LOS_CpupUsageMonitor(CPUP_TYPE_E type,CPUP_MODE_E mode,UINT32 taskID)569 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CpupUsageMonitor(CPUP_TYPE_E type, CPUP_MODE_E mode, UINT32 taskID)
570 {
571 UINT32 ret;
572 LosTaskCB *taskCB = NULL;
573
574 switch (type) {
575 case SYS_CPU_USAGE:
576 if (mode == CPUP_IN_10S) {
577 PRINTK("\nSysCpuUsage in 10s: ");
578 } else if (mode == CPUP_IN_1S) {
579 PRINTK("\nSysCpuUsage in 1s: ");
580 } else {
581 PRINTK("\nSysCpuUsage in <1s: ");
582 }
583 ret = LOS_HistorySysCpuUsage(mode);
584 PRINTK("%d.%d", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
585 break;
586
587 case TASK_CPU_USAGE:
588 if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) {
589 PRINT_ERR("\nThe taskid is invalid.\n");
590 return OS_ERROR;
591 }
592 taskCB = OS_TCB_FROM_TID(taskID);
593 if ((taskCB->taskStatus & OS_TASK_STATUS_UNUSED)) {
594 PRINT_ERR("\nThe taskid is invalid.\n");
595 return OS_ERROR;
596 }
597 if (mode == CPUP_IN_10S) {
598 PRINTK("\nCPUusage of taskID %d in 10s: ", taskID);
599 } else if (mode == CPUP_IN_1S) {
600 PRINTK("\nCPUusage of taskID %d in 1s: ", taskID);
601 } else {
602 PRINTK("\nCPUusage of taskID %d in <1s: ", taskID);
603 }
604 ret = LOS_HistoryTaskCpuUsage(taskID, mode);
605 PRINTK("%u.%u", ret / LOS_CPUP_PRECISION_MULT, ret % LOS_CPUP_PRECISION_MULT);
606 break;
607
608 default:
609 PRINT_ERR("\nThe type is invalid.\n");
610 return OS_ERROR;
611 }
612
613 return LOS_OK;
614 }
615
616 #if (LOSCFG_CPUP_INCLUDE_IRQ == 1)
OsCpupIrqStart(UINT32 intNum)617 LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqStart(UINT32 intNum)
618 {
619 if (g_irqCpupInitFlg == 0) {
620 return;
621 }
622
623 g_irqCpup[intNum].startTime = CpupTimeUsGet();
624 return;
625 }
626
OsCpupIrqEnd(UINT32 intNum)627 LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqEnd(UINT32 intNum)
628 {
629 UINT64 cpuTime;
630 UINT64 usedTime;
631
632 if (g_irqCpupInitFlg == 0) {
633 return;
634 }
635
636 if (g_irqCpup[intNum].startTime == 0) {
637 return;
638 }
639
640 cpuTime = CpupTimeUsGet();
641 if (cpuTime < g_irqCpup[intNum].startTime) {
642 cpuTime += OS_US_PER_TICK;
643 }
644
645 g_irqCpup[intNum].cpupID = intNum;
646 g_irqCpup[intNum].status = OS_CPUP_USED;
647 usedTime = cpuTime - g_irqCpup[intNum].startTime;
648
649 if (g_irqCpup[intNum].count <= 1000) { /* 1000, Take 1000 samples */
650 g_irqCpup[intNum].allTime += usedTime;
651 g_irqCpup[intNum].count++;
652 } else {
653 g_irqCpup[intNum].allTime = 0;
654 g_irqCpup[intNum].count = 0;
655 }
656 g_irqCpup[intNum].startTime = 0;
657 if (usedTime > g_irqCpup[intNum].timeMax) {
658 g_irqCpup[intNum].timeMax = usedTime;
659 }
660 return;
661 }
662
OsGetIrqCpupArrayBase(VOID)663 LITE_OS_SEC_TEXT_MINOR OsIrqCpupCB *OsGetIrqCpupArrayBase(VOID)
664 {
665 return g_irqCpup;
666 }
667
OsGetIrqPositions(UINT16 mode,UINT16 * curPosAddr,UINT16 * prePosAddr)668 LITE_OS_SEC_TEXT_MINOR STATIC VOID OsGetIrqPositions(UINT16 mode, UINT16* curPosAddr, UINT16* prePosAddr)
669 {
670 UINT16 curPos;
671 UINT16 prePos = 0;
672
673 curPos = g_irqHisPos;
674
675 if (mode == CPUP_IN_1S) {
676 curPos = OsGetPrePos(curPos);
677 prePos = OsGetPrePos(curPos);
678 } else if (mode == CPUP_LESS_THAN_1S) {
679 curPos = OsGetPrePos(curPos);
680 }
681
682 *curPosAddr = curPos;
683 *prePosAddr = prePos;
684 }
685
OsGetIrqAllTime(VOID)686 LITE_OS_SEC_TEXT_MINOR STATIC UINT64 OsGetIrqAllTime(VOID)
687 {
688 INT32 i;
689 UINT64 cpuTimeAll = 0;
690 for (i = 0; i < OS_CPUP_HISTORY_RECORD_NUM; i++) {
691 cpuTimeAll += g_cpuHistoryTime[i];
692 }
693
694 return cpuTimeAll;
695 }
696
OsGetIrqAllHisTime(UINT32 num)697 LITE_OS_SEC_TEXT_MINOR STATIC UINT64 OsGetIrqAllHisTime(UINT32 num)
698 {
699 INT32 i;
700 UINT64 historyTime = 0;
701 for (i = 0; i < OS_CPUP_HISTORY_RECORD_NUM; i++) {
702 historyTime += g_irqCpup[num].historyTime[i];
703 }
704
705 return historyTime;
706 }
707
LOS_GetAllIrqCpuUsage(UINT16 mode,CPUP_INFO_S * cpupInfo)708 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_GetAllIrqCpuUsage(UINT16 mode, CPUP_INFO_S *cpupInfo)
709 {
710 UINT16 loopNum;
711 UINT16 curPos;
712 UINT16 prePos = 0;
713 UINT32 intSave;
714 UINT64 cpuTimeAll;
715 UINT64 cpuTimeCurIrq;
716
717 if (g_irqCpupInitFlg == 0) {
718 return LOS_ERRNO_CPUP_NO_INIT;
719 }
720
721 if (cpupInfo == NULL) {
722 return LOS_ERRNO_CPUP_TASK_PTR_NULL;
723 }
724
725 intSave = LOS_IntLock();
726
727 OsGetIrqPositions(mode, &curPos, &prePos);
728 if (mode == CPUP_IN_10S) {
729 cpuTimeAll = OsGetIrqAllTime();
730 } else {
731 cpuTimeAll = g_cpuHistoryTime[curPos] - g_cpuHistoryTime[prePos];
732 }
733
734 for (loopNum = 0; loopNum < LOSCFG_PLATFORM_HWI_LIMIT; loopNum++) {
735 if (g_irqCpup[loopNum].status != OS_CPUP_USED) {
736 continue;
737 }
738
739 cpupInfo[loopNum].usStatus = g_irqCpup[loopNum].status;
740
741 if (mode == CPUP_IN_10S) {
742 cpuTimeCurIrq = OsGetIrqAllHisTime(loopNum);
743 } else {
744 cpuTimeCurIrq = g_irqCpup[loopNum].historyTime[curPos] - g_irqCpup[loopNum].historyTime[prePos];
745 }
746
747 if (cpuTimeAll != 0) {
748 cpupInfo[loopNum].uwUsage = (UINT32)((LOS_CPUP_PRECISION * cpuTimeCurIrq) / cpuTimeAll);
749 }
750 }
751
752 LOS_IntRestore(intSave);
753 return LOS_OK;
754 }
755 #endif
756
757 #endif /* LOSCFG_BASE_CORE_CPUP */
758