• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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