更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_process.c
浏览该文件的文档.
1/*!
2 * @file los_process.c
3 * @brief 进程模块主文件
4 * @link
5 @verbatim
6
7 并发(Concurrent):多个线程在单个核心运行,同一时间只能一个线程运行,内核不停切换线程,
8 看起来像同时运行,实际上是线程不停切换
9 并行(Parallel)每个线程分配给独立的CPU核心,线程同时运行
10 单核CPU多个进程或多个线程内能实现并发(微观上的串行,宏观上的并行)
11 多核CPU线程间可以实现宏观和微观上的并行
12 LITE_OS_SEC_BSS 和 LITE_OS_SEC_DATA_INIT 是告诉编译器这些全局变量放在哪个数据段
13
14 @endverbatim
15 * @version
16 * @author weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
17 * @date 2021-12-15
18 */
19
20/*
21 * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
22 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without modification,
25 * are permitted provided that the following conditions are met:
26 *
27 * 1. Redistributions of source code must retain the above copyright notice, this list of
28 * conditions and the following disclaimer.
29 *
30 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
31 * of conditions and the following disclaimer in the documentation and/or other materials
32 * provided with the distribution.
33 *
34 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
35 * to endorse or promote products derived from this software without specific prior written
36 * permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
39 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
40 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
42 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
43 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
44 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
45 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
46 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
47 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
48 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 */
50
51#include "los_process_pri.h"
52#include "los_sched_pri.h"
53#include "los_task_pri.h"
54#include "los_hw_pri.h"
55#include "los_sem_pri.h"
56#include "los_mp.h"
57#include "los_exc.h"
58#include "asm/page.h"
59#ifdef LOSCFG_FS_VFS
60#include "fs/fd_table.h"
61#include "fs/fs_operation.h"
62#endif
63#include "time.h"
64#include "user_copy.h"
65#include "los_signal.h"
66#ifdef LOSCFG_SECURITY_VID
67#include "vid_api.h"
68#endif
69#ifdef LOSCFG_SECURITY_CAPABILITY
70#include "capability_api.h"
71#endif
72#ifdef LOSCFG_KERNEL_DYNLOAD
73#include "los_load_elf.h"
74#endif
75#include "los_swtmr_pri.h"
76#include "los_vm_map.h"
77#include "los_vm_phys.h"
78#include "los_vm_syscall.h"
79
80LITE_OS_SEC_BSS LosProcessCB *g_processCBArray = NULL; ///< 进程池数组
81LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess;///< 空闲状态下的进程链表, .个人觉得应该取名为 g_freeProcessList @note_thinking
82LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList;///< 需要回收的进程列表
83LITE_OS_SEC_BSS UINT32 g_userInitProcess = OS_INVALID_VALUE;///< 1号进程 用户态的初始init进程,用户态下其他进程由它 fork
84LITE_OS_SEC_BSS UINT32 g_kernelInitProcess = OS_INVALID_VALUE;///< 2号进程 内核态初始Kprocess进程,内核态下其他进程由它 fork
85LITE_OS_SEC_BSS UINT32 g_kernelIdleProcess = OS_INVALID_VALUE;///< 0号进程 内核态idle进程,由Kprocess fork
86LITE_OS_SEC_BSS UINT32 g_processMaxNum;///< 进程最大数量,默认64个
87LITE_OS_SEC_BSS ProcessGroup *g_processGroup = NULL;///< 全局进程组,负责管理所有进程组
88
89/**
90 * @brief 将进程插入到空闲链表中
91 * @details
92 * @param argc 1
93 * @param[LosProcessCB] processCB 指定进程
94 * @return 函数执行结果
95 * - VOID 无
96*/
97STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB)
98{
99 UINT32 pid = processCB->processID;//获取进程ID
100 (VOID)memset_s(processCB, sizeof(LosProcessCB), 0, sizeof(LosProcessCB));//进程描述符数据清0
101 processCB->processID = pid;//进程ID
102 processCB->processStatus = OS_PROCESS_FLAG_UNUSED;//设置为进程未使用
103 processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;//timeID初始化值
104 LOS_ListTailInsert(&g_freeProcess, &processCB->pendList);//进程节点挂入g_freeProcess以分配给后续进程使用
105}
106
108{
109 LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);
110
111 LOS_ListDelete(&taskCB->threadList);
112 processCB->threadNumber--;
114}
115
117{
118 UINT32 intSave;
119 UINT16 numCount;
120 LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
121
122 SCHEDULER_LOCK(intSave);
123 taskCB->processID = pid;
124 LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList));
125
126 if (OsProcessIsUserMode(processCB)) {
127 taskCB->taskStatus |= OS_TASK_FLAG_USER_MODE;
128 if (processCB->threadNumber > 0) {
129 LosTaskCB *task = OS_TCB_FROM_TID(processCB->threadGroupID);
130 task->ops->schedParamGet(task, param);
131 } else {
133 }
134 } else {
135 LosTaskCB *runTask = OsCurrTaskGet();
136 runTask->ops->schedParamGet(runTask, param);
137 }
138
139#ifdef LOSCFG_KERNEL_VM
140 taskCB->archMmu = (UINTPTR)&processCB->vmSpace->archMmu;
141#endif
142 if (!processCB->threadNumber) {
143 processCB->threadGroupID = taskCB->taskID;
144 }
145 processCB->threadNumber++;
146
147 numCount = processCB->threadCount;
148 processCB->threadCount++;
149 SCHEDULER_UNLOCK(intSave);
150 return numCount;
151}
152/**
153 * @brief 创建进程组
154 * @details
155 * @param argc 1
156 * @param[UINT32] pid 进程ID
157 * @return 函数执行结果
158 * - ProcessGroup 返回进程组
159*/
161{
162 LosProcessCB *processCB = NULL;
163 ProcessGroup *group = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcessGroup));//从内存池中分配进程组结构体
164 if (group == NULL) {
165 return NULL;
166 }
167
168 group->groupID = pid;//参数当进程组ID
169 LOS_ListInit(&group->processList);//初始化进程链表,这里把组内的进程都挂上去
170 LOS_ListInit(&group->exitProcessList);//初始化退出进程链表,这里挂退出的进程
171
172 processCB = OS_PCB_FROM_PID(pid);//通过pid获得进程实体
173 LOS_ListTailInsert(&group->processList, &processCB->subordinateGroupList);//通过subordinateGroupList挂在进程组上,自然后续要通过它来找到进程实体
174 processCB->group = group;//设置进程所属进程组
175 processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER;//进程状态贴上当老大的标签
176 if (g_processGroup != NULL) {//全局进程组链表判空,g_processGroup指向"Kernel"进程所在组,详见: OsKernelInitProcess
177 LOS_ListTailInsert(&g_processGroup->groupList, &group->groupList);//把进程组挂到全局进程组链表上
178 }
179
180 return group;
181}
182
183/*! 退出进程组,参数是进程地址和进程组地址的地址 */
184STATIC VOID OsExitProcessGroup(LosProcessCB *processCB, ProcessGroup **group)//ProcessGroup *g_processGroup = NULL
185{
186 LosProcessCB *groupProcessCB = OS_PCB_FROM_PID(processCB->group->groupID);//找到进程组老大进程的实体
187
188 LOS_ListDelete(&processCB->subordinateGroupList);//从进程组进程链表上摘出去
189 if (LOS_ListEmpty(&processCB->group->processList) && LOS_ListEmpty(&processCB->group->exitProcessList)) {//进程组进程链表和退出进程链表都为空时
190 LOS_ListDelete(&processCB->group->groupList);//从全局进程组链表上把自己摘出去 记住它是 LOS_ListTailInsert(&g_processGroup->groupList, &group->groupList) 挂上去的
191 groupProcessCB->processStatus &= ~OS_PROCESS_FLAG_GROUP_LEADER;//贴上不是组长的标签
192 *group = processCB->group;//????? 这步操作没看明白,谁能告诉我为何要这么做?
193 if (OsProcessIsUnused(groupProcessCB) && !(groupProcessCB->processStatus & OS_PROCESS_FLAG_EXIT)) {//组长进程时退出的标签
194 LOS_ListDelete(&groupProcessCB->pendList);//进程从全局进程链表上摘除
195 OsInsertPCBToFreeList(groupProcessCB);//释放进程的资源,回到freelist再利用
196 }
197 }
198
199 processCB->group = NULL;
200}
201
202/*! 通过指定组ID找到进程组 */
204{
205 ProcessGroup *group = NULL;
206 if (g_processGroup->groupID == gid) {
207 return g_processGroup;
208 }
209 //变量进程组
210 LOS_DL_LIST_FOR_EACH_ENTRY(group, &g_processGroup->groupList, ProcessGroup, groupList) {
211 if (group->groupID == gid) {
212 return group;
213 }
214 }
215
216 PRINT_INFO("%s failed! group id = %u\n", __FUNCTION__, gid);
217 return NULL;
218}
219
220/*! 给指定进程组发送信号 */
221STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *group, siginfo_t *info, INT32 permission)
222{
223 INT32 ret, success, err;
224 LosProcessCB *childCB = NULL;
225
226 success = 0;
227 ret = -LOS_ESRCH;
228 LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(group->processList), LosProcessCB, subordinateGroupList) {//遍历进程组内的进程
229 if (childCB->processID == 0) {//0号进程为KIdle进程,是让CPU休息的进程,不处理信号
230 continue;
231 }
232
233 err = OsDispatch(childCB->processID, info, permission);//给进程发送信号
234 success |= !err;
235 ret = err;
236 }
237 /* At least one success. */
238 return success ? LOS_OK : ret;
239}
240
241/*! 给所有进程发送指定信号 */
242LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission)
243{
244 INT32 ret, success, err;
245 ProcessGroup *group = NULL;
246
247 success = 0;
248 err = OsSendSignalToSpecifyProcessGroup(g_processGroup, info, permission);//给g_processGroup进程组发送信号
249 success |= !err;
250 ret = err;
251 /* all processes group */
252 LOS_DL_LIST_FOR_EACH_ENTRY(group, &g_processGroup->groupList, ProcessGroup, groupList) {//遍历进程组
253 /* all processes in the process group. */
254 err = OsSendSignalToSpecifyProcessGroup(group, info, permission);
255 success |= !err;
256 ret = err;
257 }
258 return success ? LOS_OK : ret;
259}
260
261/*! 发送指定信号给给进程组 */
262LITE_OS_SEC_TEXT INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission)
263{
264 ProcessGroup *group = NULL;
265 /* Send SIG to all processes in process group PGRP.
266 If PGRP is zero, send SIG to all processes in
267 the current process's process group. */
268 group = OsFindProcessGroup(pid ? -pid : LOS_GetCurrProcessGroupID());
269 if (group == NULL) {
270 return -LOS_ESRCH;
271 }
272 /* all processes in the process group. */
273 return OsSendSignalToSpecifyProcessGroup(group, info, permission);
274}
275
277{
278 LosProcessCB *childCB = NULL;
279
280 LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(group->exitProcessList), LosProcessCB, subordinateGroupList) {
281 if ((childCB->processID == pid) || (pid == OS_INVALID_VALUE)) {
282 return childCB;
283 }
284 }
285
286 PRINT_INFO("%s find exit process : %d failed in group : %u\n", __FUNCTION__, pid, group->groupID);
287 return NULL;
288}
289
290/*! 查找进程是否有指定孩子进程 */
291STATIC UINT32 OsFindChildProcess(const LosProcessCB *processCB, INT32 childPid)
292{
293 LosProcessCB *childCB = NULL;
294
295 if (childPid < 0) {
296 goto ERR;
297 }
298
299 LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(processCB->childrenList), LosProcessCB, siblingList) {//
300 if (childCB->processID == childPid) {
301 return LOS_OK;
302 }
303 }
304
305ERR:
306 PRINT_INFO("%s is find the child : %d failed in parent : %u\n", __FUNCTION__, childPid, processCB->processID);
307 return LOS_NOK;
308}
309
310/*! 找出指定进程的指定孩子进程 */
311STATIC LosProcessCB *OsFindExitChildProcess(const LosProcessCB *processCB, INT32 childPid)
312{
313 LosProcessCB *exitChild = NULL;
314
315 LOS_DL_LIST_FOR_EACH_ENTRY(exitChild, &(processCB->exitChildList), LosProcessCB, siblingList) {
316 if ((childPid == OS_INVALID_VALUE) || (exitChild->processID == childPid)) {
317 return exitChild;
318 }
319 }
320
321 PRINT_INFO("%s is find the exit child : %d failed in parent : %u\n", __FUNCTION__, childPid, processCB->processID);
322 return NULL;
323}
324
325/*! 唤醒等待wakePID结束的任务 */
326VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID)
327{
328 taskCB->waitID = wakePID;
329 taskCB->ops->wake(taskCB);
330#ifdef LOSCFG_KERNEL_SMP
331 LOS_MpSchedule(OS_MP_CPU_ALL);//向所有cpu发送调度指令
332#endif
333}
334
335/*! 唤醒等待参数进程结束的任务 */
336STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *processCB, LOS_DL_LIST **anyList)
337{
338 LOS_DL_LIST *list = head;
339 LosTaskCB *taskCB = NULL;
340 UINT32 pid = 0;
341 BOOL find = FALSE;
342
343 while (list->pstNext != head) {//遍历等待链表 processCB->waitList
344 taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));//一个一个来
345 if ((taskCB->waitFlag == OS_PROCESS_WAIT_PRO) && (taskCB->waitID == processCB->processID)) {//符合OS_PROCESS_WAIT_PRO方式的
346 if (pid == 0) {
347 pid = processCB->processID;//等待的进程
348 find = TRUE;//找到了
349 } else {// @note_thinking 这个代码有点多余吧,会执行到吗?
350 pid = OS_INVALID_VALUE;
351 }
352
353 OsWaitWakeTask(taskCB, pid);//唤醒这个任务,此时会切到 LOS_Wait runTask->waitFlag = 0;处运行
354 continue;
355 }
356
357 if (taskCB->waitFlag != OS_PROCESS_WAIT_PRO) {
358 *anyList = list;
359 break;
360 }
361 list = list->pstNext;
362 }
363
364 return find;
365}
366
367/*! 检查父进程的等待任务并唤醒父进程去处理等待任务 */
368STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosProcessCB *processCB)
369{
370 LOS_DL_LIST *head = &parentCB->waitList;
371 LOS_DL_LIST *list = NULL;
372 LosTaskCB *taskCB = NULL;
373 BOOL findSpecified = FALSE;
374
375 if (LOS_ListEmpty(&parentCB->waitList)) {//父进程中是否有在等待子进程退出的任务?
376 return;//没有就退出
377 }
378 // TODO
379 findSpecified = OsWaitWakeSpecifiedProcess(head, processCB, &list);//找到指定的任务
380 if (findSpecified == TRUE) {
381 /* No thread is waiting for any child process to finish */
382 if (LOS_ListEmpty(&parentCB->waitList)) {//没有线程正在等待任何子进程结束
383 return;//已经处理完了,注意在OsWaitWakeSpecifiedProcess中做了频繁的任务切换
384 } else if (!LOS_ListEmpty(&parentCB->childrenList)) {
385 /* Other child processes exist, and other threads that are waiting
386 * for the child to finish continue to wait
387 *///存在其他子进程,正在等待它们的子进程结束而将继续等待
388 return;
389 }
390 }
391
392 /* Waiting threads are waiting for a specified child process to finish */
393 if (list == NULL) {//等待线程正在等待指定的子进程结束
394 return;
395 }
396
397 /* No child processes exist and all waiting threads are awakened */
398 if (findSpecified == TRUE) {//所有等待的任务都被一一唤醒
399 while (list->pstNext != head) {
400 taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
401 OsWaitWakeTask(taskCB, OS_INVALID_VALUE);
402 }
403 return;
404 }
405
406 while (list->pstNext != head) {//处理 OS_PROCESS_WAIT_GID 标签
407 taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
408 if (taskCB->waitFlag == OS_PROCESS_WAIT_GID) {
409 if (taskCB->waitID != processCB->group->groupID) {
410 list = list->pstNext;
411 continue;
412 }
413 }
414
415 if (findSpecified == FALSE) {
416 OsWaitWakeTask(taskCB, processCB->processID);
417 findSpecified = TRUE;
418 } else {
419 OsWaitWakeTask(taskCB, OS_INVALID_VALUE);
420 }
421
422 if (!LOS_ListEmpty(&parentCB->childrenList)) {
423 break;
424 }
425 }
426
427 return;
428}
429
430/*! 回收指定进程的资源 */
431LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
432{
433#ifdef LOSCFG_KERNEL_VM
434 if (OsProcessIsUserMode(processCB)) {
435 (VOID)OsVmSpaceRegionFree(processCB->vmSpace);
436 }
437#endif
438#ifdef LOSCFG_FS_VFS
439 if (OsProcessIsUserMode(processCB)) {//用户进程
440 delete_files(processCB->files);//归还进程占用的进程描述符`profd`,如果是最后一个占用的系统描述符的进程,则同时归还系统文件描述符`sysfd`
441 }
442 processCB->files = NULL; //重置指针为空
443#endif
444
445#ifdef LOSCFG_SECURITY_CAPABILITY //安全开关
446 if (processCB->user != NULL) {
447 (VOID)LOS_MemFree(m_aucSysMem1, processCB->user);//删除用户
448 processCB->user = NULL; //重置指针为空
449 }
450#endif
451
452 OsSwtmrRecycle(processCB->processID);//回收进程使用的定时器
453 processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
454
455#ifdef LOSCFG_SECURITY_VID
456 if (processCB->timerIdMap.bitMap != NULL) {
457 VidMapDestroy(processCB);
458 processCB->timerIdMap.bitMap = NULL;
459 }
460#endif
461
462#ifdef LOSCFG_KERNEL_LITEIPC
463 (VOID)LiteIpcPoolDestroy(processCB->processID);
464#endif
465
466#ifdef LOSCFG_KERNEL_CPUP
467 UINT32 intSave;
468 OsCpupBase *processCpup = processCB->processCpup;
469 SCHEDULER_LOCK(intSave);
470 processCB->processCpup = NULL;
471 SCHEDULER_UNLOCK(intSave);
472 (VOID)LOS_MemFree(m_aucSysMem1, processCpup);
473#endif
474
475 if (processCB->resourceLimit != NULL) {
476 (VOID)LOS_MemFree((VOID *)m_aucSysMem0, processCB->resourceLimit);
477 processCB->resourceLimit = NULL;
478 }
479}
480
481/*! 回收僵死状态进程的资源 */
482LITE_OS_SEC_TEXT STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **group)
483{
484 OsExitProcessGroup(childCB, group);//退出进程组
485 LOS_ListDelete(&childCB->siblingList);//从父亲大人的子孙链表上摘除
486 if (childCB->processStatus & OS_PROCESS_STATUS_ZOMBIES) {//如果身上僵死状态的标签
487 OsDeleteTaskFromProcess(OS_TCB_FROM_TID(childCB->threadGroupID));
488 childCB->processStatus &= ~OS_PROCESS_STATUS_ZOMBIES;//去掉僵死标签
489 childCB->processStatus |= OS_PROCESS_FLAG_UNUSED;//贴上没使用标签,进程由进程池分配,进程退出后重新回到空闲进程池
490 }
491
492 LOS_ListDelete(&childCB->pendList);//将自己从阻塞链表上摘除,注意有很多原因引起阻塞,pendList挂在哪里就以为这属于哪类阻塞
493 if (childCB->processStatus & OS_PROCESS_FLAG_EXIT) {//如果有退出标签
494 LOS_ListHeadInsert(&g_processRecycleList, &childCB->pendList);//从头部插入,注意g_processRecyleList挂的是pendList节点,所以要通过OS_PCB_FROM_PENDLIST找.
495 } else if (childCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) {//如果是进程组的组长
496 LOS_ListTailInsert(&g_processRecycleList, &childCB->pendList);//从尾部插入,意思就是组长尽量最后一个处理
497 } else {
498 OsInsertPCBToFreeList(childCB);//直接插到freeList中去,可用于重新分配了。
499 }
500}
501
502/*! 当一个进程自然退出的时候,它的孩子进程由两位老祖宗收养 */
504{
505 UINT32 parentID;
506 LosProcessCB *childCB = NULL;
507 LosProcessCB *parentCB = NULL;
508 LOS_DL_LIST *nextList = NULL;
509 LOS_DL_LIST *childHead = NULL;
510
511 if (!LOS_ListEmpty(&processCB->childrenList)) {//如果存在孩子进程
512 childHead = processCB->childrenList.pstNext;//获取孩子链表
513 LOS_ListDelete(&(processCB->childrenList));//清空自己的孩子链表
514 if (OsProcessIsUserMode(processCB)) {//是用户态进程
515 parentID = g_userInitProcess;//用户态进程老祖宗
516 } else {
517 parentID = g_kernelInitProcess;//内核态进程老祖宗
518 }
519
520 for (nextList = childHead; ;) {//遍历孩子链表
521 childCB = OS_PCB_FROM_SIBLIST(nextList);//找到孩子的真身
522 childCB->parentProcessID = parentID;//孩子磕头认老祖宗为爸爸
523 nextList = nextList->pstNext;//找下一个孩子进程
524 if (nextList == childHead) {//一圈下来,孩子们都磕完头了
525 break;
526 }
527 }
528
529 parentCB = OS_PCB_FROM_PID(parentID);//找个老祖宗的真身
530 LOS_ListTailInsertList(&parentCB->childrenList, childHead);//挂到老祖宗的孩子链表上
531 }
532
533 return;
534}
535
536/*! 回收指定进程的已经退出(死亡)的孩子进程所占资源 */
537STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB)
538{
539 LosProcessCB *childCB = NULL;
540 ProcessGroup *group = NULL;
541
542 while (!LOS_ListEmpty(&((LosProcessCB *)processCB)->exitChildList)) {//遍历直到没有了退出(死亡)的孩子进程
543 childCB = LOS_DL_LIST_ENTRY(processCB->exitChildList.pstNext, LosProcessCB, siblingList);//获取孩子进程,
544 OsRecycleZombiesProcess(childCB, &group);//其中会将childCB从exitChildList链表上摘出去
545 (VOID)LOS_MemFree(m_aucSysMem1, group);//
546 }
547}
548
549/*! 一个进程的自然消亡过程,参数是当前运行的任务*/
551{
552 LosProcessCB *parentCB = NULL;
553
554 OsChildProcessResourcesFree(processCB);//释放孩子进程的资源
555
556
557 /* is a child process */
558 if (processCB->parentProcessID != OS_INVALID_VALUE) {//判断是否有父进程
559 parentCB = OS_PCB_FROM_PID(processCB->parentProcessID);//获取父进程实体
560 LOS_ListDelete(&processCB->siblingList);//将自己从兄弟链表中摘除,家人们,永别了!
561 if (!OsProcessExitCodeSignalIsSet(processCB)) {//是否设置了退出码?
562 OsProcessExitCodeSet(processCB, status);//将进程状态设为退出码
563 }
564 LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList);//挂到父进程的孩子消亡链表,家人中,永别的可不止我一个.
565 LOS_ListDelete(&processCB->subordinateGroupList);//和志同道合的朋友们永别了,注意家里可不一定是朋友的,所有各有链表.
566 LOS_ListTailInsert(&processCB->group->exitProcessList, &processCB->subordinateGroupList);//挂到进程组消亡链表,朋友中,永别的可不止我一个.
567
568 OsWaitCheckAndWakeParentProcess(parentCB, processCB);//检查父进程的等待任务链表并唤醒对应的任务,此处将会频繁的切到其他任务运行.
569
570 OsDealAliveChildProcess(processCB);//孩子们要怎么处理,移交给(用户态和内核态)根进程
571
572 processCB->processStatus |= OS_PROCESS_STATUS_ZOMBIES;//贴上僵死进程的标签
573
574#ifdef LOSCFG_KERNEL_VM
575 (VOID)OsKill(processCB->parentProcessID, SIGCHLD, OS_KERNEL_KILL_PERMISSION);//以内核权限发送SIGCHLD(子进程退出)信号.
576#endif
577 LOS_ListHeadInsert(&g_processRecycleList, &processCB->pendList);//将进程通过其阻塞节点挂入全局进程回收链表
578 return;
579 }
580
581 LOS_Panic("pid : %u is the root process exit!\n", processCB->processID);
582 return;
583}
584
585/*! 进程模块初始化,被编译放在代码段 .init 中*/
587{
588 UINT32 index;
589 UINT32 size;
590
591 g_processMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT;//默认支持64个进程
592 size = g_processMaxNum * sizeof(LosProcessCB);//算出总大小
593
594 g_processCBArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size);// 进程池,占用内核堆,内存池分配
595 if (g_processCBArray == NULL) {
596 return LOS_NOK;
597 }
598 (VOID)memset_s(g_processCBArray, size, 0, size);//安全方式重置清0
599
600 LOS_ListInit(&g_freeProcess);//进程空闲链表初始化,创建一个进程时从g_freeProcess中申请一个进程描述符使用
601 LOS_ListInit(&g_processRecycleList);//进程回收链表初始化,回收完成后进入g_freeProcess等待再次被申请使用
602
603 for (index = 0; index < g_processMaxNum; index++) {//进程池循环创建
604 g_processCBArray[index].processID = index;//进程ID[0-g_processMaxNum-1]赋值
605 g_processCBArray[index].processStatus = OS_PROCESS_FLAG_UNUSED;// 默认都是白纸一张,贴上未使用标签
606 LOS_ListTailInsert(&g_freeProcess, &g_processCBArray[index].pendList);//注意g_freeProcess挂的是pendList节点,所以使用要通过OS_PCB_FROM_PENDLIST找到进程实体.
607 }
608
609 g_kernelIdleProcess = 0; /* 0: The idle process ID of the kernel-mode process is fixed at 0 *///内核态init进程,从名字可以看出来这是让cpu休息的进程.
610 LOS_ListDelete(&OS_PCB_FROM_PID(g_kernelIdleProcess)->pendList);//从空闲链表中摘掉
611
612 g_userInitProcess = 1; /* 1: The root process ID of the user-mode process is fixed at 1 *///用户态的根进程
613 LOS_ListDelete(&OS_PCB_FROM_PID(g_userInitProcess)->pendList);//从空闲链表中摘掉
614
615 g_kernelInitProcess = 2; /* 2: The root process ID of the kernel-mode process is fixed at 2 *///内核态的根进程
616 LOS_ListDelete(&OS_PCB_FROM_PID(g_kernelInitProcess)->pendList);//从空闲链表中摘掉
617
618 //注意:这波骚操作之后,g_freeProcess链表上还有[3,g_processMaxNum-1]号进程.创建进程是从g_freeProcess上申请
619 //即下次申请到的将是0号进程,而 OsCreateIdleProcess 将占有0号进程.
620
621 return LOS_OK;
622}
623
624/*! 进程回收再利用过程*/
625LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
626{
627 UINT32 intSave;
628 LosProcessCB *processCB = NULL;
629
630 SCHEDULER_LOCK(intSave);
631 while (!LOS_ListEmpty(&g_processRecycleList)) {//循环任务回收链表,直到为空
632 processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_processRecycleList));//找到回收链表中第一个进程实体
633 //OS_PCB_FROM_PENDLIST 代表的是通过pendlist节点找到 PCB实体,因为g_processRecyleList上面挂的是pendlist节点位置
634 if (!(processCB->processStatus & OS_PROCESS_FLAG_EXIT)) {//进程没有退出标签
635 break;
636 }
637 SCHEDULER_UNLOCK(intSave);
638
640
641 SCHEDULER_LOCK(intSave);
642 processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT;//给进程撕掉退出标签,(可能进程并没有这个标签)
643#ifdef LOSCFG_KERNEL_VM
644 LosVmSpace *space = NULL;
645 if (OsProcessIsUserMode(processCB)) {//进程是否是用户态进程
646 space = processCB->vmSpace;//只有用户态的进程才需要释放虚拟内存空间
647 }
648 processCB->vmSpace = NULL;
649#endif
650 /* OS_PROCESS_FLAG_GROUP_LEADER: The lead process group cannot be recycled without destroying the PCB.
651 * !OS_PROCESS_FLAG_UNUSED: Parent process does not reclaim child process resources.
652 */
653 LOS_ListDelete(&processCB->pendList);//将进程从进程链表上摘除
654 if ((processCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) ||//如果进程是进程组组长或者处于僵死状态
655 (processCB->processStatus & OS_PROCESS_STATUS_ZOMBIES)) {
656 LOS_ListTailInsert(&g_processRecycleList, &processCB->pendList);//将进程挂到进程回收链表上,因为组长不能走啊
657 } else {
658 /* Clear the bottom 4 bits of process status */
659 OsInsertPCBToFreeList(processCB);//进程回到可分配池中,再分配利用
660 }
661#ifdef LOSCFG_KERNEL_VM
662 SCHEDULER_UNLOCK(intSave);
663 (VOID)LOS_VmSpaceFree(space);//释放用户态进程的虚拟内存空间,因为内核只有一个虚拟空间,因此不需要释放虚拟空间.
664 SCHEDULER_LOCK(intSave);
665#endif
666 }
667
668 SCHEDULER_UNLOCK(intSave);
669}
670
671/*! 删除PCB块 其实是 PCB块回归进程池,先进入回收链表*/
672STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
673{
674 UINT32 intSave;
675 ProcessGroup *group = NULL;
676
677 if (processCB == NULL) {
678 return;
679 }
680
681 OsProcessResourcesToFree(processCB);//释放进程所占用的资源
682
683 SCHEDULER_LOCK(intSave);
684 if (processCB->parentProcessID != OS_INVALID_VALUE) {
685 LOS_ListDelete(&processCB->siblingList);//将进程从兄弟链表中摘除
686 processCB->parentProcessID = OS_INVALID_VALUE;
687 }
688
689 if (processCB->group != NULL) {
690 OsExitProcessGroup(processCB, &group);//退出进程组
691 }
692
693 processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;//设置进程状态为非初始化
694 processCB->processStatus |= OS_PROCESS_FLAG_EXIT; //设置进程状态为退出
696 SCHEDULER_UNLOCK(intSave);
697
698 (VOID)LOS_MemFree(m_aucSysMem1, group);//释放内存
699 OsWriteResourceEvent(OS_RESOURCE_EVENT_FREE);
700 return;
701}
702
703/*! 设置进程的名字*/
704UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name)
705{
706 errno_t errRet;
707
708 if (processCB == NULL) {
709 return LOS_EINVAL;
710 }
711
712 if (name != NULL) {
713 errRet = strncpy_s(processCB->processName, OS_PCB_NAME_LEN, name, OS_PCB_NAME_LEN - 1);
714 if (errRet == EOK) {
715 return LOS_OK;
716 }
717 }
718
719 switch (processCB->processMode) {
720 case OS_KERNEL_MODE:
721 errRet = snprintf_s(processCB->processName, OS_PCB_NAME_LEN, OS_PCB_NAME_LEN - 1,
722 "KerProcess%u", processCB->processID);
723 break;
724 default:
725 errRet = snprintf_s(processCB->processName, OS_PCB_NAME_LEN, OS_PCB_NAME_LEN - 1,
726 "UserProcess%u", processCB->processID);
727 break;
728 }
729
730 if (errRet < 0) {
731 return LOS_NOK;
732 }
733 return LOS_OK;
734}
735
736/*! 初始化PCB(进程控制块)*/
737STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name)
738{
739 processCB->processMode = mode; //用户态进程还是内核态进程
740 processCB->processStatus = OS_PROCESS_STATUS_INIT; //进程初始状态
741 processCB->parentProcessID = OS_INVALID_VALUE; //爸爸进程,外面指定
742 processCB->threadGroupID = OS_INVALID_VALUE; //所属线程组
743 processCB->umask = OS_PROCESS_DEFAULT_UMASK; //掩码
744 processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
745
746 LOS_ListInit(&processCB->threadSiblingList);//初始化孩子任务/线程链表,上面挂的都是由此fork的孩子线程 见于 OsTaskCBInit LOS_ListTailInsert(&(processCB->threadSiblingList), &(taskCB->threadList));
747 LOS_ListInit(&processCB->childrenList); //初始化孩子进程链表,上面挂的都是由此fork的孩子进程 见于 OsCopyParent LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);
748 LOS_ListInit(&processCB->exitChildList); //初始化记录退出孩子进程链表,上面挂的是哪些exit 见于 OsProcessNaturalExit LOS_ListTailInsert(&parentCB->exitChildList, &processCB->siblingList);
749 LOS_ListInit(&(processCB->waitList)); //初始化等待任务链表 上面挂的是处于等待的 见于 OsWaitInsertWaitLIstInOrder LOS_ListHeadInsert(&processCB->waitList, &runTask->pendList);
750
751#ifdef LOSCFG_KERNEL_VM
752 if (OsProcessIsUserMode(processCB)) {//如果是用户态进程
753 processCB->vmSpace = OsCreateUserVmSpace();//创建用户空间
754 if (processCB->vmSpace == NULL) {
755 processCB->processStatus = OS_PROCESS_FLAG_UNUSED;
756 return LOS_ENOMEM;
757 }
758 } else {
759 processCB->vmSpace = LOS_GetKVmSpace();//从这里也可以看出,所有内核态进程是共享一个进程空间的
760 }//在鸿蒙内核态进程只有kprocess 和 kidle 两个
761#endif
762
763#ifdef LOSCFG_KERNEL_CPUP
765 if (processCB->processCpup == NULL) {
766 return LOS_ENOMEM;
767 }
768 (VOID)memset_s(processCB->processCpup, sizeof(OsCpupBase), 0, sizeof(OsCpupBase));
769#endif
770#ifdef LOSCFG_SECURITY_VID
771 status_t status = VidMapListInit(processCB);
772 if (status != LOS_OK) {
773 return LOS_ENOMEM;
774 }
775#endif
776#ifdef LOSCFG_SECURITY_CAPABILITY
777 OsInitCapability(processCB);//初始化进程安全相关功能
778#endif
779
780 if (OsSetProcessName(processCB, name) != LOS_OK) {
781 return LOS_ENOMEM;
782 }
783
784 return LOS_OK;
785}
786//创建用户
787#ifdef LOSCFG_SECURITY_CAPABILITY
788STATIC User *OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)//参数size 表示组数量
789{ //(size - 1) * sizeof(UINT32) 用于 user->groups[..],这种设计节约了内存,不造成不需要的浪费
790 User *user = LOS_MemAlloc(m_aucSysMem1, sizeof(User) + (size - 1) * sizeof(UINT32));
791 if (user == NULL) {
792 return NULL;
793 }
794
795 user->userID = userID;
796 user->effUserID = userID;
797 user->gid = gid;
798 user->effGid = gid;
799 user->groupNumber = size;//用户组数量
800 user->groups[0] = gid; //用户组列表,一个用户可以属于多个用户组
801 return user;
802}
803
804/*! 检查参数群组ID是否在当前用户所属群组中*/
805LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid)
806{
807 UINT32 intSave;
808 UINT32 count;
809 User *user = NULL;
810
811 SCHEDULER_LOCK(intSave);
812 user = OsCurrUserGet();//当前进程所属用户
813 for (count = 0; count < user->groupNumber; count++) {//循环对比
814 if (user->groups[count] == gid) {
815 SCHEDULER_UNLOCK(intSave);
816 return TRUE;
817 }
818 }
819
820 SCHEDULER_UNLOCK(intSave);
821 return FALSE;
822}
823#endif
824
825/*! 获取当前进程的用户ID*/
826LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID)
827{
828#ifdef LOSCFG_SECURITY_CAPABILITY
829 UINT32 intSave;
830 INT32 uid;
831
832 SCHEDULER_LOCK(intSave);
833 uid = (INT32)OsCurrUserGet()->userID;
834 SCHEDULER_UNLOCK(intSave);
835 return uid;
836#else
837 return 0;
838#endif
839}
840
841/*! 获取当前进程的用户组ID*/
842LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID)
843{
844#ifdef LOSCFG_SECURITY_CAPABILITY
845 UINT32 intSave;
846 INT32 gid;
847
848 SCHEDULER_LOCK(intSave);
849 gid = (INT32)OsCurrUserGet()->gid;
850 SCHEDULER_UNLOCK(intSave);
851
852 return gid;
853#else
854 return 0;
855#endif
856}
857
858/*! 进程创建初始化*/
859STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name)
860{
861 ProcessGroup *group = NULL;
862 UINT32 ret = OsInitPCB(processCB, flags, name);
863 if (ret != LOS_OK) {
864 goto EXIT;
865 }
866
867#ifdef LOSCFG_FS_VFS
868 processCB->files = alloc_files();//分配进程的文件的管理器
869 if (processCB->files == NULL) {
870 ret = LOS_ENOMEM;
871 goto EXIT;
872 }
873#endif
874
875 group = OsCreateProcessGroup(processCB->processID);//创建进程组
876 if (group == NULL) {
877 ret = LOS_ENOMEM;
878 goto EXIT;
879 }
880
881#ifdef LOSCFG_SECURITY_CAPABILITY //用户安全宏
882 processCB->user = OsCreateUser(0, 0, 1);//创建用户
883 if (processCB->user == NULL) {
884 ret = LOS_ENOMEM;
885 goto EXIT;
886 }
887#endif
888
889 return LOS_OK;
890
891EXIT:
892 OsDeInitPCB(processCB);//删除进程控制块,归还内存
893 return ret;
894}
895/*! 创建2,0号进程,即内核态进程的老祖宗*/
896LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
897{
898 UINT32 ret = OsProcessInit();
899 if (ret != LOS_OK) {
900 return ret;
901 }
902
903 LosProcessCB *kerInitProcess = OS_PCB_FROM_PID(g_kernelInitProcess);//获取进程池中2号实体
904 ret = OsProcessCreateInit(kerInitProcess, OS_KERNEL_MODE, "KProcess");//创建内核态祖宗进程
905 if (ret != LOS_OK) {
906 return ret;
907 }
908
909 kerInitProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;//去掉初始化标签
910 g_processGroup = kerInitProcess->group;//进程组ID就是2号进程本身
911 LOS_ListInit(&g_processGroup->groupList);//初始化进程组链表
912
913 LosProcessCB *idleProcess = OS_PCB_FROM_PID(g_kernelIdleProcess);//获取进程池中0号实体
914 ret = OsInitPCB(idleProcess, OS_KERNEL_MODE, "KIdle");//创建内核态0号进程
915 if (ret != LOS_OK) {
916 return ret;
917 }
918 idleProcess->parentProcessID = kerInitProcess->processID;//认2号进程为父,它可是长子.
919 LOS_ListTailInsert(&kerInitProcess->childrenList, &idleProcess->siblingList);//挂到内核态祖宗进程的子孙链接上
920 idleProcess->group = kerInitProcess->group;//和老祖宗一个进程组,注意是父子并不代表是朋友.
921 LOS_ListTailInsert(&kerInitProcess->group->processList, &idleProcess->subordinateGroupList);//挂到老祖宗的进程组链表上,进入了老祖宗的朋友圈.
922#ifdef LOSCFG_SECURITY_CAPABILITY
923 idleProcess->user = kerInitProcess->user;//共享用户
924#endif
925#ifdef LOSCFG_FS_VFS
926 idleProcess->files = kerInitProcess->files;//共享文件
927#endif
928 idleProcess->processStatus &= ~OS_PROCESS_STATUS_INIT;
929
930 ret = OsIdleTaskCreate();//创建cpu的idle任务,从此当前CPU OsPercpuGet()->idleTaskID 有了休息的地方.
931 if (ret != LOS_OK) {
932 return ret;
933 }
934 idleProcess->threadGroupID = OsGetIdleTaskId();
935
936 return LOS_OK;
937}
938/// 进程调度参数检查
939STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
940{
941 if (OS_PID_CHECK_INVALID(pid)) {//进程ID是否有效,默认 g_processMaxNum = 64
942 return LOS_EINVAL;
943 }
944
945 if (which != LOS_PRIO_PROCESS) {//进程标识
946 return LOS_EINVAL;
947 }
948
949 if (prio > OS_PROCESS_PRIORITY_LOWEST) {//鸿蒙优先级是 0 -31级,0级最大
950 return LOS_EINVAL;//返回无效参数
951 }
952
953 if (policy != LOS_SCHED_RR) {
954 return LOS_EINVAL;
955 }
956
957 return LOS_OK;
958}
959
960#ifdef LOSCFG_SECURITY_CAPABILITY //检查进程的安全许可证
961STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedParam *param, UINT16 prio)
962{
963 LosProcessCB *runProcess = OsCurrProcessGet();//获得当前进程
964
965 /* always trust kernel process */
966 if (!OsProcessIsUserMode(runProcess)) {//进程必须在内核模式下,也就是说在内核模式下是安全的.
967 return TRUE;
968 }
969
970 /* user mode process can reduce the priority of itself */
971 if ((runProcess->processID == processCB->processID) && (prio > param->basePrio)) {
972 return TRUE;
973 }
974
975 /* user mode process with privilege of CAP_SCHED_SETPRIORITY can change the priority */
976 if (IsCapPermit(CAP_SCHED_SETPRIORITY)) {
977 return TRUE;
978 }
979 return FALSE;
980}
981#endif
982/// 设置进程调度计划
983LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
984{
985 SchedParam param = { 0 };
986 UINT32 intSave;
987
988 INT32 ret = OsProcessSchedlerParamCheck(which, pid, prio, policy);
989 if (ret != LOS_OK) {
990 return -ret;
991 }
992
993 LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
994 SCHEDULER_LOCK(intSave);//持有调度自旋锁,多CPU情况下调度期间需要原子处理
995 if (OsProcessIsInactive(processCB)) {//进程未活动的处理
996 ret = LOS_ESRCH;
997 goto EXIT;
998 }
999
1000#ifdef LOSCFG_SECURITY_CAPABILITY
1001 if (!OsProcessCapPermitCheck(processCB, &param, prio)) {
1002 ret = LOS_EPERM;
1003 goto EXIT;
1004 }
1005#endif
1006
1007 LosTaskCB *taskCB = OS_TCB_FROM_TID(processCB->threadGroupID);
1008 taskCB->ops->schedParamGet(taskCB, &param);
1009 param.basePrio = prio;
1010
1011 BOOL needSched = taskCB->ops->schedParamModify(taskCB, &param);
1012 SCHEDULER_UNLOCK(intSave);//还锁
1013
1014 LOS_MpSchedule(OS_MP_CPU_ALL);//核间中断
1015 if (needSched && OS_SCHEDULER_ACTIVE) {
1016 LOS_Schedule();//发起调度
1017 }
1018 return LOS_OK;
1019
1020EXIT:
1021 SCHEDULER_UNLOCK(intSave);//还锁
1022 return -ret;
1023}
1024/// 设置指定进程的调度参数,包括优先级和调度策略
1025LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, UINT16 prio)
1026{
1027 return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, prio, policy);
1028}
1029/// 获得指定进程的调度策略
1031{
1032 UINT32 intSave;
1033
1034 if (OS_PID_CHECK_INVALID(pid)) {
1035 return -LOS_EINVAL;
1036 }
1037
1038 SCHEDULER_LOCK(intSave);
1039 LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
1040 if (OsProcessIsUnused(processCB)) {
1041 SCHEDULER_UNLOCK(intSave);
1042 return -LOS_ESRCH;
1043 }
1044
1045 SCHEDULER_UNLOCK(intSave);
1046
1047 return LOS_SCHED_RR;
1048}
1049/// 接口封装 - 设置进程优先级
1050LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, UINT16 prio)
1051{
1052 return OsSetProcessScheduler(LOS_PRIO_PROCESS, pid, prio, LOS_GetProcessScheduler(pid));
1053}
1054/// 接口封装 - 获取进程优先级 which:标识进程,进程组,用户
1055LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
1056{
1057 UINT32 intSave;
1058 SchedParam param = { 0 };
1059 (VOID)which;
1060
1061 if (OS_PID_CHECK_INVALID(pid)) {
1062 return -LOS_EINVAL;
1063 }
1064
1065 if (which != LOS_PRIO_PROCESS) {
1066 return -LOS_EINVAL;
1067 }
1068
1069 LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
1070 SCHEDULER_LOCK(intSave);
1071 if (OsProcessIsUnused(processCB)) {
1072 SCHEDULER_UNLOCK(intSave);
1073 return -LOS_ESRCH;
1074 }
1075
1076 LosTaskCB *taskCB = OS_TCB_FROM_TID(processCB->threadGroupID);
1077 taskCB->ops->schedParamGet(taskCB, &param);
1078
1079 SCHEDULER_UNLOCK(intSave);
1080 return param.basePrio;
1081}
1082/// 接口封装 - 获取指定进程优先级
1084{
1085 return OsGetProcessPriority(LOS_PRIO_PROCESS, pid);
1086}
1087
1088/*!
1089* 将任务挂入进程的waitList链表,表示这个任务在等待某个进程的退出
1090* 当被等待进程退出时候会将自己挂到父进程的退出子进程链表和进程组的退出进程链表.
1091*/
1092STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *processCB)
1093{
1094 LOS_DL_LIST *head = &processCB->waitList;
1095 LOS_DL_LIST *list = head;
1096 LosTaskCB *taskCB = NULL;
1097
1098 if (runTask->waitFlag == OS_PROCESS_WAIT_GID) {
1099 while (list->pstNext != head) {
1100 taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
1101 if (taskCB->waitFlag == OS_PROCESS_WAIT_PRO) {
1102 list = list->pstNext;
1103 continue;
1104 }
1105 break;
1106 }
1107 } else if (runTask->waitFlag == OS_PROCESS_WAIT_ANY) {
1108 while (list->pstNext != head) {
1109 taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(list));
1110 if (taskCB->waitFlag != OS_PROCESS_WAIT_ANY) {
1111 list = list->pstNext;
1112 continue;
1113 }
1114 break;
1115 }
1116 }
1117 /* if runTask->waitFlag == OS_PROCESS_WAIT_PRO,
1118 * this node is inserted directly into the header of the waitList
1119 */
1120 (VOID)runTask->ops->wait(runTask, list->pstNext, LOS_WAIT_FOREVER);
1121 return;
1122}
1123/// 设置等待子进程退出方式方法
1124STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcessCB **child)
1125{
1126 LosProcessCB *childCB = NULL;
1127 ProcessGroup *group = NULL;
1128 LosTaskCB *runTask = OsCurrTaskGet();
1129 UINT32 ret;
1130
1131 if (pid > 0) {//等待进程号为pid的子进程结束
1132 /* Wait for the child process whose process number is pid. */
1133 childCB = OsFindExitChildProcess(processCB, pid);//看能否从退出的孩子链表中找到PID
1134 if (childCB != NULL) {//找到了,确实有一个已经退出的PID,注意一个进程退出时会挂到父进程的exitChildList上
1135 goto WAIT_BACK;//直接成功返回
1136 }
1137
1138 ret = OsFindChildProcess(processCB, pid);//看能否从现有的孩子链表中找到PID
1139 if (ret != LOS_OK) {
1140 return LOS_ECHILD;//参数进程并没有这个PID孩子,返回孩子进程失败.
1141 }
1142 runTask->waitFlag = OS_PROCESS_WAIT_PRO;//设置当前任务的等待类型
1143 runTask->waitID = pid; //当前任务要等待进程ID结束
1144 } else if (pid == 0) {//等待同一进程组中的任何子进程
1145 /* Wait for any child process in the same process group */
1146 childCB = OsFindGroupExitProcess(processCB->group, OS_INVALID_VALUE);//看能否从退出的孩子链表中找到PID
1147 if (childCB != NULL) {//找到了,确实有一个已经退出的PID
1148 goto WAIT_BACK;//直接成功返回
1149 }
1150 runTask->waitID = processCB->group->groupID;//等待进程组的任意一个子进程结束
1151 runTask->waitFlag = OS_PROCESS_WAIT_GID;//设置当前任务的等待类型
1152 } else if (pid == -1) {//等待任意子进程
1153 /* Wait for any child process */
1154 childCB = OsFindExitChildProcess(processCB, OS_INVALID_VALUE);//看能否从退出的孩子链表中找到PID
1155 if (childCB != NULL) {//找到了,确实有一个已经退出的PID
1156 goto WAIT_BACK;
1157 }
1158 runTask->waitID = pid;//等待PID,这个PID可以和当前进程没有任何关系
1159 runTask->waitFlag = OS_PROCESS_WAIT_ANY;//设置当前任务的等待类型
1160 } else { /* pid < -1 */ //等待指定进程组内为|pid|的所有子进程
1161 /* Wait for any child process whose group number is the pid absolute value. */
1162 group = OsFindProcessGroup(-pid);//先通过PID找到进程组
1163 if (group == NULL) {
1164 return LOS_ECHILD;
1165 }
1166
1167 childCB = OsFindGroupExitProcess(group, OS_INVALID_VALUE);//在进程组里任意一个已经退出的子进程
1168 if (childCB != NULL) {
1169 goto WAIT_BACK;
1170 }
1171
1172 runTask->waitID = -pid;//此处用负数是为了和(pid == 0)以示区别,因为二者的waitFlag都一样.
1173 runTask->waitFlag = OS_PROCESS_WAIT_GID;//设置当前任务的等待类型
1174 }
1175
1176WAIT_BACK:
1177 *child = childCB;
1178 return LOS_OK;
1179}
1180/// 等待回收孩子进程 @note_thinking 这样写Porcess不太好吧
1181STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info)
1182{
1183 ProcessGroup *group = NULL;
1184 UINT32 pid = childCB->processID;
1185 UINT16 mode = childCB->processMode;
1186 INT32 exitCode = childCB->exitCode;
1187 UINT32 uid = 0;
1188
1189#ifdef LOSCFG_SECURITY_CAPABILITY
1190 if (childCB->user != NULL) {
1191 uid = childCB->user->userID;
1192 }
1193#endif
1194
1195 OsRecycleZombiesProcess((LosProcessCB *)childCB, &group);//回收僵尸进程
1196 SCHEDULER_UNLOCK(intSave);
1197
1198 if (status != NULL) {
1199 if (mode == OS_USER_MODE) {//孩子为用户态进程
1200 (VOID)LOS_ArchCopyToUser((VOID *)status, (const VOID *)(&(exitCode)), sizeof(INT32));//从内核空间拷贝退出码
1201 } else {
1202 *status = exitCode;
1203 }
1204 }
1205 /* get signal info */
1206 if (info != NULL) {
1207 siginfo_t tempinfo = { 0 };
1208
1209 tempinfo.si_signo = SIGCHLD;
1210 tempinfo.si_errno = 0;
1211 tempinfo.si_pid = pid;
1212 tempinfo.si_uid = uid;
1213 /*
1214 * Process exit code
1215 * 31 15 8 7 0
1216 * | | exit code | core dump | signal |
1217 */
1218 if ((exitCode & 0x7f) == 0) {
1219 tempinfo.si_code = CLD_EXITED;
1220 tempinfo.si_status = (exitCode >> 8U);
1221 } else {
1222 tempinfo.si_code = (exitCode & 0x80) ? CLD_DUMPED : CLD_KILLED;
1223 tempinfo.si_status = (exitCode & 0x7f);
1224 }
1225
1226 if (mode == OS_USER_MODE) {
1227 (VOID)LOS_ArchCopyToUser((VOID *)(info), (const VOID *)(&(tempinfo)), sizeof(siginfo_t));
1228 } else {
1229 (VOID)memcpy_s((VOID *)(info), sizeof(siginfo_t), (const VOID *)(&(tempinfo)), sizeof(siginfo_t));
1230 }
1231 }
1232 (VOID)LOS_MemFree(m_aucSysMem1, group);
1233 return pid;
1234}
1235/// 检查要等待的孩子进程
1237{ //当进程没有孩子且没有退出的孩子进程
1238 if (LOS_ListEmpty(&(processCB->childrenList)) && LOS_ListEmpty(&(processCB->exitChildList))) {
1239 return LOS_ECHILD;
1240 }
1241
1242 return OsWaitSetFlag(processCB, pid, childCB);//设置等待子进程退出方式方法
1243}
1244
1246{
1247 UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WUNTRACED | LOS_WAIT_WCONTINUED;
1248
1249 flag = ~flag & options;
1250 if (flag != 0) {//三种方式中一种都没有
1251 return LOS_EINVAL;//无效参数
1252 }
1253
1254 if ((options & (LOS_WAIT_WCONTINUED | LOS_WAIT_WUNTRACED)) != 0) {//暂不支持这两种方式.
1255 return LOS_EOPNOTSUPP;//不支持
1256 }
1257
1258 if (OS_INT_ACTIVE) {//中断发生期间
1259 return LOS_EINTR;//中断提示
1260 }
1261
1262 return LOS_OK;
1263}
1264///等待子进程结束并回收子进程,返回已经终止的子进程的进程ID号,并清除僵死进程。
1265STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage)
1266{
1267 (VOID)rusage;
1268 UINT32 ret;
1269 UINT32 intSave;
1270 LosProcessCB *childCB = NULL;
1271
1272 LosProcessCB *processCB = OsCurrProcessGet();
1273 LosTaskCB *runTask = OsCurrTaskGet();
1274 SCHEDULER_LOCK(intSave);
1275 ret = OsWaitChildProcessCheck(processCB, pid, &childCB);//先检查下看能不能找到参数要求的退出子进程
1276 if (ret != LOS_OK) {
1277 pid = -ret;
1278 goto ERROR;
1279 }
1280
1281 if (childCB != NULL) {//找到了进程
1282 return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info);
1283 }
1284 //没有找到,看是否要返回还是去做个登记
1285 if ((options & LOS_WAIT_WNOHANG) != 0) {//有LOS_WAIT_WNOHANG标签
1286 runTask->waitFlag = 0;//等待标识置0
1287 pid = 0;//这里置0,是为了 return 0
1288 goto ERROR;
1289 }
1290 //等待孩子进程退出
1291 OsWaitInsertWaitListInOrder(runTask, processCB);//将当前任务挂入进程waitList链表
1292 //发起调度的目的是为了让出CPU,让其他进程/任务运行
1293
1294 runTask->waitFlag = 0;
1295 if (runTask->waitID == OS_INVALID_VALUE) {
1296 pid = -LOS_ECHILD;//没有此子进程
1297 goto ERROR;
1298 }
1299
1300 childCB = OS_PCB_FROM_PID(runTask->waitID);//获取当前任务的等待子进程ID
1301 if (!(childCB->processStatus & OS_PROCESS_STATUS_ZOMBIES)) {//子进程非僵死进程
1302 pid = -LOS_ESRCH;//没有此进程
1303 goto ERROR;
1304 }
1305 //回收僵死进程
1306 return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info);
1307
1308ERROR:
1309 SCHEDULER_UNLOCK(intSave);
1310 return pid;
1311}
1312
1313LITE_OS_SEC_TEXT INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, VOID *rusage)
1314{
1315 (VOID)rusage;
1316 UINT32 ret;
1317
1318 ret = OsWaitOptionsCheck(options);
1319 if (ret != LOS_OK) {
1320 return -ret;
1321 }
1322
1323 return OsWait(pid, status, NULL, options, NULL);
1324}
1325
1327{
1328 UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WEXITED | LOS_WAIT_WNOWAIT;
1329
1330 flag = ~flag & options;
1331 if ((flag != 0) || (options == 0)) {
1332 return LOS_EINVAL;
1333 }
1334
1335 /*
1336 * only support LOS_WAIT_WNOHANG | LOS_WAIT_WEXITED
1337 * notsupport LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WNOWAIT
1338 */
1339 if ((options & (LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WNOWAIT)) != 0) {
1340 return LOS_EOPNOTSUPP;
1341 }
1342
1343 if (OS_INT_ACTIVE) {
1344 return LOS_EINTR;
1345 }
1346
1347 return LOS_OK;
1348}
1349
1350LITE_OS_SEC_TEXT INT32 LOS_Waitid(INT32 pid, USER siginfo_t *info, UINT32 options, VOID *rusage)
1351{
1352 (VOID)rusage;
1353 UINT32 ret;
1354
1355 /* check options value */
1356 ret = OsWaitidOptionsCheck(options);
1357 if (ret != LOS_OK) {
1358 return -ret;
1359 }
1360
1361 return OsWait(pid, NULL, info, options, NULL);
1362}
1363
1364/// 设置进程组检查
1366{
1367 LosProcessCB *runProcessCB = OsCurrProcessGet();//拿到当前运行进程
1368 LosProcessCB *groupProcessCB = OS_PCB_FROM_PID(gid);//通过组ID拿到组长PCB实体
1369
1370 if (OsProcessIsInactive(processCB)) {//进程是否活动
1371 return LOS_ESRCH;
1372 }
1373 //参数进程不在用户态或者组长不在用户态
1374 if (!OsProcessIsUserMode(processCB) || !OsProcessIsUserMode(groupProcessCB)) {
1375 return LOS_EPERM;
1376 }
1377
1378 if (runProcessCB->processID == processCB->parentProcessID) {
1379 if (processCB->processStatus & OS_PROCESS_FLAG_ALREADY_EXEC) {
1380 return LOS_EACCES;
1381 }
1382 } else if (processCB->processID != runProcessCB->processID) {
1383 return LOS_ESRCH;
1384 }
1385
1386 /* Add the process to another existing process group */
1387 if (processCB->processID != gid) {
1388 if (!(groupProcessCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER)) {
1389 return LOS_EPERM;
1390 }
1391
1392 if ((groupProcessCB->parentProcessID != processCB->parentProcessID) && (gid != processCB->parentProcessID)) {
1393 return LOS_EPERM;
1394 }
1395 }
1396
1397 return LOS_OK;
1398}
1399
1401{
1402 ProcessGroup *oldGroup = NULL;
1403 ProcessGroup *newGroup = NULL;
1404 LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
1405 UINT32 ret = OsSetProcessGroupCheck(processCB, gid);
1406 if (ret != LOS_OK) {
1407 return ret;
1408 }
1409
1410 if (processCB->group->groupID == gid) {
1411 return LOS_OK;
1412 }
1413
1414 oldGroup = processCB->group;
1415 OsExitProcessGroup(processCB, group);
1416
1417 newGroup = OsFindProcessGroup(gid);
1418 if (newGroup != NULL) {
1419 LOS_ListTailInsert(&newGroup->processList, &processCB->subordinateGroupList);
1420 processCB->group = newGroup;
1421 return LOS_OK;
1422 }
1423
1424 newGroup = OsCreateProcessGroup(gid);
1425 if (newGroup == NULL) {
1426 LOS_ListTailInsert(&oldGroup->processList, &processCB->subordinateGroupList);
1427 processCB->group = oldGroup;
1428 if (*group != NULL) {
1430 processCB = OS_PCB_FROM_PID(oldGroup->groupID);
1431 processCB->processStatus |= OS_PROCESS_FLAG_GROUP_LEADER;
1432 *group = NULL;
1433 }
1434 return LOS_EPERM;
1435 }
1436 return LOS_OK;
1437}
1438
1439LITE_OS_SEC_TEXT INT32 OsSetProcessGroupID(UINT32 pid, UINT32 gid)
1440{
1441 ProcessGroup *group = NULL;
1442 UINT32 ret;
1443 UINT32 intSave;
1444
1445 if ((OS_PID_CHECK_INVALID(pid)) || (OS_PID_CHECK_INVALID(gid))) {
1446 return -LOS_EINVAL;
1447 }
1448
1449 SCHEDULER_LOCK(intSave);
1450 ret = OsSetProcessGroupIDUnsafe(pid, gid, &group);
1451 SCHEDULER_UNLOCK(intSave);
1452 (VOID)LOS_MemFree(m_aucSysMem1, group);
1453 return -ret;
1454}
1455
1457{
1458 return OsSetProcessGroupID(OsCurrProcessGet()->processID, gid);
1459}
1460
1462{
1463 INT32 gid;
1464 UINT32 intSave;
1465 LosProcessCB *processCB = NULL;
1466
1467 if (OS_PID_CHECK_INVALID(pid)) {
1468 return -LOS_EINVAL;
1469 }
1470
1471 SCHEDULER_LOCK(intSave);
1472 processCB = OS_PCB_FROM_PID(pid);
1473 if (OsProcessIsUnused(processCB)) {
1474 gid = -LOS_ESRCH;
1475 goto EXIT;
1476 }
1477
1478 gid = (INT32)processCB->group->groupID;
1479
1480EXIT:
1481 SCHEDULER_UNLOCK(intSave);
1482 return gid;
1483}
1484/// 获取当前进程的组ID
1485LITE_OS_SEC_TEXT INT32 LOS_GetCurrProcessGroupID(VOID)
1486{
1487 return LOS_GetProcessGroupID(OsCurrProcessGet()->processID);
1488}
1489/// 为用户态任务分配栈空间
1490#ifdef LOSCFG_KERNEL_VM
1492{
1493 LosProcessCB *processCB = NULL;
1494 UINT32 intSave;
1495
1496 SCHEDULER_LOCK(intSave);
1498 SCHEDULER_UNLOCK(intSave);
1499 PRINT_ERR("No idle PCB in the system!\n");
1500 return NULL;
1501 }
1502
1503 processCB = OS_PCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_freeProcess));
1504 LOS_ListDelete(&processCB->pendList);
1505 SCHEDULER_UNLOCK(intSave);
1506
1507 return processCB;
1508}
1509
1510STATIC VOID *OsUserInitStackAlloc(LosProcessCB *processCB, UINT32 *size)
1511{
1512 LosVmMapRegion *region = NULL;
1513 UINT32 stackSize = ALIGN(OS_USER_TASK_STACK_SIZE, PAGE_SIZE);//1M栈空间 按页对齐
1514 //线性区分配虚拟内存
1515 region = LOS_RegionAlloc(processCB->vmSpace, 0, stackSize,
1516 VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ |
1517 VM_MAP_REGION_FLAG_PERM_WRITE, 0);//可使用可读可写区
1518 if (region == NULL) {
1519 return NULL;
1520 }
1521
1522 LOS_SetRegionTypeAnon(region);//匿名映射
1523 region->regionFlags |= VM_MAP_REGION_FLAG_STACK;//标记该线性区为栈区
1524
1525 *size = stackSize;//记录栈大小
1526
1527 return (VOID *)(UINTPTR)region->range.base;
1528}
1529
1530#ifdef LOSCFG_KERNEL_DYNLOAD
1531LITE_OS_SEC_TEXT VOID OsExecProcessVmSpaceRestore(LosVmSpace *oldSpace)
1532{
1533 LosProcessCB *processCB = OsCurrProcessGet();
1534 LosTaskCB *runTask = OsCurrTaskGet();
1535
1536 processCB->vmSpace = oldSpace;
1537 runTask->archMmu = (UINTPTR)&processCB->vmSpace->archMmu;
1539}
1540
1541LITE_OS_SEC_TEXT LosVmSpace *OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR stackBase, INT32 randomDevFD)
1542{
1543 LosProcessCB *processCB = OsCurrProcessGet();
1544 LosTaskCB *runTask = OsCurrTaskGet();
1545
1548
1549 LosVmSpace *oldSpace = processCB->vmSpace;
1550 processCB->vmSpace = newSpace;
1551 processCB->vmSpace->heapBase += OsGetRndOffset(randomDevFD);
1552 processCB->vmSpace->heapNow = processCB->vmSpace->heapBase;
1553 processCB->vmSpace->mapBase += OsGetRndOffset(randomDevFD);
1554 processCB->vmSpace->mapSize = stackBase - processCB->vmSpace->mapBase;
1555 runTask->archMmu = (UINTPTR)&processCB->vmSpace->archMmu;
1557 return oldSpace;
1558}
1559
1560/**
1561 * @brief 进程的回收再利用,被LOS_DoExecveFile调用
1562 * @param processCB
1563 * @param name
1564 * @param oldSpace
1565 * @param oldFiles
1566 * @return LITE_OS_SEC_TEXT
1567 */
1568LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name,
1569 LosVmSpace *oldSpace, UINTPTR oldFiles)
1570{
1571 UINT32 ret;
1572 const CHAR *processName = NULL;
1573
1574 if ((processCB == NULL) || (name == NULL)) {
1575 return LOS_NOK;
1576 }
1577
1578 processName = strrchr(name, '/');
1579 processName = (processName == NULL) ? name : (processName + 1); /* 1: Do not include '/' */
1580
1581 ret = (UINT32)OsSetTaskName(OsCurrTaskGet(), processName, TRUE);
1582 if (ret != LOS_OK) {
1583 return ret;
1584 }
1585
1586#ifdef LOSCFG_KERNEL_LITEIPC
1587 (VOID)LiteIpcPoolDestroy(processCB->processID);
1588#endif
1589
1590 processCB->sigHandler = 0;
1592
1593 LOS_VmSpaceFree(oldSpace);
1594#ifdef LOSCFG_FS_VFS
1595 CloseOnExec((struct files_struct *)oldFiles);
1596 delete_files_snapshot((struct files_struct *)oldFiles);
1597#endif
1598
1599 OsSwtmrRecycle(processCB->processID);//回收定时器
1600 processCB->timerID = (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID;
1601
1602#ifdef LOSCFG_SECURITY_VID
1603 VidMapDestroy(processCB);
1604 ret = VidMapListInit(processCB);
1605 if (ret != LOS_OK) {
1606 return LOS_NOK;
1607 }
1608#endif
1609
1610 processCB->processStatus &= ~OS_PROCESS_FLAG_EXIT; //去掉进程退出标签
1611 processCB->processStatus |= OS_PROCESS_FLAG_ALREADY_EXEC;//加上进程运行elf标签
1612
1613 return LOS_OK;
1614}
1615/// 执行用户态任务, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小
1616LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize)
1617{
1618 UINT32 intSave;
1619
1620 if (entry == NULL) {
1621 return LOS_NOK;
1622 }
1623
1624 if ((sp == 0) || (LOS_Align(sp, LOSCFG_STACK_POINT_ALIGN_SIZE) != sp)) {//对齐
1625 return LOS_NOK;
1626 }
1627 //注意 sp此时指向栈底,栈底地址要大于栈顶
1628 if ((mapBase == 0) || (mapSize == 0) || (sp <= mapBase) || (sp > (mapBase + mapSize))) {//参数检查
1629 return LOS_NOK;
1630 }
1631
1632 LosTaskCB *taskCB = OsCurrTaskGet();//获取当前任务
1633 SCHEDULER_LOCK(intSave);//拿自旋锁
1634
1635 taskCB->userMapBase = mapBase;//用户态栈顶位置
1636 taskCB->userMapSize = mapSize;//用户态栈
1637 taskCB->taskEntry = (TSK_ENTRY_FUNC)entry;//任务的入口函数
1638 //初始化内核态栈
1639 TaskContext *taskContext = (TaskContext *)OsTaskStackInit(taskCB->taskID, taskCB->stackSize,
1640 (VOID *)taskCB->topOfStack, FALSE);
1641 OsUserTaskStackInit(taskContext, (UINTPTR)taskCB->taskEntry, sp);//初始化用户栈,将内核栈中上下文的 context->R[0] = sp ,context->sp = sp
1642 //这样做的目的是将用户栈SP保存到内核栈中,
1643 SCHEDULER_UNLOCK(intSave);//解锁
1644 return LOS_OK;
1645}
1646#endif
1647/// 用户进程开始初始化
1649{
1650 UINT32 intSave;
1651 INT32 ret;
1652
1653 UINT32 taskID = OsCreateUserTask(processCB->processID, param);
1654 if (taskID == OS_INVALID_VALUE) {
1655 return LOS_NOK;
1656 }
1657
1658 ret = LOS_SetProcessPriority(processCB->processID, OS_PROCESS_USERINIT_PRIORITY);
1659 if (ret != LOS_OK) {
1660 PRINT_ERR("User init process set priority failed! ERROR:%d \n", ret);
1661 goto EXIT;
1662 }
1663
1664 SCHEDULER_LOCK(intSave);
1665 processCB->processStatus &= ~OS_PROCESS_STATUS_INIT;
1666 SCHEDULER_UNLOCK(intSave);
1667
1668 ret = LOS_SetTaskScheduler(taskID, LOS_SCHED_RR, OS_TASK_PRIORITY_LOWEST);//调度器:设置为抢占式调度和最低任务优先级(31级)
1669 if (ret != LOS_OK) {
1670 PRINT_ERR("User init process set scheduler failed! ERROR:%d \n", ret);
1671 goto EXIT;
1672 }
1673
1674 return LOS_OK;
1675
1676EXIT:
1677 (VOID)LOS_TaskDelete(taskID);
1678 return ret;
1679}
1680
1682{
1683 /* userInitTextStart -----
1684 * | user text |
1685 *
1686 * | user data | initSize
1687 * userInitBssStart ---
1688 * | user bss | initBssSize
1689 * userInitEnd --- -----
1690 */
1691 errno_t errRet;
1692 INT32 ret;
1693 CHAR *userInitTextStart = (CHAR *)&__user_init_entry;
1694 CHAR *userInitBssStart = (CHAR *)&__user_init_bss;
1695 CHAR *userInitEnd = (CHAR *)&__user_init_end;
1696 UINT32 initBssSize = userInitEnd - userInitBssStart;
1697 UINT32 initSize = userInitEnd - userInitTextStart;
1698 VOID *userBss = NULL;
1699 VOID *userText = NULL;
1700
1701 if ((LOS_Align((UINTPTR)userInitTextStart, PAGE_SIZE) != (UINTPTR)userInitTextStart) ||
1702 (LOS_Align((UINTPTR)userInitEnd, PAGE_SIZE) != (UINTPTR)userInitEnd)) {
1703 return LOS_EINVAL;
1704 }
1705
1706 if ((initSize == 0) || (initSize <= initBssSize)) {
1707 return LOS_EINVAL;
1708 }
1709
1710 userText = LOS_PhysPagesAllocContiguous(initSize >> PAGE_SHIFT);
1711 if (userText == NULL) {
1712 return LOS_NOK;
1713 }
1714
1715 errRet = memcpy_s(userText, initSize, (VOID *)&__user_init_load_addr, initSize - initBssSize);
1716 if (errRet != EOK) {
1717 PRINT_ERR("Load user init text, data and bss failed! err : %d\n", errRet);
1718 goto ERROR;
1719 }
1720 ret = LOS_VaddrToPaddrMmap(processCB->vmSpace, (VADDR_T)(UINTPTR)userInitTextStart, LOS_PaddrQuery(userText),
1721 initSize, VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE |
1722 VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_PERM_EXECUTE |
1723 VM_MAP_REGION_FLAG_PERM_USER);
1724 if (ret < 0) {
1725 PRINT_ERR("Mmap user init text, data and bss failed! err : %d\n", ret);
1726 goto ERROR;
1727 }
1728
1729 /* The User init boot segment may not actually exist */
1730 if (initBssSize != 0) {
1731 userBss = (VOID *)((UINTPTR)userText + userInitBssStart - userInitTextStart);
1732 errRet = memset_s(userBss, initBssSize, 0, initBssSize);
1733 if (errRet != EOK) {
1734 PRINT_ERR("memset user init bss failed! err : %d\n", errRet);
1735 goto ERROR;
1736 }
1737 }
1738
1739 return LOS_OK;
1740
1741ERROR:
1742 (VOID)LOS_PhysPagesFreeContiguous(userText, initSize >> PAGE_SHIFT);
1743 return LOS_NOK;
1744}
1745
1746LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID)
1747{
1748 UINT32 ret;
1749 UINT32 size;
1750 TSK_INIT_PARAM_S param = { 0 };
1751 VOID *stack = NULL;
1752
1753 LosProcessCB *processCB = OS_PCB_FROM_PID(g_userInitProcess);
1754 ret = OsProcessCreateInit(processCB, OS_USER_MODE, "Init");
1755 if (ret != LOS_OK) {
1756 return ret;
1757 }
1758
1759 ret = OsLoadUserInit(processCB);
1760 if (ret != LOS_OK) {
1761 goto ERROR;
1762 }
1763
1764 stack = OsUserInitStackAlloc(processCB, &size);
1765 if (stack == NULL) {
1766 PRINT_ERR("Alloc user init process user stack failed!\n");
1767 goto ERROR;
1768 }
1769
1771 param.userParam.userSP = (UINTPTR)stack + size;
1772 param.userParam.userMapBase = (UINTPTR)stack;
1773 param.userParam.userMapSize = size;
1774 param.uwResved = OS_TASK_FLAG_PTHREAD_JOIN;
1775 ret = OsUserInitProcessStart(processCB, &param);
1776 if (ret != LOS_OK) {
1777 (VOID)OsUnMMap(processCB->vmSpace, param.userParam.userMapBase, param.userParam.userMapSize);
1778 goto ERROR;
1779 }
1780
1781 return LOS_OK;
1782
1783ERROR:
1784 OsDeInitPCB(processCB);
1785 return ret;
1786}
1787/// 拷贝用户信息 直接用memcpy_s
1788STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB)
1789{
1790#ifdef LOSCFG_SECURITY_CAPABILITY
1791 UINT32 size = sizeof(User) + sizeof(UINT32) * (parentCB->user->groupNumber - 1);
1792 childCB->user = LOS_MemAlloc(m_aucSysMem1, size);
1793 if (childCB->user == NULL) {
1794 return LOS_ENOMEM;
1795 }
1796
1797 (VOID)memcpy_s(childCB->user, size, parentCB->user, size);
1798#endif
1799 return LOS_OK;
1800}
1801
1802//拷贝一个Task过程
1803STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size)
1804{
1805 LosTaskCB *runTask = OsCurrTaskGet();
1806 TSK_INIT_PARAM_S taskParam = { 0 };
1807 UINT32 ret, taskID, intSave;
1808 SchedParam param = { 0 };
1809
1810 SCHEDULER_LOCK(intSave);
1811 if (OsProcessIsUserMode(childProcessCB)) {//用户态进程
1812 taskParam.pfnTaskEntry = runTask->taskEntry;//拷贝当前任务入口地址
1813 taskParam.uwStackSize = runTask->stackSize; //栈空间大小
1814 taskParam.userParam.userArea = runTask->userArea; //用户态栈区栈顶位置
1815 taskParam.userParam.userMapBase = runTask->userMapBase; //用户态栈底
1816 taskParam.userParam.userMapSize = runTask->userMapSize; //用户态栈大小
1817 } else {//注意内核态进程创建任务的入口由外界指定,例如 OsCreateIdleProcess 指定了OsIdleTask
1818 taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)entry;//参数(sp)为内核态入口地址
1819 taskParam.uwStackSize = size;//参数(size)为内核态栈大小
1820 }
1821 if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
1822 taskParam.uwResved = LOS_TASK_ATTR_JOINABLE;
1823 }
1824
1825 runTask->ops->schedParamGet(runTask, &param);
1826 SCHEDULER_UNLOCK(intSave);
1827
1828 taskParam.pcName = (CHAR *)name;
1829 taskParam.policy = param.policy;
1830 taskParam.usTaskPrio = param.priority;
1831 taskParam.processID = childProcessCB->processID;
1832
1833 ret = LOS_TaskCreateOnly(&taskID, &taskParam);
1834 if (ret != LOS_OK) {
1835 if (ret == LOS_ERRNO_TSK_TCB_UNAVAILABLE) {
1836 return LOS_EAGAIN;
1837 }
1838 return LOS_ENOMEM;
1839 }
1840
1841 LosTaskCB *childTaskCB = OS_TCB_FROM_TID(taskID);
1842 childTaskCB->taskStatus = runTask->taskStatus;//任务状态先同步,注意这里是赋值操作. ...01101001
1843 childTaskCB->ops->schedParamModify(childTaskCB, &param);
1844 if (childTaskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//因只能有一个运行的task,所以如果一样要改4号位
1845 childTaskCB->taskStatus &= ~OS_TASK_STATUS_RUNNING;//将四号位清0 ,变成 ...01100001
1846 } else {//非运行状态下会发生什么?
1847 if (OS_SCHEDULER_ACTIVE) {//克隆线程发生错误未运行
1848 LOS_Panic("Clone thread status not running error status: 0x%x\n", childTaskCB->taskStatus);
1849 }
1850 childTaskCB->taskStatus &= ~OS_TASK_STATUS_UNUSED;//干净的Task
1851 }
1852
1853 if (OsProcessIsUserMode(childProcessCB)) {//是否是用户进程
1854 SCHEDULER_LOCK(intSave);
1855 OsUserCloneParentStack(childTaskCB->stackPointer, runTask->topOfStack, runTask->stackSize);//拷贝当前任务上下文给新的任务
1856 SCHEDULER_UNLOCK(intSave);
1857 }
1858 return LOS_OK;
1859}
1860//拷贝父亲大人的遗传基因信息
1861STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
1862{
1863 UINT32 ret;
1864 UINT32 intSave;
1865 LosProcessCB *parentProcessCB = NULL;
1866
1867 SCHEDULER_LOCK(intSave);
1868
1869 if (flags & CLONE_PARENT) { //这里指明 childProcessCB 和 runProcessCB 有同一个父亲,是兄弟关系
1870 parentProcessCB = OS_PCB_FROM_PID(runProcessCB->parentProcessID);//找出当前进程的父亲大人
1871 } else {
1872 parentProcessCB = runProcessCB;
1873 }
1874 childProcessCB->parentProcessID = parentProcessCB->processID;//指认父亲,这个赋值代表从此是你儿了
1875 LOS_ListTailInsert(&parentProcessCB->childrenList, &childProcessCB->siblingList);//通过我的兄弟姐妹节点,挂到父亲的孩子链表上,于我而言,父亲的这个链表上挂的都是我的兄弟姐妹
1876 //不会被排序,老大,老二,老三 老天爷指定了。
1877 childProcessCB->group = parentProcessCB->group;//跟父亲大人在同一个进程组,注意父亲可能是组长,但更可能不是组长,
1878 LOS_ListTailInsert(&parentProcessCB->group->processList, &childProcessCB->subordinateGroupList);//自己去组里登记下,这个要自己登记,跟父亲没啥关系。
1879 ret = OsCopyUser(childProcessCB, parentProcessCB);
1880
1881 SCHEDULER_UNLOCK(intSave);
1882 return ret;
1883}
1884//拷贝虚拟空间
1885STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
1886{
1887 status_t status;
1888 UINT32 intSave;
1889
1890 if (!OsProcessIsUserMode(childProcessCB)) {//不是用户模式,直接返回,什么意思?内核虚拟空间只有一个,无需COPY !!!
1891 return LOS_OK;
1892 }
1893
1894 if (flags & CLONE_VM) {//贴有虚拟内存的标签
1895 SCHEDULER_LOCK(intSave);
1896 childProcessCB->vmSpace->archMmu.virtTtb = runProcessCB->vmSpace->archMmu.virtTtb;//TTB虚拟地址基地址,即L1表存放位置,virtTtb是个指针,进程的虚拟空间是指定的范围的
1897 childProcessCB->vmSpace->archMmu.physTtb = runProcessCB->vmSpace->archMmu.physTtb;//TTB物理地址基地址,physTtb是个值,取决于运行时映射到物理内存的具体哪个位置.
1898 SCHEDULER_UNLOCK(intSave);
1899 return LOS_OK;
1900 }
1901
1902 status = LOS_VmSpaceClone(runProcessCB->vmSpace, childProcessCB->vmSpace);//虚拟空间clone
1903 if (status != LOS_OK) {
1904 return LOS_ENOMEM;
1905 }
1906 return LOS_OK;
1907}
1908/// 拷贝进程文件描述符(proc_fd)信息
1909STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
1910{
1911#ifdef LOSCFG_FS_VFS
1912 if (flags & CLONE_FILES) {
1913 childProcessCB->files = runProcessCB->files;
1914 } else {
1915 childProcessCB->files = dup_fd(runProcessCB->files);
1916 }
1917 if (childProcessCB->files == NULL) {
1918 return LOS_ENOMEM;
1919 }
1920#endif
1921
1922 childProcessCB->consoleID = runProcessCB->consoleID;//控制台也是文件
1923 childProcessCB->umask = runProcessCB->umask;
1924 return LOS_OK;
1925}
1926
1927STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINTPTR sp, UINT32 size)
1928{
1929 UINT32 ret;
1930 LosProcessCB *run = OsCurrProcessGet();//获取当前进程
1931
1932 ret = OsInitPCB(child, run->processMode, name);
1933 if (ret != LOS_OK) {
1934 return ret;
1935 }
1936
1937 ret = OsCopyParent(flags, child, run);//拷贝父亲大人的基因信息
1938 if (ret != LOS_OK) {
1939 return ret;
1940 }
1941
1942 return OsCopyTask(flags, child, name, sp, size);//拷贝任务,设置任务入口函数,栈大小
1943}
1944//设置进程组和加入进程调度就绪队列
1946{
1947 UINT32 intSave;
1948 UINT32 ret;
1949 ProcessGroup *group = NULL;
1950
1951 LosTaskCB *taskCB = OS_TCB_FROM_TID(child->threadGroupID);
1952 SCHEDULER_LOCK(intSave);
1953 if (run->group->groupID == OS_USER_PRIVILEGE_PROCESS_GROUP) {//如果是有用户特权进程组
1954 ret = OsSetProcessGroupIDUnsafe(child->processID, child->processID, &group);//设置组ID,存在不安全的风险
1955 if (ret != LOS_OK) {
1956 SCHEDULER_UNLOCK(intSave);
1957 return LOS_ENOMEM;
1958 }
1959 }
1960
1961 child->processStatus &= ~OS_PROCESS_STATUS_INIT;
1962 taskCB->ops->enqueue(OsSchedRunqueue(), taskCB);
1963 SCHEDULER_UNLOCK(intSave);
1964
1965 (VOID)LOS_MemFree(m_aucSysMem1, group);
1966 return LOS_OK;
1967}
1968/// 拷贝进程资源
1970{
1971 UINT32 ret;
1972
1973 ret = OsCopyMM(flags, child, run);//拷贝虚拟空间
1974 if (ret != LOS_OK) {
1975 return ret;
1976 }
1977
1978 ret = OsCopyFile(flags, child, run);//拷贝文件信息
1979 if (ret != LOS_OK) {
1980 return ret;
1981 }
1982
1983#ifdef LOSCFG_KERNEL_LITEIPC
1984 if (run->ipcInfo != NULL) { //重新初始化IPC池
1985 child->ipcInfo = LiteIpcPoolReInit((const ProcIpcInfo *)(run->ipcInfo));//@note_good 将沿用用户态空间地址(即线性区地址)
1986 if (child->ipcInfo == NULL) {//因为整个进程虚拟空间都是拷贝的,ipc的用户态虚拟地址当然可以拷贝,但因进程不同了,所以需要重新申请ipc池和重新
1987 return LOS_ENOMEM;//映射池中两个地址.
1988 }
1989 }
1990#endif
1991
1992#ifdef LOSCFG_SECURITY_CAPABILITY
1993 OsCopyCapability(run, child);//拷贝安全能力
1994#endif
1995
1996 return LOS_OK;
1997}
1998/// 拷贝进程
1999STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size)
2000{
2001 UINT32 ret, processID;
2002 LosProcessCB *run = OsCurrProcessGet();//获取当前进程
2003
2004 LosProcessCB *child = OsGetFreePCB();//从进程池中申请一个进程控制块,鸿蒙进程池默认64
2005 if (child == NULL) {
2006 return -LOS_EAGAIN;
2007 }
2008 processID = child->processID;
2009
2010 ret = OsForkInitPCB(flags, child, name, sp, size);//初始化进程控制块
2011 if (ret != LOS_OK) {
2012 goto ERROR_INIT;
2013 }
2014
2015 ret = OsCopyProcessResources(flags, child, run);//拷贝进程的资源,包括虚拟空间,文件,安全,IPC ==
2016 if (ret != LOS_OK) {
2017 goto ERROR_TASK;
2018 }
2019
2020 ret = OsChildSetProcessGroupAndSched(child, run);//设置进程组和加入进程调度就绪队列
2021 if (ret != LOS_OK) {
2022 goto ERROR_TASK;
2023 }
2024
2025 LOS_MpSchedule(OS_MP_CPU_ALL);//给各CPU发送准备接受调度信号
2026 if (OS_SCHEDULER_ACTIVE) {//当前CPU core处于活动状态
2027 LOS_Schedule();// 申请调度
2028 }
2029
2030 return processID;
2031
2032ERROR_TASK:
2033 (VOID)LOS_TaskDelete(child->threadGroupID);
2034ERROR_INIT:
2035 OsDeInitPCB(child);
2036 return -ret;
2037}
2038
2039/*!
2040 * @brief OsClone 进程克隆
2041 *
2042 * @param flags
2043 * @param size 进程主任务内核栈大小
2044 * @param sp 进程主任务的入口函数
2045 * @return
2046 *
2047 * @see
2048 */
2049LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size)
2050{
2051 UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_VM;
2052
2053 if (flags & (~cloneFlag)) {
2054 PRINT_WARN("Clone dont support some flags!\n");
2055 }
2056
2057 return OsCopyProcess(cloneFlag & flags, NULL, sp, size);
2058}
2059//著名的 fork 函数 记得前往 https://gitee.com/weharmony/kernel_liteos_a_note fork一下 :)
2060LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize)
2061{
2062 UINT32 cloneFlag = CLONE_PARENT | CLONE_THREAD | CLONE_VFORK | CLONE_FILES;
2063
2064 if (flags & (~cloneFlag)) {
2065 PRINT_WARN("Clone dont support some flags!\n");
2066 }
2067
2068 flags |= CLONE_FILES;
2069 return OsCopyProcess(cloneFlag & flags, name, (UINTPTR)entry, stackSize);//拷贝一个进程
2070}
2071#else
2072LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID)
2073{
2074 return 0;
2075}
2076#endif
2077
2078/*!
2079 * @brief LOS_Exit
2080 * 进程退出
2081 * @param status
2082 * @return
2083 *
2084 * @see
2085 */
2086LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status)
2087{
2088 UINT32 intSave;
2089
2090 (void)status;
2091 /* The exit of a kernel - state process must be kernel - state and all threads must actively exit */
2092 LosProcessCB *processCB = OsCurrProcessGet();
2093 SCHEDULER_LOCK(intSave);
2094 if (!OsProcessIsUserMode(processCB) && (processCB->threadNumber != 1)) {//内核态下进程的退出方式,必须是所有的任务都退出了
2095 SCHEDULER_UNLOCK(intSave);
2096 PRINT_ERR("Kernel-state processes with multiple threads are not allowed to exit directly\n");
2097 return;
2098 }
2099 SCHEDULER_UNLOCK(intSave);
2100
2102 OsRunningTaskToExit(OsCurrTaskGet(), OS_PRO_EXIT_OK);
2103}
2104
2105
2106/*!
2107 * @brief LOS_GetUsedPIDList
2108 * 获取使用中的进程列表
2109 * @param pidList
2110 * @param pidMaxNum
2111 * @return
2112 *
2113 * @see
2114 */
2115LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum)
2116{
2117 LosProcessCB *pcb = NULL;
2118 INT32 num = 0;
2119 UINT32 intSave;
2120 UINT32 pid = 1;
2121
2122 if (pidList == NULL) {
2123 return 0;
2124 }
2125 SCHEDULER_LOCK(intSave);
2126 while (OsProcessIDUserCheckInvalid(pid) == false) {//遍历进程池
2127 pcb = OS_PCB_FROM_PID(pid);
2128 pid++;
2129 if (OsProcessIsUnused(pcb)) {//未使用的不算
2130 continue;
2131 }
2132 pidList[num] = pcb->processID;//由参数带走
2133 num++;
2134 if (num >= pidMaxNum) {
2135 break;
2136 }
2137 }
2138 SCHEDULER_UNLOCK(intSave);
2139 return num;
2140}
2141
2142#ifdef LOSCFG_FS_VFS
2143LITE_OS_SEC_TEXT struct fd_table_s *LOS_GetFdTable(UINT32 pid)
2144{
2145 LosProcessCB *pcb = NULL;
2146 struct files_struct *files = NULL;
2147
2148 if (OS_PID_CHECK_INVALID(pid)) {
2149 return NULL;
2150 }
2151 pcb = OS_PCB_FROM_PID(pid);
2152 files = pcb->files;
2153 if (files == NULL) {
2154 return NULL;
2155 }
2156
2157 return files->fdt;
2158}
2159#endif
2160/// 获取当前进程的进程ID
2161LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID)
2162{
2163 return OsCurrProcessGet()->processID;
2164}
2165/// 按指定状态退出指定进程
2166#ifdef LOSCFG_KERNEL_VM
2168{
2169 INT32 ret;
2170
2171 taskCB->taskStatus |= OS_TASK_FLAG_EXIT_KILL;
2172#ifdef LOSCFG_KERNEL_SMP
2173 /** The other core that the thread is running on and is currently running in a non-system call */
2174 if (!taskCB->sig.sigIntLock && (taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
2175 taskCB->signal = SIGNAL_KILL;
2176 LOS_MpSchedule(taskCB->currCpu);
2177 } else
2178#endif
2179 {
2180 ret = OsTaskKillUnsafe(taskCB->taskID, SIGKILL);
2181 if (ret != LOS_OK) {
2182 PRINT_ERR("pid %u exit, Exit task group %u kill %u failed! ERROR: %d\n",
2183 taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, ret);
2184 }
2185 }
2186
2187 if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) {
2188 taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN;
2189 LOS_ListInit(&taskCB->joinList);
2190 }
2191
2192 ret = OsTaskJoinPendUnsafe(taskCB);
2193 if (ret != LOS_OK) {
2194 PRINT_ERR("pid %u exit, Exit task group %u to wait others task %u(0x%x) exit failed! ERROR: %d\n",
2195 taskCB->processID, OsCurrTaskGet()->taskID, taskCB->taskID, taskCB->taskStatus, ret);
2196 }
2197}
2198#endif
2199
2200LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID)
2201{
2202#ifdef LOSCFG_KERNEL_VM
2203 UINT32 intSave;
2204
2205 LosProcessCB *processCB = OsCurrProcessGet();
2206 LosTaskCB *currTask = OsCurrTaskGet();
2207 SCHEDULER_LOCK(intSave);
2208 if ((processCB->processStatus & OS_PROCESS_FLAG_EXIT) || !OsProcessIsUserMode(processCB)) {
2209 SCHEDULER_UNLOCK(intSave);
2210 return;
2211 }
2212
2213 processCB->processStatus |= OS_PROCESS_FLAG_EXIT;
2214 processCB->threadGroupID = currTask->taskID;
2215
2216 LOS_DL_LIST *list = &processCB->threadSiblingList;
2217 LOS_DL_LIST *head = list;
2218 do {
2219 LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList);
2220 if ((OsTaskIsInactive(taskCB) ||
2221 ((taskCB->taskStatus & OS_TASK_STATUS_READY) && !taskCB->sig.sigIntLock)) &&
2222 !(taskCB->taskStatus & OS_TASK_STATUS_RUNNING)) {
2223 OsInactiveTaskDelete(taskCB);
2224 } else if (taskCB != currTask) {
2226 } else {
2227 /* Skip the current task */
2228 list = list->pstNext;
2229 }
2230 } while (head != list->pstNext);
2231
2232 SCHEDULER_UNLOCK(intSave);
2233
2234 LOS_ASSERT(processCB->threadNumber == 1);
2235#endif
2236 return;
2237}
2238/// 获取系统支持的最大进程数目
2240{
2241 return g_processMaxNum;
2242}
2243/// 获取用户态进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的
2244LITE_OS_SEC_TEXT UINT32 OsGetUserInitProcessID(VOID)
2245{
2246 return g_userInitProcess;//用户态根进程 序号为 1
2247}
2248/// 获取内核态根进程
2249LITE_OS_SEC_TEXT UINT32 OsGetKernelInitProcessID(VOID)
2250{
2251 return g_kernelInitProcess;
2252}
2253/// 获取内核态空闲进程
2254LITE_OS_SEC_TEXT UINT32 OsGetIdleProcessID(VOID)
2255{
2256 return g_kernelIdleProcess;
2257}
2258/// 设置进程的信号处理函数
2259LITE_OS_SEC_TEXT VOID OsSetSigHandler(UINTPTR addr)
2260{
2261 OsCurrProcessGet()->sigHandler = addr;
2262}
2263/// 获取进程的信号处理函数
2264LITE_OS_SEC_TEXT UINTPTR OsGetSigHandler(VOID)
2265{
2266 return OsCurrProcessGet()->sigHandler;
2267}
2268
macro EXC_SP_SET stackSize
Definition: asm.h:50
macro EXC_SP_SET reg1 mrc 获取CPU信息 and mov mul reg0 计算当前CPU栈的偏移位置 ldr reg1 相减得到栈顶 mov sp
Definition: asm.h:57
BOOL IsCapPermit(UINT32 capIndex)
Definition: capability.c:43
VOID OsInitCapability(LosProcessCB *processCB)
初始化进程安全能力
Definition: capability.c:54
VOID OsCopyCapability(LosProcessCB *from, LosProcessCB *to)
进程间安全能力的拷贝
Definition: capability.c:59
struct files_struct * dup_fd(struct files_struct *oldf)
复制FD
void delete_files_snapshot(struct files_struct *files)
删除文件管理器快照
struct ProcessCB LosProcessCB
Definition: fd_table.h:105
void delete_files(struct files_struct *files)
删除参数进程的文件管理器
struct files_struct * alloc_files(void)
为进程分配文件管理器,其中包含fd总数,(0,1,2)默认给了stdin,stdout,stderr
void CloseOnExec(struct files_struct *files)
Definition: vfs_cloexec.c:42
LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
Align the value (addr) by some bytes (boundary) you specify.
Definition: los_misc.c:35
NORETURN VOID LOS_Panic(const CHAR *fmt,...)
Kernel panic function.
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
Definition: los_list.h:244
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListHeadInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the head of a doubly linked list.
Definition: los_list.h:268
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsertList(LOS_DL_LIST *oldList, LOS_DL_LIST *newList)
Insert a doubly list to the tail of a doubly linked list.
Definition: los_list.h:377
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
Definition: los_list.h:292
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
Definition: los_list.h:321
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
Definition: los_memory.c:1123
UINT8 * m_aucSysMem1
系统动态内存池地址的起始地址 @note_thinking 能否不要用 0,1来命名核心变量 ???
Definition: los_memory.c:108
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
Definition: los_memory.c:1369
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
Definition: los_memory.c:107
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID)
Delete a task.
Definition: los_task.c:968
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
LOS_TaskCreateOnly 创建任务,并使该任务进入suspend状态,不对该任务进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态
Definition: los_task.c:663
LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority)
Set the scheduling policy and priority for the task.
Definition: los_task.c:1493
VOID LOS_Schedule(VOID)
Trigger active task scheduling.
Definition: los_sched.c:469
VOID *(* TSK_ENTRY_FUNC)(UINTPTR param1, UINTPTR param2, UINTPTR param3, UINTPTR param4)
Define the type of a task entrance function.
Definition: los_task.h:480
LITE_OS_SEC_TEXT ProcIpcInfo * LiteIpcPoolReInit(const ProcIpcInfo *parent)
LiteIpcPoolReInit 重新初始化进程的IPC消息内存池
Definition: hm_liteipc.c:346
LITE_OS_SEC_TEXT UINT32 LiteIpcPoolDestroy(UINT32 processID)
销毁指定进程的IPC池
Definition: hm_liteipc.c:386
VOID LOS_ArchMmuContextSwitch(LosArchMmu *archMmu)
LOS_ArchMmuContextSwitch 切换MMU上下文
VOID OsUserCloneParentStack(VOID *childStack, UINTPTR parentTopOfStask, UINT32 parentStackSize)
把父任务上下文克隆给子任务
Definition: los_hw.c:107
VOID * OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag)
内核态任务运行栈初始化
Definition: los_hw.c:73
VOID OsUserTaskStackInit(TaskContext *context, UINTPTR taskEntry, UINTPTR stack)
用户态运行栈初始化,此时上下文还在内核区
Definition: los_hw.c:123
UINT32 OsGetRndOffset(INT32 randomDevFD)
Definition: los_load_elf.c:719
VOID LOS_MpSchedule(UINT32 target)
Definition: los_mp.c:76
LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize)
执行用户态任务, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小
Definition: los_process.c:1616
STATIC UINT32 OsCopyProcessResources(UINT32 flags, LosProcessCB *child, LosProcessCB *run)
拷贝进程资源
Definition: los_process.c:1969
STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, const CHAR *name)
Definition: los_process.c:737
STATIC UINT32 OsCopyParent(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
Definition: los_process.c:1861
LITE_OS_SEC_BSS LosProcessCB * g_processCBArray
进程池数组
Definition: los_process.c:80
STATIC ProcessGroup * OsFindProcessGroup(UINT32 gid)
Definition: los_process.c:203
STATIC VOID * OsUserInitStackAlloc(LosProcessCB *processCB, UINT32 *size)
Definition: los_process.c:1510
LITE_OS_SEC_BSS UINT32 g_kernelIdleProcess
0号进程 内核态idle进程,由Kprocess fork
Definition: los_process.c:85
LITE_OS_SEC_TEXT INT32 OsGetProcessPriority(INT32 which, INT32 pid)
接口封装 - 获取进程优先级 which:标识进程,进程组,用户
Definition: los_process.c:1055
LITE_OS_SEC_TEXT UINT32 OsGetIdleProcessID(VOID)
获取内核态空闲进程
Definition: los_process.c:2254
LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum)
LOS_GetUsedPIDList 获取使用中的进程列表
Definition: los_process.c:2115
LITE_OS_SEC_TEXT INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission)
Definition: los_process.c:262
LITE_OS_SEC_TEXT UINT32 OsGetUserInitProcessID(VOID)
获取用户态进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的
Definition: los_process.c:2244
VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB)
Definition: los_process.c:107
STATIC INLINE INT32 OsProcessSchedlerParamCheck(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
进程调度参数检查
Definition: los_process.c:939
STATIC UINT32 OsSetProcessGroupIDUnsafe(UINT32 pid, UINT32 gid, ProcessGroup **group)
Definition: los_process.c:1400
STATIC UINT32 OsChildSetProcessGroupAndSched(LosProcessCB *child, LosProcessCB *run)
Definition: los_process.c:1945
STATIC UINT32 OsCopyFile(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
拷贝进程文件描述符(proc_fd)信息
Definition: los_process.c:1909
STATIC VOID ThreadGroupActiveTaskKilled(LosTaskCB *taskCB)
按指定状态退出指定进程
Definition: los_process.c:2167
LITE_OS_SEC_TEXT INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy)
设置进程调度计划
Definition: los_process.c:983
LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID)
Definition: los_process.c:1746
LITE_OS_SEC_TEXT INT32 LOS_GetUserID(VOID)
Definition: los_process.c:826
LITE_OS_SEC_TEXT UINT32 OsGetKernelInitProcessID(VOID)
获取内核态根进程
Definition: los_process.c:2249
LITE_OS_SEC_TEXT INT32 LOS_Waitid(INT32 pid, USER siginfo_t *info, UINT32 options, VOID *rusage)
Definition: los_process.c:1350
LITE_OS_SEC_BSS UINT32 g_processMaxNum
进程最大数量,默认64个
Definition: los_process.c:86
LITE_OS_SEC_TEXT INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize)
Definition: los_process.c:2060
LITE_OS_SEC_TEXT VOID OsExecProcessVmSpaceRestore(LosVmSpace *oldSpace)
Definition: los_process.c:1531
LITE_OS_SEC_TEXT INT32 LOS_GetProcessScheduler(INT32 pid)
获得指定进程的调度策略
Definition: los_process.c:1030
LITE_OS_SEC_TEXT VOID OsSetSigHandler(UINTPTR addr)
设置进程的信号处理函数
Definition: los_process.c:2259
STATIC VOID OsExitProcessGroup(LosProcessCB *processCB, ProcessGroup **group)
Definition: los_process.c:184
STATIC UINT32 OsCopyTask(UINT32 flags, LosProcessCB *childProcessCB, const CHAR *name, UINTPTR entry, UINT32 size)
Definition: los_process.c:1803
LITE_OS_SEC_TEXT INT32 LOS_SetProcessPriority(INT32 pid, UINT16 prio)
接口封装 - 设置进程优先级
Definition: los_process.c:1050
LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status)
LOS_Exit 进程退出
Definition: los_process.c:2086
LITE_OS_SEC_TEXT UINTPTR OsGetSigHandler(VOID)
获取进程的信号处理函数
Definition: los_process.c:2264
STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB)
拷贝用户信息 直接用memcpy_s
Definition: los_process.c:1788
LITE_OS_SEC_TEXT INT32 LOS_GetGroupID(VOID)
Definition: los_process.c:842
STATIC VOID OsDealAliveChildProcess(LosProcessCB *processCB)
Definition: los_process.c:503
VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status)
Definition: los_process.c:550
LITE_OS_SEC_TEXT LosVmSpace * OsExecProcessVmSpaceReplace(LosVmSpace *newSpace, UINTPTR stackBase, INT32 randomDevFD)
Definition: los_process.c:1541
LITE_OS_SEC_BSS UINT32 g_kernelInitProcess
2号进程 内核态初始Kprocess进程,内核态下其他进程由它 fork
Definition: los_process.c:84
LITE_OS_SEC_TEXT INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, VOID *rusage)
Definition: los_process.c:1313
UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB, SchedParam *param)
Definition: los_process.c:116
STATIC VOID OsChildProcessResourcesFree(const LosProcessCB *processCB)
Definition: los_process.c:537
STATIC UINT32 OsWaitOptionsCheck(UINT32 options)
Definition: los_process.c:1245
LITE_OS_SEC_TEXT INT32 LOS_GetProcessGroupID(UINT32 pid)
Definition: los_process.c:1461
LITE_OS_SEC_BSS UINT32 g_userInitProcess
1号进程 用户态的初始init进程,用户态下其他进程由它 fork
Definition: los_process.c:83
STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 size)
拷贝进程
Definition: los_process.c:1999
STATIC BOOL OsProcessCapPermitCheck(const LosProcessCB *processCB, const SchedParam *param, UINT16 prio)
Definition: los_process.c:961
STATIC VOID OsWaitCheckAndWakeParentProcess(LosProcessCB *parentCB, const LosProcessCB *processCB)
Definition: los_process.c:368
STATIC BOOL OsWaitWakeSpecifiedProcess(LOS_DL_LIST *head, const LosProcessCB *processCB, LOS_DL_LIST **anyList)
Definition: los_process.c:336
STATIC UINT32 OsForkInitPCB(UINT32 flags, LosProcessCB *child, const CHAR *name, UINTPTR sp, UINT32 size)
Definition: los_process.c:1927
LITE_OS_SEC_TEXT struct fd_table_s * LOS_GetFdTable(UINT32 pid)
Definition: los_process.c:2143
LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID)
Definition: los_process.c:2200
LITE_OS_SEC_TEXT UINT32 LOS_GetSystemProcessMaximum(VOID)
获取系统支持的最大进程数目
Definition: los_process.c:2239
LITE_OS_SEC_TEXT INT32 OsSetProcessGroupID(UINT32 pid, UINT32 gid)
Definition: los_process.c:1439
STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info)
等待回收孩子进程 @note_thinking 这样写Porcess不太好吧
Definition: los_process.c:1181
STATIC User * OsCreateUser(UINT32 userID, UINT32 gid, UINT32 size)
Definition: los_process.c:788
STATIC UINT32 OsCopyMM(UINT32 flags, LosProcessCB *childProcessCB, LosProcessCB *runProcessCB)
Definition: los_process.c:1885
LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
Definition: los_process.c:625
UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name)
Definition: los_process.c:704
STATIC UINT32 OsWaitSetFlag(const LosProcessCB *processCB, INT32 pid, LosProcessCB **child)
设置等待子进程退出方式方法
Definition: los_process.c:1124
STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S *param)
用户进程开始初始化
Definition: los_process.c:1648
LITE_OS_SEC_TEXT INT32 LOS_GetCurrProcessGroupID(VOID)
获取当前进程的组ID
Definition: los_process.c:1485
STATIC UINT32 OsWaitidOptionsCheck(UINT32 options)
Definition: los_process.c:1326
STATIC LosProcessCB * OsFindGroupExitProcess(ProcessGroup *group, INT32 pid)
Definition: los_process.c:276
LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission)
Definition: los_process.c:242
LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name, LosVmSpace *oldSpace, UINTPTR oldFiles)
进程的回收再利用,被LOS_DoExecveFile调用
Definition: los_process.c:1568
LITE_OS_SEC_TEXT_INIT UINT32 OsSystemProcessCreate(VOID)
Definition: los_process.c:896
STATIC VOID OsWaitInsertWaitListInOrder(LosTaskCB *runTask, LosProcessCB *processCB)
Definition: los_process.c:1092
LITE_OS_SEC_BSS ProcessGroup * g_processGroup
全局进程组,负责管理所有进程组
Definition: los_process.c:87
STATIC UINT32 OsLoadUserInit(LosProcessCB *processCB)
Definition: los_process.c:1681
STATIC LosProcessCB * OsFindExitChildProcess(const LosProcessCB *processCB, INT32 childPid)
Definition: los_process.c:311
LITE_OS_SEC_TEXT INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, UINT16 prio)
设置指定进程的调度参数,包括优先级和调度策略
Definition: los_process.c:1025
STATIC UINT32 OsSetProcessGroupCheck(const LosProcessCB *processCB, UINT32 gid)
设置进程组检查
Definition: los_process.c:1365
STATIC UINT32 OsWaitChildProcessCheck(LosProcessCB *processCB, INT32 pid, LosProcessCB **childCB)
检查要等待的孩子进程
Definition: los_process.c:1236
LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
Definition: los_process.c:431
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_processRecycleList
需要回收的进程列表
Definition: los_process.c:82
STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage)
等待子进程结束并回收子进程,返回已经终止的子进程的进程ID号,并清除僵死进程。
Definition: los_process.c:1265
LITE_OS_SEC_TEXT STATIC VOID OsRecycleZombiesProcess(LosProcessCB *childCB, ProcessGroup **group)
Definition: los_process.c:482
LITE_OS_SEC_TEXT INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size)
OsClone 进程克隆
Definition: los_process.c:2049
STATIC LosProcessCB * OsGetFreePCB(VOID)
为用户态任务分配栈空间
Definition: los_process.c:1491
LITE_OS_SEC_TEXT INT32 OsSetCurrProcessGroupID(UINT32 gid)
Definition: los_process.c:1456
LITE_OS_SEC_TEXT INT32 LOS_GetProcessPriority(INT32 pid)
接口封装 - 获取指定进程优先级
Definition: los_process.c:1083
STATIC ProcessGroup * OsCreateProcessGroup(UINT32 pid)
创建进程组
Definition: los_process.c:160
STATIC UINT32 OsProcessInit(VOID)
Definition: los_process.c:586
STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *group, siginfo_t *info, INT32 permission)
Definition: los_process.c:221
STATIC UINT32 OsFindChildProcess(const LosProcessCB *processCB, INT32 childPid)
Definition: los_process.c:291
STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const CHAR *name)
Definition: los_process.c:859
VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID)
Definition: los_process.c:326
LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID)
获取当前进程的进程ID
Definition: los_process.c:2161
STATIC INLINE VOID OsInsertPCBToFreeList(LosProcessCB *processCB)
将进程插入到空闲链表中
Definition: los_process.c:97
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_freeProcess
空闲状态下的进程链表, .个人觉得应该取名为 g_freeProcessList @note_thinking
Definition: los_process.c:81
LITE_OS_SEC_TEXT BOOL LOS_CheckInGroups(UINT32 gid)
Definition: los_process.c:805
STATIC VOID OsDeInitPCB(LosProcessCB *processCB)
Definition: los_process.c:672
STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB)
进程不活跃函数定义:身上贴有不使用且不活跃标签的进程
STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)
STATIC INLINE User * OsCurrUserGet(VOID)
UINTPTR __user_init_load_addr
init 进程的加载地址 ,由链接器赋值
STATIC INLINE BOOL OsProcessExitCodeSignalIsSet(LosProcessCB *processCB)
进程退出码是否被设置过,默认是 0 ,如果 & 0x7FU 还是 0 ,说明没有被设置过.
UINTPTR __user_init_bss
查看 LITE_USER_SEC_BSS ,赋值由liteos.ld完成
STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB)
STATIC INLINE BOOL OsProcessIDUserCheckInvalid(UINT32 pid)
STATIC INLINE LosProcessCB * OsCurrProcessGet(VOID)
UINTPTR __user_init_end
init 进程的用户空间初始化结束地址
UINTPTR __user_init_entry
第一个用户态进程(init)的入口地址 查看 LITE_USER_SEC_ENTRY
STATIC INLINE VOID OsProcessExitCodeSet(LosProcessCB *processCB, UINT32 code)
设置进程退出号(8 ~ 15)
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
STATIC INLINE SchedRunqueue * OsSchedRunqueue(VOID)
STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB)
VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param)
Definition: los_sched.c:267
int OsDispatch(pid_t pid, siginfo_t *info, int permission)
信号分发,发送信号权限/进程组过滤.
Definition: los_signal.c:412
int OsKill(pid_t pid, int sig, int permission)
Definition: los_signal.c:450
INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo)
Definition: los_signal.c:490
LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
回收指定进程的软时钟
Definition: los_swtmr.c:391
LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree()
Definition: los_task.c:472
LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
创建一个空闲任务
Definition: los_task.c:300
UINT32 OsGetIdleTaskId(VOID)
获取IdletaskId,每个CPU核都对Task进行了内部管理,做到真正的并行处理
Definition: los_task.c:295
LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
挂起任务,任务进入等待链表,Join代表是支持通过一个任务去唤醒其他的任务
Definition: los_task.c:224
LITE_OS_SEC_TEXT INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName)
Definition: los_task.c:1337
LITE_OS_SEC_TEXT VOID OsWriteResourceEvent(UINT32 events)
Definition: los_task.c:1642
VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB)
Definition: los_task.c:198
LITE_OS_SEC_TEXT VOID OsInactiveTaskDelete(LosTaskCB *taskCB)
Definition: los_task.c:947
LITE_OS_SEC_TEXT VOID OsRunningTaskToExit(LosTaskCB *runTask, UINT32 status)
Definition: los_task.c:908
LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam)
创建一个用户态任务
Definition: los_task.c:1434
unsigned short UINT16
Definition: los_typedef.h:56
signed int INT32
Definition: los_typedef.h:60
int status_t
Definition: los_typedef.h:205
unsigned long VADDR_T
Definition: los_typedef.h:208
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
size_t BOOL
Definition: los_typedef.h:88
PADDR_T LOS_PaddrQuery(VOID *vaddr)
通过虚拟地址查询映射的物理地址
Definition: los_vm_map.c:550
STATUS_T LOS_VmSpaceFree(LosVmSpace *space)
LosVmSpace * OsCreateUserVmSpace(VOID)
创建用户进程空间
Definition: los_vm_map.c:281
STATIC INLINE VOID LOS_SetRegionTypeAnon(LosVmMapRegion *region)
设为匿名swap映射线性区
Definition: los_vm_map.h:270
STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace)
Definition: los_vm_map.c:318
LosVmSpace * LOS_GetKVmSpace(VOID)
内核空间只有g_kVmSpace一个,所有的内核进程都共用一个内核空间
Definition: los_vm_map.c:130
STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, size_t len, UINT32 flags)
LosVmMapRegion * LOS_RegionAlloc(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags, VM_OFFSET_T pgoff)
Definition: los_vm_map.c:581
STATUS_T OsVmSpaceRegionFree(LosVmSpace *space)
STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size)
VOID * LOS_PhysPagesAllocContiguous(size_t nPages)
分配连续的物理页
Definition: los_vm_phys.c:478
VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
释放指定页数地址连续的物理内存
Definition: los_vm_phys.c:494
内存管理单元(英语:memory management unit,缩写为MMU),有时称作分页内存管理单元(英语:paged memory management unit,缩写为PMMU)。
Definition: los_arch_mmu.h:86
VADDR_T * virtTtb
Definition: los_arch_mmu.h:90
PADDR_T physTtb
Definition: los_arch_mmu.h:91
struct LOS_DL_LIST * pstNext
Definition: los_list.h:84
进程IPC信息,见于进程结构体: LosProcessCB.ipcInfo
Definition: hm_liteipc.h:92
UINT16 processMode
struct rlimit * resourceLimit
每个进程在运行时系统不会无限制的允许单个进程不断的消耗资源,因此都会设置资源限制。
timer_t timerID
LOS_DL_LIST waitList
UINT32 processID
UINTPTR sigHandler
OsCpupBase * processCpup
LOS_DL_LIST siblingList
LOS_DL_LIST childrenList
LOS_DL_LIST subordinateGroupList
UINT32 exitCode
ProcIpcInfo * ipcInfo
UINT32 threadCount
struct files_struct * files
UINT32 threadGroupID
UINT16 processStatus
CHAR processName[OS_PCB_NAME_LEN]
TimerIdMap timerIdMap
User * user
进程的拥有者
UINT16 consoleID
LOS_DL_LIST threadSiblingList
LOS_DL_LIST pendList
volatile UINT32 threadNumber
UINT32 parentProcessID
LOS_DL_LIST exitChildList
ProcessGroup * group
mode_t umask
umask(user file-creatiopn mode mask)为用户文件创建掩码,是创建文件或文件夹时默认权限的基础。
LosVmSpace * vmSpace
LOS_DL_LIST exitProcessList
LOS_DL_LIST processList
LOS_DL_LIST groupList
VOID(* enqueue)(SchedRunqueue *rq, LosTaskCB *taskCB)
入队列
UINT32(* wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout)
任务等待
VOID(* wake)(LosTaskCB *taskCB)
任务唤醒
BOOL(* schedParamModify)(LosTaskCB *taskCB, const SchedParam *param)
修改调度参数
UINT32(* schedParamGet)(const LosTaskCB *taskCB, SchedParam *param)
获取调度参数
UINT16 basePrio
UINT16 policy
UINT16 priority
UINTPTR waitID
LOS_DL_LIST threadList
TSK_ENTRY_FUNC taskEntry
LOS_DL_LIST joinList
UINT32 taskID
UINT32 stackSize
UINT32 signal
sig_cb sig
信号控制块,用于异步通信,类似于 linux singal模块
UINTPTR userMapBase
用户空间的栈顶位置,内存来自用户空间,和topOfStack有本质的区别.
UINTPTR topOfStack
VOID * stackPointer
UINT16 currCpu
UINT32 userMapSize
UINTPTR archMmu
UINT32 processID
const SchedOps * ops
UINTPTR userArea
用户空间的堆区开始位置
UINT16 taskStatus
UINT16 waitFlag
UINT32 * bitMap
Definition: vid_type.h:40
UINT32 groupNumber
用户组数量
UINT32 groups[1]
UINT32 effUserID
UINT32 userID
用户ID [0,60000],0为root用户
UINT32 gid
用户组ID [0,60000],0为root用户组
UINT32 effGid
UINT32 userMapSize
用户空间的栈大小,栈底 = userMapBase + userMapSize
Definition: los_task.h:494
UINTPTR userArea
用户空间的堆区开始位置
Definition: los_task.h:491
UINTPTR userMapBase
用户空间的栈顶位置.
Definition: los_task.h:493
UINTPTR userSP
用户空间当前栈指针位置
Definition: los_task.h:492
VADDR_T base
Definition: los_vm_map.h:84
UINT32 regionFlags
Definition: los_vm_map.h:125
LosVmMapRange range
Definition: los_vm_map.h:123
虚拟空间,每个进程都有一个属于自己的虚拟内存地址空间
Definition: los_vm_map.h:146
VADDR_T mapBase
Definition: los_vm_map.h:155
VADDR_T heapBase
Definition: los_vm_map.h:152
VADDR_T heapNow
Definition: los_vm_map.h:153
LosArchMmu archMmu
Definition: los_vm_map.h:157
UINT32 mapSize
Definition: los_vm_map.h:156
进程fd表结构体
Definition: fd_table.h:84
struct fd_table_s * fdt
持有的文件表
Definition: fd_table.h:95
unsigned int sigIntLock
信号中断锁
Definition: los_signal.h:229
sigset_t sigprocmask
Signals that are blocked | 任务屏蔽了哪些信号
Definition: los_signal.h:223
UINT16 policy
Definition: los_task.h:506
UINT16 usTaskPrio
Definition: los_task.h:505
UINT32 uwStackSize
Definition: los_task.h:508
CHAR * pcName
Definition: los_task.h:509
UINT32 processID
进程ID
Definition: los_task.h:516
TSK_ENTRY_FUNC pfnTaskEntry
Definition: los_task.h:504
UserTaskParam userParam
任务用户态运行时任何参数
Definition: los_task.h:517
UINT32 uwResved
Definition: los_task.h:513
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void
if(tv==NULL)
Definition: time.c:430
size_t LOS_ArchCopyToUser(void *dst, const void *src, size_t len)
从内核空间拷贝到用户空间
Definition: user_copy.c:79
void VidMapDestroy(LosProcessCB *processCB)
销毁虚拟ID映射
Definition: vid.c:57
UINT32 VidMapListInit(LosProcessCB *processCB)
Definition: vid.c:36