454 lines
15 KiB
C
454 lines
15 KiB
C
/*
|
|
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
|
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
* conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
|
* provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
|
* to endorse or promote products derived from this software without specific prior written
|
|
* permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "stdlib.h"
|
|
#include "los_config.h"
|
|
#include "los_exc.h"
|
|
#include "los_memstat_pri.h"
|
|
#include "los_sem_pri.h"
|
|
#include "los_seq_buf.h"
|
|
#include "los_task_pri.h"
|
|
#ifdef LOSCFG_SHELL
|
|
#include "shcmd.h"
|
|
#include "shell.h"
|
|
#endif
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
#include "los_cpup_pri.h"
|
|
#endif
|
|
#ifdef LOSCFG_SAVE_EXCINFO
|
|
#include "los_excinfo_pri.h"
|
|
#endif
|
|
#include "los_process_pri.h"
|
|
#ifdef LOSCFG_FS_VFS
|
|
#include "fs/file.h"
|
|
#endif
|
|
#include "los_sched_pri.h"
|
|
#include "los_swtmr_pri.h"
|
|
#include "los_info_pri.h"
|
|
#ifdef LOSCFG_SCHED_DEBUG
|
|
#include "los_statistics_pri.h"
|
|
#endif
|
|
|
|
#define OS_PROCESS_MEM_INFO 0x2U
|
|
#undef SHOW
|
|
#ifdef LOSCFG_FS_VFS
|
|
#if defined(LOSCFG_BLACKBOX) && defined(LOSCFG_SAVE_EXCINFO)
|
|
#define SaveExcInfo(arg, ...) WriteExcInfoToBuf(arg, ##__VA_ARGS__)
|
|
#else
|
|
#define SaveExcInfo(arg, ...)
|
|
#endif
|
|
#define SHOW(arg...) do { \
|
|
if (seqBuf != NULL) { \
|
|
(void)LosBufPrintf((struct SeqBuf *)seqBuf, ##arg); \
|
|
} else { \
|
|
PRINTK(arg); \
|
|
} \
|
|
SaveExcInfo(arg); \
|
|
} while (0)
|
|
#else
|
|
#define SHOW(arg...) PRINTK(arg)
|
|
#endif
|
|
|
|
#define CPUP_MULT LOS_CPUP_PRECISION_MULT
|
|
|
|
STATIC UINT8 *ConvertProcessModeToString(UINT16 mode)
|
|
{
|
|
if (mode == OS_KERNEL_MODE) {
|
|
return (UINT8 *)"kernel";
|
|
} else if (mode == OS_USER_MODE) {
|
|
return (UINT8 *)"user";
|
|
}
|
|
|
|
return (UINT8 *)"ERROR";
|
|
}
|
|
|
|
STATIC UINT8 *ConvertSchedPolicyToString(UINT16 policy)
|
|
{
|
|
if (policy == LOS_SCHED_RR) {
|
|
return (UINT8 *)"RR";
|
|
} else if (policy == LOS_SCHED_FIFO) {
|
|
return (UINT8 *)"FIFO";
|
|
} else if (policy == LOS_SCHED_DEADLINE) {
|
|
return (UINT8 *)"EDF";
|
|
} else if (policy == LOS_SCHED_IDLE) {
|
|
return (UINT8 *)"IDLE";
|
|
}
|
|
|
|
return (UINT8 *)"ERROR";
|
|
}
|
|
|
|
STATIC UINT8 *ConvertProcessStatusToString(UINT16 status)
|
|
{
|
|
if (status & OS_PROCESS_STATUS_ZOMBIES) {
|
|
return (UINT8 *)"Zombies";
|
|
} else if (status & OS_PROCESS_STATUS_INIT) {
|
|
return (UINT8 *)"Init";
|
|
} else if (status & OS_PROCESS_STATUS_RUNNING) {
|
|
return (UINT8 *)"Running";
|
|
} else if (status & OS_PROCESS_STATUS_READY) {
|
|
return (UINT8 *)"Ready";
|
|
}
|
|
return (UINT8 *)"Pending";
|
|
}
|
|
|
|
STATIC VOID ProcessInfoTitle(VOID *seqBuf, UINT16 flag)
|
|
{
|
|
SHOW("\r\n PID PPID PGID UID Mode Status Policy Priority MTID TTotal");
|
|
if (flag & OS_PROCESS_INFO_ALL) {
|
|
#ifdef LOSCFG_KERNEL_VM
|
|
if (flag & OS_PROCESS_MEM_INFO) {
|
|
SHOW(" VirtualMem ShareMem PhysicalMem");
|
|
}
|
|
#endif
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
SHOW(" CPUUSE CPUUSE10s CPUUSE1s");
|
|
#endif /* LOSCFG_KERNEL_CPUP */
|
|
} else {
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
SHOW(" CPUUSE10s");
|
|
#endif /* LOSCFG_KERNEL_CPUP */
|
|
}
|
|
SHOW(" PName\n");
|
|
}
|
|
|
|
STATIC VOID ProcessDataShow(const ProcessInfo *processInfo, VOID *seqBuf, UINT16 flag)
|
|
{
|
|
SHOW("%5u%6u%5d%6d%7s%8s%7s%9u%5u%7u", processInfo->pid, processInfo->ppid, processInfo->pgroupID,
|
|
processInfo->userID, ConvertProcessModeToString(processInfo->mode),
|
|
ConvertProcessStatusToString(processInfo->status),
|
|
ConvertSchedPolicyToString(processInfo->policy), processInfo->basePrio,
|
|
processInfo->threadGroupID, processInfo->threadNumber);
|
|
|
|
if (flag & OS_PROCESS_INFO_ALL) {
|
|
#ifdef LOSCFG_KERNEL_VM
|
|
if (flag & OS_PROCESS_MEM_INFO) {
|
|
SHOW("%#11x%#9x%#12x", processInfo->virtualMem, processInfo->shareMem, processInfo->physicalMem);
|
|
}
|
|
#endif
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
SHOW("%4u.%-2u%7u.%-2u%6u.%-2u ",
|
|
processInfo->cpupAllsUsage / CPUP_MULT, processInfo->cpupAllsUsage % CPUP_MULT,
|
|
processInfo->cpup10sUsage / CPUP_MULT, processInfo->cpup10sUsage % CPUP_MULT,
|
|
processInfo->cpup1sUsage / CPUP_MULT, processInfo->cpup1sUsage % CPUP_MULT);
|
|
#endif /* LOSCFG_KERNEL_CPUP */
|
|
} else {
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
SHOW("%7u.%-2u ", processInfo->cpup10sUsage / CPUP_MULT, processInfo->cpup10sUsage % CPUP_MULT);
|
|
#endif /* LOSCFG_KERNEL_CPUP */
|
|
}
|
|
SHOW("%-32s\n", processInfo->name);
|
|
}
|
|
|
|
STATIC VOID AllProcessDataShow(const ProcessInfo *pcbArray, VOID *seqBuf, UINT16 flag)
|
|
{
|
|
for (UINT32 pid = 1; pid < g_processMaxNum; ++pid) {
|
|
const ProcessInfo *processInfo = pcbArray + pid;
|
|
if (processInfo->status & OS_PROCESS_FLAG_UNUSED) {
|
|
continue;
|
|
}
|
|
ProcessDataShow(processInfo, seqBuf, flag);
|
|
}
|
|
}
|
|
|
|
STATIC VOID ProcessInfoShow(const ProcessInfo *pcbArray, VOID *seqBuf, UINT16 flag)
|
|
{
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
UINT32 pid = OS_KERNEL_IDLE_PROCESS_ID;
|
|
UINT32 sysUsage = LOS_CPUP_PRECISION - pcbArray[pid].cpup10sUsage;
|
|
SHOW("\n allCpu(%%): %4u.%02u sys, %4u.%02u idle\n", sysUsage / CPUP_MULT, sysUsage % CPUP_MULT,
|
|
pcbArray[pid].cpup10sUsage / CPUP_MULT, pcbArray[pid].cpup10sUsage % CPUP_MULT);
|
|
#endif
|
|
|
|
ProcessInfoTitle(seqBuf, flag);
|
|
AllProcessDataShow(pcbArray, seqBuf, flag);
|
|
}
|
|
|
|
STATIC UINT8 *ConvertTaskStatusToString(UINT16 taskStatus)
|
|
{
|
|
if (taskStatus & OS_TASK_STATUS_INIT) {
|
|
return (UINT8 *)"Init";
|
|
} else if (taskStatus & OS_TASK_STATUS_RUNNING) {
|
|
return (UINT8 *)"Running";
|
|
} else if (taskStatus & OS_TASK_STATUS_READY) {
|
|
return (UINT8 *)"Ready";
|
|
} else if (taskStatus & OS_TASK_STATUS_FROZEN) {
|
|
return (UINT8 *)"Frozen";
|
|
} else if (taskStatus & OS_TASK_STATUS_SUSPENDED) {
|
|
return (UINT8 *)"Suspended";
|
|
} else if (taskStatus & OS_TASK_STATUS_DELAY) {
|
|
return (UINT8 *)"Delay";
|
|
} else if (taskStatus & OS_TASK_STATUS_PEND_TIME) {
|
|
return (UINT8 *)"PendTime";
|
|
} else if (taskStatus & OS_TASK_STATUS_PENDING) {
|
|
return (UINT8 *)"Pending";
|
|
} else if (taskStatus & OS_TASK_STATUS_EXIT) {
|
|
return (UINT8 *)"Exit";
|
|
}
|
|
|
|
return (UINT8 *)"Invalid";
|
|
}
|
|
|
|
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
|
#define OS_PEND_REASON_MAX_LEN 20
|
|
|
|
STATIC CHAR *CheckTaskWaitFlag(const TaskInfo *taskInfo, UINTPTR *lockID)
|
|
{
|
|
*lockID = taskInfo->waitID;
|
|
switch (taskInfo->waitFlag) {
|
|
case OS_TASK_WAIT_PROCESS:
|
|
return "Child";
|
|
case OS_TASK_WAIT_GID:
|
|
return "PGroup";
|
|
case OS_TASK_WAIT_ANYPROCESS:
|
|
return "AnyChild";
|
|
case OS_TASK_WAIT_SEM:
|
|
return "Semaphore";
|
|
case OS_TASK_WAIT_QUEUE:
|
|
return "Queue";
|
|
case OS_TASK_WAIT_JOIN:
|
|
return "Join";
|
|
case OS_TASK_WAIT_SIGNAL:
|
|
return "Signal";
|
|
case OS_TASK_WAIT_LITEIPC:
|
|
return "LiteIPC";
|
|
case OS_TASK_WAIT_MUTEX:
|
|
return "Mutex";
|
|
case OS_TASK_WAIT_EVENT:
|
|
return "Event";
|
|
case OS_TASK_WAIT_FUTEX:
|
|
return "Futex";
|
|
case OS_TASK_WAIT_COMPLETE:
|
|
return "Complete";
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
STATIC VOID TaskPendingReasonInfoGet(const TaskInfo *taskInfo, CHAR *pendReason, UINT32 maxLen, UINTPTR *lockID)
|
|
{
|
|
CHAR *reason = NULL;
|
|
|
|
if (!(taskInfo->status & OS_TASK_STATUS_PENDING)) {
|
|
reason = (CHAR *)ConvertTaskStatusToString(taskInfo->status);
|
|
goto EXIT;
|
|
}
|
|
|
|
reason = CheckTaskWaitFlag(taskInfo, lockID);
|
|
if (reason == NULL) {
|
|
reason = "Others";
|
|
}
|
|
|
|
if (taskInfo->taskMux != NULL) {
|
|
*lockID = (UINTPTR)taskInfo->taskMux;
|
|
LosTaskCB *owner = ((LosMux *)taskInfo->taskMux)->owner;
|
|
if (owner != NULL) {
|
|
if (snprintf_s(pendReason, maxLen, maxLen - 1, "Mutex-%u", owner->taskID) == EOK) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
EXIT:
|
|
if (strcpy_s(pendReason, maxLen, reason) != EOK) {
|
|
PRINT_ERR("Get pend reason copy failed !\n");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
STATIC VOID TaskInfoTitle(VOID *seqBuf, UINT16 flag)
|
|
{
|
|
SHOW("\r\n TID PID");
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
SHOW(" Affi CPU");
|
|
#endif
|
|
SHOW(" Status Policy Priority StackSize WaterLine");
|
|
if (flag & OS_PROCESS_INFO_ALL) {
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
SHOW(" CPUUSE CPUUSE10s CPUUSE1s");
|
|
#endif /* LOSCFG_KERNEL_CPUP */
|
|
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
|
SHOW(" StackPoint TopOfStack PendReason LockID");
|
|
#endif
|
|
} else {
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
SHOW(" CPUUSE10s ");
|
|
#endif /* LOSCFG_KERNEL_CPUP */
|
|
}
|
|
SHOW(" TaskName\n");
|
|
}
|
|
|
|
STATIC VOID TaskInfoDataShow(const TaskInfo *taskInfo, VOID *seqBuf, UINT16 flag)
|
|
{
|
|
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
|
UINTPTR lockID = 0;
|
|
CHAR pendReason[OS_PEND_REASON_MAX_LEN] = { 0 };
|
|
#endif
|
|
SHOW(" %4u%5u", taskInfo->tid, taskInfo->pid);
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
SHOW("%#5x%4d ", taskInfo->cpuAffiMask, (INT16)(taskInfo->currCpu));
|
|
#endif
|
|
SHOW("%9s%7s%9u%#10x%#10x", ConvertTaskStatusToString(taskInfo->status),
|
|
ConvertSchedPolicyToString(taskInfo->policy), taskInfo->priority, taskInfo->stackSize, taskInfo->waterLine);
|
|
if (flag & OS_PROCESS_INFO_ALL) {
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
SHOW("%4u.%-2u%7u.%-2u%6u.%-2u ", taskInfo->cpupAllsUsage / CPUP_MULT, taskInfo->cpupAllsUsage % CPUP_MULT,
|
|
taskInfo->cpup10sUsage / CPUP_MULT, taskInfo->cpup10sUsage % CPUP_MULT,
|
|
taskInfo->cpup1sUsage / CPUP_MULT, taskInfo->cpup1sUsage % CPUP_MULT);
|
|
#endif /* LOSCFG_KERNEL_CPUP */
|
|
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
|
TaskPendingReasonInfoGet(taskInfo, pendReason, OS_PEND_REASON_MAX_LEN, &lockID);
|
|
SHOW("%#12x%#12x%11s%#11x", taskInfo->stackPoint, taskInfo->topOfStack, pendReason, lockID);
|
|
#endif
|
|
} else {
|
|
#ifdef LOSCFG_KERNEL_CPUP
|
|
SHOW("%8u.%-2u ", taskInfo->cpup10sUsage / CPUP_MULT, taskInfo->cpup10sUsage % CPUP_MULT);
|
|
#endif /* LOSCFG_KERNEL_CPUP */
|
|
}
|
|
SHOW(" %-32s\n", taskInfo->name);
|
|
}
|
|
|
|
STATIC VOID ProcessTaskInfoDataShow(const ProcessThreadInfo *allTaskInfo, VOID *seqBuf, UINT16 flag)
|
|
{
|
|
for (UINT32 index = 0; index < allTaskInfo->threadCount; index++) {
|
|
const TaskInfo *taskInfo = &allTaskInfo->taskInfo[index];
|
|
TaskInfoDataShow(taskInfo, seqBuf, flag);
|
|
}
|
|
}
|
|
|
|
STATIC VOID TaskInfoData(const ProcessThreadInfo *allTaskInfo, VOID *seqBuf, UINT16 flag)
|
|
{
|
|
ProcessInfoTitle(seqBuf, flag);
|
|
ProcessDataShow(&allTaskInfo->processInfo, seqBuf, flag);
|
|
TaskInfoTitle(seqBuf, flag);
|
|
ProcessTaskInfoDataShow(allTaskInfo, seqBuf, flag);
|
|
}
|
|
|
|
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 processID, VOID *seqBuf, UINT16 flag)
|
|
{
|
|
UINT32 size;
|
|
|
|
if (processID == OS_ALL_TASK_MASK) {
|
|
size = sizeof(ProcessInfo) * g_processMaxNum;
|
|
ProcessInfo *pcbArray = (ProcessInfo *)LOS_MemAlloc(m_aucSysMem1, size);
|
|
if (pcbArray == NULL) {
|
|
PRINT_ERR("Memory is not enough to save task info!\n");
|
|
return LOS_NOK;
|
|
}
|
|
(VOID)memset_s(pcbArray, size, 0, size);
|
|
OsGetAllProcessInfo(pcbArray);
|
|
ProcessInfoShow((const ProcessInfo *)pcbArray, seqBuf, flag);
|
|
(VOID)LOS_MemFree(m_aucSysMem1, pcbArray);
|
|
return LOS_OK;
|
|
}
|
|
|
|
ProcessThreadInfo *threadInfo = (ProcessThreadInfo *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessThreadInfo));
|
|
if (threadInfo == NULL) {
|
|
return LOS_NOK;
|
|
}
|
|
(VOID)memset_s(threadInfo, sizeof(ProcessThreadInfo), 0, sizeof(ProcessThreadInfo));
|
|
|
|
if (OsGetProcessThreadInfo(processID, threadInfo) != LOS_OK) {
|
|
(VOID)LOS_MemFree(m_aucSysMem1, threadInfo);
|
|
return LOS_NOK;
|
|
}
|
|
|
|
TaskInfoData(threadInfo, seqBuf, flag);
|
|
(VOID)LOS_MemFree(m_aucSysMem1, threadInfo);
|
|
return LOS_OK;
|
|
}
|
|
|
|
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv)
|
|
{
|
|
INT32 processID = OS_ALL_TASK_MASK;
|
|
UINT32 flag = 0;
|
|
#ifdef LOSCFG_KERNEL_VM
|
|
flag |= OS_PROCESS_MEM_INFO;
|
|
#endif
|
|
|
|
if (argc == 0) {
|
|
return OsShellCmdTskInfoGet((UINT32)processID, NULL, flag);
|
|
}
|
|
|
|
if (argc >= 3) { /* 3: The task shell name restricts the parameters */
|
|
goto TASK_HELP;
|
|
}
|
|
|
|
if ((argc == 1) && (strcmp("-a", argv[0]) == 0)) {
|
|
flag |= OS_PROCESS_INFO_ALL;
|
|
} else if ((argc == 2) && (strcmp("-p", argv[0]) == 0)) { /* 2: Two parameters */
|
|
flag |= OS_PROCESS_INFO_ALL;
|
|
processID = atoi(argv[1]);
|
|
#ifdef LOSCFG_SCHED_DEBUG
|
|
#ifdef LOSCFG_SCHED_TICK_DEBUG
|
|
} else if (strcmp("-i", argv[0]) == 0) {
|
|
if (!OsShellShowTickResponse()) {
|
|
return LOS_OK;
|
|
}
|
|
goto TASK_HELP;
|
|
#endif
|
|
#ifdef LOSCFG_SCHED_HPF_DEBUG
|
|
} else if (strcmp("-t", argv[0]) == 0) {
|
|
if (!OsShellShowSchedStatistics()) {
|
|
return LOS_OK;
|
|
}
|
|
goto TASK_HELP;
|
|
#endif
|
|
#ifdef LOSCFG_SCHED_EDF_DEBUG
|
|
} else if (strcmp("-e", argv[0]) == 0) {
|
|
if (!OsShellShowEdfSchedStatistics()) {
|
|
return LOS_OK;
|
|
}
|
|
goto TASK_HELP;
|
|
#endif
|
|
#endif
|
|
} else {
|
|
goto TASK_HELP;
|
|
}
|
|
|
|
return OsShellCmdTskInfoGet((UINT32)processID, NULL, flag);
|
|
|
|
TASK_HELP:
|
|
PRINTK("Unknown option: %s\n", argv[0]);
|
|
PRINTK("Usage:\n");
|
|
PRINTK(" task --- Basic information about all created processes.\n");
|
|
PRINTK(" task -a --- Complete information about all created processes.\n");
|
|
PRINTK(" task -p [pid] --- Complete information about specifies processes and its task.\n");
|
|
return LOS_NOK;
|
|
}
|
|
|
|
#ifdef LOSCFG_SHELL
|
|
SHELLCMD_ENTRY(task_shellcmd, CMD_TYPE_EX, "task", 1, (CmdCallBackFunc)OsShellCmdDumpTask);
|
|
#endif
|
|
|