1 /*
2 * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "los_info_pri.h"
32 #include "los_task_pri.h"
33 #include "los_vm_dump.h"
34
GetCurrParentPid(UINT32 pid,const LosProcessCB * processCB)35 STATIC UINT32 GetCurrParentPid(UINT32 pid, const LosProcessCB *processCB)
36 {
37 if (processCB->parentProcess == NULL) {
38 return 0;
39 }
40
41 #ifdef LOSCFG_PID_CONTAINER
42 if (pid == OS_USER_ROOT_PROCESS_ID) {
43 return 0;
44 }
45
46 if (OS_PROCESS_CONTAINER_CHECK(processCB->parentProcess, OsCurrProcessGet())) {
47 return OsGetVpidFromCurrContainer(processCB->parentProcess);
48 }
49 #endif
50 return processCB->parentProcess->processID;
51 }
52
GetCurrTid(const LosTaskCB * taskCB)53 STATIC INLINE UINT32 GetCurrTid(const LosTaskCB *taskCB)
54 {
55 #ifdef LOSCFG_PID_CONTAINER
56 if (taskCB->pidContainer != OsCurrTaskGet()->pidContainer) {
57 return OsGetVtidFromCurrContainer(taskCB);
58 }
59 #endif
60 return taskCB->taskID;
61 }
62
GetProcessStatus(LosProcessCB * processCB)63 STATIC UINT16 GetProcessStatus(LosProcessCB *processCB)
64 {
65 UINT16 status;
66 LosTaskCB *taskCB = NULL;
67
68 if (LOS_ListEmpty(&processCB->threadSiblingList)) {
69 return processCB->processStatus;
70 }
71
72 status = processCB->processStatus;
73 LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) {
74 status |= (taskCB->taskStatus & 0x00FF);
75 }
76 return status;
77 }
78
GetProcessInfo(ProcessInfo * pcbInfo,const LosProcessCB * processCB)79 STATIC VOID GetProcessInfo(ProcessInfo *pcbInfo, const LosProcessCB *processCB)
80 {
81 SchedParam param = {0};
82 pcbInfo->pid = OsGetPid(processCB);
83 pcbInfo->ppid = GetCurrParentPid(pcbInfo->pid, processCB);
84 pcbInfo->status = GetProcessStatus((LosProcessCB *)processCB);
85 pcbInfo->mode = processCB->processMode;
86 if (processCB->pgroup != NULL) {
87 pcbInfo->pgroupID = OsGetPid(OS_GET_PGROUP_LEADER(processCB->pgroup));
88 } else {
89 pcbInfo->pgroupID = -1;
90 }
91 #ifdef LOSCFG_SECURITY_CAPABILITY
92 if (processCB->user != NULL) {
93 pcbInfo->userID = processCB->user->userID;
94 } else {
95 pcbInfo->userID = -1;
96 }
97 #else
98 pcbInfo->userID = 0;
99 #endif
100 LosTaskCB *taskCB = processCB->threadGroup;
101 pcbInfo->threadGroupID = taskCB->taskID;
102 taskCB->ops->schedParamGet(taskCB, ¶m);
103 pcbInfo->policy = LOS_SCHED_RR;
104 pcbInfo->basePrio = param.basePrio;
105 pcbInfo->threadNumber = processCB->threadNumber;
106 #ifdef LOSCFG_KERNEL_CPUP
107 (VOID)OsGetProcessAllCpuUsageUnsafe(processCB->processCpup, pcbInfo);
108 #endif
109 (VOID)memcpy_s(pcbInfo->name, OS_PCB_NAME_LEN, processCB->processName, OS_PCB_NAME_LEN);
110 }
111
112 #ifdef LOSCFG_KERNEL_VM
GetProcessMemInfo(ProcessInfo * pcbInfo,const LosProcessCB * processCB,LosVmSpace * vmSpace)113 STATIC VOID GetProcessMemInfo(ProcessInfo *pcbInfo, const LosProcessCB *processCB, LosVmSpace *vmSpace)
114 {
115 /* Process memory usage statistics, idle task defaults to 0 */
116 if (processCB == &g_processCBArray[0]) {
117 pcbInfo->virtualMem = 0;
118 pcbInfo->shareMem = 0;
119 pcbInfo->physicalMem = 0;
120 } else if (vmSpace == LOS_GetKVmSpace()) {
121 (VOID)OsShellCmdProcessPmUsage(vmSpace, &pcbInfo->shareMem, &pcbInfo->physicalMem);
122 pcbInfo->virtualMem = pcbInfo->physicalMem;
123 } else {
124 pcbInfo->virtualMem = OsShellCmdProcessVmUsage(vmSpace);
125 if (pcbInfo->virtualMem == 0) {
126 pcbInfo->status = OS_PROCESS_FLAG_UNUSED;
127 return;
128 }
129 if (OsShellCmdProcessPmUsage(vmSpace, &pcbInfo->shareMem, &pcbInfo->physicalMem) == 0) {
130 pcbInfo->status = OS_PROCESS_FLAG_UNUSED;
131 }
132 }
133 }
134 #endif
135
GetThreadInfo(ProcessThreadInfo * threadInfo,LosProcessCB * processCB)136 STATIC VOID GetThreadInfo(ProcessThreadInfo *threadInfo, LosProcessCB *processCB)
137 {
138 SchedParam param = {0};
139 LosTaskCB *taskCB = NULL;
140 if (LOS_ListEmpty(&processCB->threadSiblingList)) {
141 threadInfo->threadCount = 0;
142 return;
143 }
144
145 threadInfo->threadCount = 0;
146 LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &processCB->threadSiblingList, LosTaskCB, threadList) {
147 TaskInfo *taskInfo = &threadInfo->taskInfo[threadInfo->threadCount];
148 taskInfo->tid = GetCurrTid(taskCB);
149 taskInfo->pid = OsGetPid(processCB);
150 taskInfo->status = taskCB->taskStatus;
151 taskCB->ops->schedParamGet(taskCB, ¶m);
152 taskInfo->policy = param.policy;
153 taskInfo->priority = param.priority;
154 #ifdef LOSCFG_KERNEL_SMP
155 taskInfo->currCpu = taskCB->currCpu;
156 taskInfo->cpuAffiMask = taskCB->cpuAffiMask;
157 #endif
158 taskInfo->stackPoint = (UINTPTR)taskCB->stackPointer;
159 taskInfo->topOfStack = taskCB->topOfStack;
160 taskInfo->stackSize = taskCB->stackSize;
161 taskInfo->waitFlag = taskCB->waitFlag;
162 taskInfo->waitID = taskCB->waitID;
163 taskInfo->taskMux = taskCB->taskMux;
164 (VOID)OsStackWaterLineGet((const UINTPTR *)(taskCB->topOfStack + taskCB->stackSize),
165 (const UINTPTR *)taskCB->topOfStack, &taskInfo->waterLine);
166 #ifdef LOSCFG_KERNEL_CPUP
167 (VOID)OsGetTaskAllCpuUsageUnsafe(&taskCB->taskCpup, taskInfo);
168 #endif
169 (VOID)memcpy_s(taskInfo->name, OS_TCB_NAME_LEN, taskCB->taskName, OS_TCB_NAME_LEN);
170 threadInfo->threadCount++;
171 }
172 }
173
OsGetProcessThreadInfo(UINT32 pid,ProcessThreadInfo * threadInfo)174 UINT32 OsGetProcessThreadInfo(UINT32 pid, ProcessThreadInfo *threadInfo)
175 {
176 UINT32 intSave;
177
178 if (OS_PID_CHECK_INVALID(pid) || (pid == 0) || (threadInfo == NULL)) {
179 return LOS_NOK;
180 }
181
182 LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
183 if (OsProcessIsUnused(processCB)) {
184 return LOS_NOK;
185 }
186
187 #ifdef LOSCFG_KERNEL_VM
188 GetProcessMemInfo(&threadInfo->processInfo, processCB, processCB->vmSpace);
189 #endif
190
191 SCHEDULER_LOCK(intSave);
192 GetProcessInfo(&threadInfo->processInfo, processCB);
193 GetThreadInfo(threadInfo, processCB);
194 SCHEDULER_UNLOCK(intSave);
195 return LOS_OK;
196 }
197
ProcessMemUsageGet(ProcessInfo * pcbArray)198 STATIC VOID ProcessMemUsageGet(ProcessInfo *pcbArray)
199 {
200 UINT32 intSave;
201 #ifdef LOSCFG_PID_CONTAINER
202 PidContainer *pidContainer = OsCurrTaskGet()->pidContainer;
203 for (UINT32 pid = 0; pid < g_processMaxNum; ++pid) {
204 ProcessVid *processVid = &pidContainer->pidArray[pid];
205 const LosProcessCB *processCB = (LosProcessCB *)processVid->cb;
206 #else
207 for (UINT32 pid = 0; pid < g_processMaxNum; ++pid) {
208 const LosProcessCB *processCB = OS_PCB_FROM_RPID(pid);
209 #endif
210 ProcessInfo *pcbInfo = pcbArray + pid;
211 SCHEDULER_LOCK(intSave);
212 if (OsProcessIsUnused(processCB)) {
213 SCHEDULER_UNLOCK(intSave);
214 pcbInfo->status = OS_PROCESS_FLAG_UNUSED;
215 continue;
216 }
217 #ifdef LOSCFG_KERNEL_VM
218 LosVmSpace *vmSpace = processCB->vmSpace;
219 #endif
220 SCHEDULER_UNLOCK(intSave);
221
222 #ifdef LOSCFG_KERNEL_VM
223 GetProcessMemInfo(pcbInfo, processCB, vmSpace);
224 #endif
225 }
226 }
227
228 UINT32 OsGetAllProcessInfo(ProcessInfo *pcbArray)
229 {
230 UINT32 intSave;
231 if (pcbArray == NULL) {
232 return LOS_NOK;
233 }
234
235 ProcessMemUsageGet(pcbArray);
236
237 SCHEDULER_LOCK(intSave);
238 #ifdef LOSCFG_PID_CONTAINER
239 PidContainer *pidContainer = OsCurrTaskGet()->pidContainer;
240 for (UINT32 index = 0; index < LOSCFG_BASE_CORE_PROCESS_LIMIT; index++) {
241 ProcessVid *processVid = &pidContainer->pidArray[index];
242 LosProcessCB *processCB = (LosProcessCB *)processVid->cb;
243 #else
244 for (UINT32 index = 0; index < LOSCFG_BASE_CORE_PROCESS_LIMIT; index++) {
245 LosProcessCB *processCB = OS_PCB_FROM_RPID(index);
246 #endif
247 ProcessInfo *pcbInfo = pcbArray + index;
248 if (OsProcessIsUnused(processCB)) {
249 pcbInfo->status = OS_PROCESS_FLAG_UNUSED;
250 continue;
251 }
252 GetProcessInfo(pcbInfo, processCB);
253 }
254 SCHEDULER_UNLOCK(intSave);
255 return LOS_OK;
256 }
257