mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
bugfix: 修复进程pcb被回收时,未将其从链表中删除的问题 (#87)
* bugfix: 修复进程pcb被回收时,未将其从链表中删除的问题 new: pcb相关api文档 * 将文档加入目录
This commit is contained in:
parent
0bfe94f46b
commit
3d729e2069
@ -4,4 +4,5 @@
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
kthread
|
||||
kthread
|
||||
pcb
|
27
docs/kernel/process_management/pcb.md
Normal file
27
docs/kernel/process_management/pcb.md
Normal file
@ -0,0 +1,27 @@
|
||||
# PCB 进程控制块
|
||||
|
||||
PCB的全称为process control block, 它是每个进程/线程的核心控制结构。定义于`kernel/src/process/proc-types.h`中。
|
||||
|
||||
## PCB详解
|
||||
|
||||
Todo:
|
||||
|
||||
## 与PCB的管理相关的API
|
||||
|
||||
### 根据pid寻找pcb
|
||||
|
||||
**process_find_pcb_by_pid**
|
||||
|
||||
该API提供了根据pid寻找pcb的功能,定义在`kernel/src/process/process.h`中。
|
||||
|
||||
当找到目标的pcb时,返回对应的pcb,否则返回NULL。
|
||||
|
||||
#### 参数
|
||||
|
||||
**pid**
|
||||
进程id
|
||||
|
||||
#### 返回值
|
||||
|
||||
**struct process_control_block**
|
||||
目标pcb
|
@ -84,7 +84,7 @@ struct process_control_block
|
||||
// 进程切换时保存的状态信息
|
||||
struct thread_struct *thread;
|
||||
|
||||
// 连接各个pcb的双向链表
|
||||
// pcb加入调度队列时,所使用的链表节点
|
||||
struct List list;
|
||||
|
||||
//todo:给pcb中加一个spinlock_t成员
|
||||
@ -105,7 +105,7 @@ struct process_control_block
|
||||
struct vfs_file_t *fds[PROC_MAX_FD_NUM];
|
||||
|
||||
// 链表中的下一个pcb
|
||||
struct process_control_block *next_pcb;
|
||||
struct process_control_block *prev_pcb, *next_pcb;
|
||||
// 父进程的pcb
|
||||
struct process_control_block *parent_pcb;
|
||||
|
||||
|
@ -676,7 +676,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
||||
struct process_control_block *tsk = NULL;
|
||||
|
||||
// 为新的进程分配栈空间,并将pcb放置在底部
|
||||
tsk = (struct process_control_block *)kmalloc(STACK_SIZE, 0);
|
||||
tsk = (struct process_control_block *)kzalloc(STACK_SIZE, 0);
|
||||
barrier();
|
||||
|
||||
if (tsk == NULL)
|
||||
@ -717,6 +717,9 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
||||
tsk->pid = process_global_pid++;
|
||||
barrier();
|
||||
// 加入到进程链表中
|
||||
// todo: 对pcb_list_lock加锁
|
||||
tsk->prev_pcb = &initial_proc_union.pcb;
|
||||
barrier();
|
||||
tsk->next_pcb = initial_proc_union.pcb.next_pcb;
|
||||
barrier();
|
||||
initial_proc_union.pcb.next_pcb = tsk;
|
||||
@ -779,13 +782,14 @@ copy_flags_failed:;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据pid获取进程的pcb
|
||||
* @brief 根据pid获取进程的pcb。存在对应的pcb时,返回对应的pcb的指针,否则返回NULL
|
||||
*
|
||||
* @param pid
|
||||
* @return struct process_control_block*
|
||||
*/
|
||||
struct process_control_block *process_get_pcb(long pid)
|
||||
struct process_control_block *process_find_pcb_by_pid(pid_t pid)
|
||||
{
|
||||
// todo: 当进程管理模块拥有pcblist_lock之后,对其加锁
|
||||
struct process_control_block *pcb = initial_proc_union.pcb.next_pcb;
|
||||
|
||||
// 使用蛮力法搜索指定pid的pcb
|
||||
@ -797,6 +801,7 @@ struct process_control_block *process_get_pcb(long pid)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将进程加入到调度器的就绪队列中
|
||||
*
|
||||
@ -1174,8 +1179,15 @@ int process_release_pcb(struct process_control_block *pcb)
|
||||
{
|
||||
// 释放子进程的页表
|
||||
process_exit_mm(pcb);
|
||||
if ((pcb->flags & PF_KTHREAD)) // 释放内核线程的worker private结构体
|
||||
if ((pcb->flags & PF_KTHREAD)) // 释放内核线程的worker private结构体
|
||||
free_kthread_struct(pcb);
|
||||
|
||||
// 将pcb从pcb链表中移除
|
||||
// todo: 对相关的pcb加锁
|
||||
pcb->prev_pcb->next_pcb = pcb->next_pcb;
|
||||
pcb->next_pcb->prev_pcb = pcb->prev_pcb;
|
||||
|
||||
// 释放当前pcb
|
||||
kfree(pcb);
|
||||
return 0;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
{ \
|
||||
.state = PROC_UNINTERRUPTIBLE, .flags = PF_KTHREAD, .preempt_count = 0, .signal = 0, .cpu_id = 0, \
|
||||
.mm = &initial_mm, .thread = &initial_thread, .addr_limit = 0xffffffffffffffff, .pid = 0, .priority = 2, \
|
||||
.virtual_runtime = 0, .fds = {0}, .next_pcb = &proc, .parent_pcb = &proc, .exit_code = 0, \
|
||||
.virtual_runtime = 0, .fds = {0}, .next_pcb = &proc, .prev_pcb = &proc, .parent_pcb = &proc, .exit_code = 0, \
|
||||
.wait_child_proc_exit = 0, .worker_private = NULL, .policy = SCHED_NORMAL \
|
||||
}
|
||||
|
||||
@ -95,12 +95,12 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
||||
unsigned long stack_size);
|
||||
|
||||
/**
|
||||
* @brief 根据pid获取进程的pcb
|
||||
* @brief 根据pid获取进程的pcb。存在对应的pcb时,返回对应的pcb的指针,否则返回NULL
|
||||
*
|
||||
* @param pid
|
||||
* @return struct process_control_block*
|
||||
*/
|
||||
struct process_control_block *process_get_pcb(long pid);
|
||||
struct process_control_block *process_find_pcb_by_pid(pid_t pid);
|
||||
|
||||
/**
|
||||
* @brief 将进程加入到调度器的就绪队列中
|
||||
|
@ -518,14 +518,8 @@ uint64_t sys_wait4(struct pt_regs *regs)
|
||||
// 查找pid为指定值的进程
|
||||
// ps: 这里判断子进程的方法没有按照posix 2008来写。
|
||||
// todo: 根据进程树判断是否为当前进程的子进程
|
||||
for (proc = &initial_proc_union.pcb; proc->next_pcb != &initial_proc_union.pcb; proc = proc->next_pcb)
|
||||
{
|
||||
if (proc->next_pcb->pid == pid)
|
||||
{
|
||||
child_proc = proc->next_pcb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
child_proc = process_find_pcb_by_pid(pid);
|
||||
|
||||
if (child_proc == NULL)
|
||||
return -ECHILD;
|
||||
@ -542,7 +536,6 @@ uint64_t sys_wait4(struct pt_regs *regs)
|
||||
if (likely(status != NULL))
|
||||
*status = child_proc->exit_code;
|
||||
// copy_to_user(status, (void*)child_proc->exit_code, sizeof(int));
|
||||
proc->next_pcb = child_proc->next_pcb;
|
||||
|
||||
process_release_pcb(child_proc);
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user