• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2023 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 "stdlib.h"
33 #include "los_config.h"
34 #include "los_exc.h"
35 #include "los_memstat_pri.h"
36 #include "los_sem_pri.h"
37 #include "los_seq_buf.h"
38 #include "los_task_pri.h"
39 #ifdef LOSCFG_SHELL
40 #include "shcmd.h"
41 #include "shell.h"
42 #endif
43 #ifdef LOSCFG_KERNEL_CPUP
44 #include "los_cpup_pri.h"
45 #endif
46 #ifdef LOSCFG_SAVE_EXCINFO
47 #include "los_excinfo_pri.h"
48 #endif
49 #include "los_process_pri.h"
50 #ifdef LOSCFG_FS_VFS
51 #include "fs/file.h"
52 #endif
53 #include "los_sched_pri.h"
54 #include "los_swtmr_pri.h"
55 #include "los_info_pri.h"
56 #ifdef LOSCFG_SCHED_DEBUG
57 #include "los_statistics_pri.h"
58 #endif
59 
60 #define OS_PROCESS_MEM_INFO 0x2U
61 #undef SHOW
62 #ifdef LOSCFG_FS_VFS
63 #if defined(LOSCFG_BLACKBOX) && defined(LOSCFG_SAVE_EXCINFO)
64 #define SaveExcInfo(arg, ...) WriteExcInfoToBuf(arg, ##__VA_ARGS__)
65 #else
66 #define SaveExcInfo(arg, ...)
67 #endif
68 #define SHOW(arg...) do {                                    \
69     if (seqBuf != NULL) {                                    \
70         (void)LosBufPrintf((struct SeqBuf *)seqBuf, ##arg);  \
71     } else {                                                 \
72         PRINTK(arg);                                         \
73     }                                                        \
74     SaveExcInfo(arg);                                        \
75 } while (0)
76 #else
77 #define SHOW(arg...) PRINTK(arg)
78 #endif
79 
80 #define CPUP_MULT LOS_CPUP_PRECISION_MULT
81 
ConvertProcessModeToString(UINT16 mode)82 STATIC UINT8 *ConvertProcessModeToString(UINT16 mode)
83 {
84     if (mode == OS_KERNEL_MODE) {
85         return (UINT8 *)"kernel";
86     } else if (mode == OS_USER_MODE) {
87         return (UINT8 *)"user";
88     }
89 
90     return (UINT8 *)"ERROR";
91 }
92 
ConvertSchedPolicyToString(UINT16 policy)93 STATIC UINT8 *ConvertSchedPolicyToString(UINT16 policy)
94 {
95     if (policy == LOS_SCHED_RR) {
96         return (UINT8 *)"RR";
97     } else if (policy == LOS_SCHED_FIFO) {
98         return (UINT8 *)"FIFO";
99     } else if (policy == LOS_SCHED_DEADLINE) {
100         return (UINT8 *)"EDF";
101     } else if (policy == LOS_SCHED_IDLE) {
102         return (UINT8 *)"IDLE";
103     }
104 
105     return (UINT8 *)"ERROR";
106 }
107 
ConvertProcessStatusToString(UINT16 status)108 STATIC UINT8 *ConvertProcessStatusToString(UINT16 status)
109 {
110     if (status & OS_PROCESS_STATUS_ZOMBIES) {
111         return (UINT8 *)"Zombies";
112     } else if (status & OS_PROCESS_STATUS_INIT) {
113         return (UINT8 *)"Init";
114     } else if (status & OS_PROCESS_STATUS_RUNNING) {
115         return (UINT8 *)"Running";
116     } else if (status & OS_PROCESS_STATUS_READY) {
117         return (UINT8 *)"Ready";
118     }
119     return (UINT8 *)"Pending";
120 }
121 
ProcessInfoTitle(VOID * seqBuf,UINT16 flag)122 STATIC VOID ProcessInfoTitle(VOID *seqBuf, UINT16 flag)
123 {
124     SHOW("\r\n  PID  PPID PGID   UID   Mode  Status Policy Priority MTID TTotal");
125     if (flag & OS_PROCESS_INFO_ALL) {
126 #ifdef LOSCFG_KERNEL_VM
127         if (flag & OS_PROCESS_MEM_INFO) {
128             SHOW(" VirtualMem ShareMem PhysicalMem");
129         }
130 #endif
131 #ifdef LOSCFG_KERNEL_CPUP
132         SHOW(" CPUUSE CPUUSE10s CPUUSE1s");
133 #endif /* LOSCFG_KERNEL_CPUP */
134     } else {
135 #ifdef LOSCFG_KERNEL_CPUP
136         SHOW(" CPUUSE10s");
137 #endif /* LOSCFG_KERNEL_CPUP */
138     }
139     SHOW(" PName\n");
140 }
141 
ProcessDataShow(const ProcessInfo * processInfo,VOID * seqBuf,UINT16 flag)142 STATIC VOID ProcessDataShow(const ProcessInfo *processInfo, VOID *seqBuf, UINT16 flag)
143 {
144     SHOW("%5u%6u%5d%6d%7s%8s%7s%9u%5u%7u", processInfo->pid, processInfo->ppid, processInfo->pgroupID,
145          processInfo->userID, ConvertProcessModeToString(processInfo->mode),
146          ConvertProcessStatusToString(processInfo->status),
147          ConvertSchedPolicyToString(processInfo->policy), processInfo->basePrio,
148          processInfo->threadGroupID, processInfo->threadNumber);
149 
150     if (flag & OS_PROCESS_INFO_ALL) {
151 #ifdef LOSCFG_KERNEL_VM
152         if (flag & OS_PROCESS_MEM_INFO) {
153             SHOW("%#11x%#9x%#12x", processInfo->virtualMem, processInfo->shareMem, processInfo->physicalMem);
154         }
155 #endif
156 #ifdef LOSCFG_KERNEL_CPUP
157         SHOW("%4u.%-2u%7u.%-2u%6u.%-2u ",
158              processInfo->cpupAllsUsage / CPUP_MULT, processInfo->cpupAllsUsage % CPUP_MULT,
159              processInfo->cpup10sUsage / CPUP_MULT, processInfo->cpup10sUsage % CPUP_MULT,
160              processInfo->cpup1sUsage / CPUP_MULT, processInfo->cpup1sUsage % CPUP_MULT);
161 #endif /* LOSCFG_KERNEL_CPUP */
162     } else {
163 #ifdef LOSCFG_KERNEL_CPUP
164         SHOW("%7u.%-2u ", processInfo->cpup10sUsage / CPUP_MULT, processInfo->cpup10sUsage % CPUP_MULT);
165 #endif /* LOSCFG_KERNEL_CPUP */
166     }
167     SHOW("%-32s\n", processInfo->name);
168 }
169 
AllProcessDataShow(const ProcessInfo * pcbArray,VOID * seqBuf,UINT16 flag)170 STATIC VOID AllProcessDataShow(const ProcessInfo *pcbArray, VOID *seqBuf, UINT16 flag)
171 {
172     for (UINT32 pid = 1; pid < g_processMaxNum; ++pid) {
173         const ProcessInfo *processInfo = pcbArray + pid;
174         if (processInfo->status & OS_PROCESS_FLAG_UNUSED) {
175             continue;
176         }
177         ProcessDataShow(processInfo, seqBuf, flag);
178     }
179 }
180 
ProcessInfoShow(const ProcessInfo * pcbArray,VOID * seqBuf,UINT16 flag)181 STATIC VOID ProcessInfoShow(const ProcessInfo *pcbArray, VOID *seqBuf, UINT16 flag)
182 {
183 #ifdef LOSCFG_KERNEL_CPUP
184     UINT32 pid = OS_KERNEL_IDLE_PROCESS_ID;
185     UINT32 sysUsage = LOS_CPUP_PRECISION - pcbArray[pid].cpup10sUsage;
186     SHOW("\n  allCpu(%%): %4u.%02u sys, %4u.%02u idle\n", sysUsage / CPUP_MULT, sysUsage % CPUP_MULT,
187          pcbArray[pid].cpup10sUsage / CPUP_MULT, pcbArray[pid].cpup10sUsage % CPUP_MULT);
188 #endif
189 
190     ProcessInfoTitle(seqBuf, flag);
191     AllProcessDataShow(pcbArray, seqBuf, flag);
192 }
193 
ConvertTaskStatusToString(UINT16 taskStatus)194 STATIC UINT8 *ConvertTaskStatusToString(UINT16 taskStatus)
195 {
196     if (taskStatus & OS_TASK_STATUS_INIT) {
197         return (UINT8 *)"Init";
198     } else if (taskStatus & OS_TASK_STATUS_RUNNING) {
199         return (UINT8 *)"Running";
200     } else if (taskStatus & OS_TASK_STATUS_READY) {
201         return (UINT8 *)"Ready";
202     } else if (taskStatus & OS_TASK_STATUS_FROZEN) {
203         return (UINT8 *)"Frozen";
204     } else if (taskStatus & OS_TASK_STATUS_SUSPENDED) {
205         return (UINT8 *)"Suspended";
206     } else if (taskStatus & OS_TASK_STATUS_DELAY) {
207         return (UINT8 *)"Delay";
208     } else if (taskStatus & OS_TASK_STATUS_PEND_TIME) {
209         return (UINT8 *)"PendTime";
210     } else if (taskStatus & OS_TASK_STATUS_PENDING) {
211         return (UINT8 *)"Pending";
212     } else if (taskStatus & OS_TASK_STATUS_EXIT) {
213         return (UINT8 *)"Exit";
214     }
215 
216     return (UINT8 *)"Invalid";
217 }
218 
219 #ifdef LOSCFG_SHELL_CMD_DEBUG
220 #define OS_PEND_REASON_MAX_LEN 20
221 
CheckTaskWaitFlag(const TaskInfo * taskInfo,UINTPTR * lockID)222 STATIC CHAR *CheckTaskWaitFlag(const TaskInfo *taskInfo, UINTPTR *lockID)
223 {
224     *lockID = taskInfo->waitID;
225     switch (taskInfo->waitFlag) {
226         case OS_TASK_WAIT_PROCESS:
227             return "Child";
228         case OS_TASK_WAIT_GID:
229             return "PGroup";
230         case OS_TASK_WAIT_ANYPROCESS:
231             return "AnyChild";
232         case OS_TASK_WAIT_SEM:
233             return "Semaphore";
234         case OS_TASK_WAIT_QUEUE:
235             return "Queue";
236         case OS_TASK_WAIT_JOIN:
237             return "Join";
238         case OS_TASK_WAIT_SIGNAL:
239             return "Signal";
240         case OS_TASK_WAIT_LITEIPC:
241             return "LiteIPC";
242         case OS_TASK_WAIT_MUTEX:
243             return "Mutex";
244         case OS_TASK_WAIT_EVENT:
245             return "Event";
246         case OS_TASK_WAIT_FUTEX:
247             return "Futex";
248         case OS_TASK_WAIT_COMPLETE:
249             return "Complete";
250         default:
251             break;
252     }
253 
254     return NULL;
255 }
256 
TaskPendingReasonInfoGet(const TaskInfo * taskInfo,CHAR * pendReason,UINT32 maxLen,UINTPTR * lockID)257 STATIC VOID TaskPendingReasonInfoGet(const TaskInfo *taskInfo, CHAR *pendReason, UINT32 maxLen, UINTPTR *lockID)
258 {
259     CHAR *reason = NULL;
260 
261     if (!(taskInfo->status & OS_TASK_STATUS_PENDING)) {
262         reason = (CHAR *)ConvertTaskStatusToString(taskInfo->status);
263         goto EXIT;
264     }
265 
266     reason = CheckTaskWaitFlag(taskInfo, lockID);
267     if (reason == NULL) {
268         reason = "Others";
269     }
270 
271     if (taskInfo->taskMux != NULL) {
272         *lockID = (UINTPTR)taskInfo->taskMux;
273         LosTaskCB *owner = ((LosMux *)taskInfo->taskMux)->owner;
274         if (owner != NULL) {
275             if (snprintf_s(pendReason, maxLen, maxLen - 1, "Mutex-%u", owner->taskID) == EOK) {
276                 return;
277             }
278         }
279     }
280 
281 EXIT:
282     if (strcpy_s(pendReason, maxLen, reason) != EOK) {
283         PRINT_ERR("Get pend reason copy failed !\n");
284     }
285 }
286 #endif
287 
TaskInfoTitle(VOID * seqBuf,UINT16 flag)288 STATIC VOID TaskInfoTitle(VOID *seqBuf, UINT16 flag)
289 {
290     SHOW("\r\n  TID  PID");
291 #ifdef LOSCFG_KERNEL_SMP
292     SHOW(" Affi CPU");
293 #endif
294     SHOW("    Status Policy Priority StackSize WaterLine");
295     if (flag & OS_PROCESS_INFO_ALL) {
296 #ifdef LOSCFG_KERNEL_CPUP
297         SHOW(" CPUUSE CPUUSE10s CPUUSE1s");
298 #endif /* LOSCFG_KERNEL_CPUP */
299 #ifdef LOSCFG_SHELL_CMD_DEBUG
300         SHOW("   StackPoint  TopOfStack PendReason     LockID");
301 #endif
302     } else {
303 #ifdef LOSCFG_KERNEL_CPUP
304         SHOW("  CPUUSE10s ");
305 #endif /* LOSCFG_KERNEL_CPUP */
306     }
307     SHOW("  TaskName\n");
308 }
309 
TaskInfoDataShow(const TaskInfo * taskInfo,VOID * seqBuf,UINT16 flag)310 STATIC VOID TaskInfoDataShow(const TaskInfo *taskInfo, VOID *seqBuf, UINT16 flag)
311 {
312 #ifdef LOSCFG_SHELL_CMD_DEBUG
313     UINTPTR lockID = 0;
314     CHAR pendReason[OS_PEND_REASON_MAX_LEN] = { 0 };
315 #endif
316     SHOW(" %4u%5u", taskInfo->tid, taskInfo->pid);
317 
318 #ifdef LOSCFG_KERNEL_SMP
319     SHOW("%#5x%4d ", taskInfo->cpuAffiMask, (INT16)(taskInfo->currCpu));
320 #endif
321     SHOW("%9s%7s%9u%#10x%#10x", ConvertTaskStatusToString(taskInfo->status),
322          ConvertSchedPolicyToString(taskInfo->policy), taskInfo->priority, taskInfo->stackSize, taskInfo->waterLine);
323     if (flag & OS_PROCESS_INFO_ALL) {
324 #ifdef LOSCFG_KERNEL_CPUP
325         SHOW("%4u.%-2u%7u.%-2u%6u.%-2u ", taskInfo->cpupAllsUsage / CPUP_MULT, taskInfo->cpupAllsUsage % CPUP_MULT,
326              taskInfo->cpup10sUsage / CPUP_MULT, taskInfo->cpup10sUsage % CPUP_MULT,
327              taskInfo->cpup1sUsage / CPUP_MULT, taskInfo->cpup1sUsage % CPUP_MULT);
328 #endif /* LOSCFG_KERNEL_CPUP */
329 #ifdef LOSCFG_SHELL_CMD_DEBUG
330         TaskPendingReasonInfoGet(taskInfo, pendReason, OS_PEND_REASON_MAX_LEN, &lockID);
331         SHOW("%#12x%#12x%11s%#11x", taskInfo->stackPoint, taskInfo->topOfStack, pendReason, lockID);
332 #endif
333     } else {
334 #ifdef LOSCFG_KERNEL_CPUP
335         SHOW("%8u.%-2u ", taskInfo->cpup10sUsage / CPUP_MULT, taskInfo->cpup10sUsage % CPUP_MULT);
336 #endif /* LOSCFG_KERNEL_CPUP */
337     }
338     SHOW("  %-32s\n", taskInfo->name);
339 }
340 
ProcessTaskInfoDataShow(const ProcessThreadInfo * allTaskInfo,VOID * seqBuf,UINT16 flag)341 STATIC VOID ProcessTaskInfoDataShow(const ProcessThreadInfo *allTaskInfo, VOID *seqBuf, UINT16 flag)
342 {
343     for (UINT32 index = 0; index < allTaskInfo->threadCount; index++) {
344         const TaskInfo *taskInfo = &allTaskInfo->taskInfo[index];
345         TaskInfoDataShow(taskInfo, seqBuf, flag);
346     }
347 }
348 
TaskInfoData(const ProcessThreadInfo * allTaskInfo,VOID * seqBuf,UINT16 flag)349 STATIC VOID TaskInfoData(const ProcessThreadInfo *allTaskInfo, VOID *seqBuf, UINT16 flag)
350 {
351     ProcessInfoTitle(seqBuf, flag);
352     ProcessDataShow(&allTaskInfo->processInfo, seqBuf, flag);
353     TaskInfoTitle(seqBuf, flag);
354     ProcessTaskInfoDataShow(allTaskInfo, seqBuf, flag);
355 }
356 
OsShellCmdTskInfoGet(UINT32 processID,VOID * seqBuf,UINT16 flag)357 LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 processID, VOID *seqBuf, UINT16 flag)
358 {
359     UINT32 size;
360 
361     if (processID == OS_ALL_TASK_MASK) {
362         size = sizeof(ProcessInfo) * g_processMaxNum;
363         ProcessInfo *pcbArray = (ProcessInfo *)LOS_MemAlloc(m_aucSysMem1, size);
364         if (pcbArray == NULL) {
365             PRINT_ERR("Memory is not enough to save task info!\n");
366             return LOS_NOK;
367         }
368         (VOID)memset_s(pcbArray, size, 0, size);
369         OsGetAllProcessInfo(pcbArray);
370         ProcessInfoShow((const ProcessInfo *)pcbArray, seqBuf, flag);
371         (VOID)LOS_MemFree(m_aucSysMem1, pcbArray);
372         return LOS_OK;
373     }
374 
375     ProcessThreadInfo *threadInfo = (ProcessThreadInfo *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessThreadInfo));
376     if (threadInfo == NULL) {
377         return LOS_NOK;
378     }
379     (VOID)memset_s(threadInfo, sizeof(ProcessThreadInfo), 0, sizeof(ProcessThreadInfo));
380 
381     if (OsGetProcessThreadInfo(processID, threadInfo) != LOS_OK) {
382         (VOID)LOS_MemFree(m_aucSysMem1, threadInfo);
383         return LOS_NOK;
384     }
385 
386     TaskInfoData(threadInfo, seqBuf, flag);
387     (VOID)LOS_MemFree(m_aucSysMem1, threadInfo);
388     return LOS_OK;
389 }
390 
OsShellCmdDumpTask(INT32 argc,const CHAR ** argv)391 LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv)
392 {
393     INT32 processID = OS_ALL_TASK_MASK;
394     UINT32 flag = 0;
395 #ifdef LOSCFG_KERNEL_VM
396     flag |= OS_PROCESS_MEM_INFO;
397 #endif
398 
399     if (argc == 0) {
400         return OsShellCmdTskInfoGet((UINT32)processID, NULL, flag);
401     }
402 
403     if (argc >= 3) { /* 3: The task shell name restricts the parameters */
404         goto TASK_HELP;
405     }
406 
407     if ((argc == 1) && (strcmp("-a", argv[0]) == 0)) {
408         flag |= OS_PROCESS_INFO_ALL;
409     } else if ((argc == 2) && (strcmp("-p", argv[0]) == 0)) { /* 2: Two parameters */
410         flag |= OS_PROCESS_INFO_ALL;
411         processID = atoi(argv[1]);
412 #ifdef LOSCFG_SCHED_DEBUG
413 #ifdef LOSCFG_SCHED_TICK_DEBUG
414     } else if (strcmp("-i", argv[0]) == 0) {
415         if (!OsShellShowTickResponse()) {
416             return LOS_OK;
417         }
418         goto TASK_HELP;
419 #endif
420 #ifdef LOSCFG_SCHED_HPF_DEBUG
421     } else if (strcmp("-t", argv[0]) == 0) {
422         if (!OsShellShowSchedStatistics()) {
423             return LOS_OK;
424         }
425         goto TASK_HELP;
426 #endif
427 #ifdef LOSCFG_SCHED_EDF_DEBUG
428     } else if (strcmp("-e", argv[0]) == 0) {
429         if (!OsShellShowEdfSchedStatistics()) {
430             return LOS_OK;
431         }
432         goto TASK_HELP;
433 #endif
434 #endif
435     } else {
436         goto TASK_HELP;
437     }
438 
439     return OsShellCmdTskInfoGet((UINT32)processID, NULL, flag);
440 
441 TASK_HELP:
442     PRINTK("Unknown option: %s\n", argv[0]);
443     PRINTK("Usage:\n");
444     PRINTK(" task          --- Basic information about all created processes.\n");
445     PRINTK(" task -a       --- Complete information about all created processes.\n");
446     PRINTK(" task -p [pid] --- Complete information about specifies processes and its task.\n");
447     return LOS_NOK;
448 }
449 
450 #ifdef LOSCFG_SHELL
451 SHELLCMD_ENTRY(task_shellcmd, CMD_TYPE_EX, "task", 1, (CmdCallBackFunc)OsShellCmdDumpTask);
452 #endif
453 
454