bugfix: 修复进程pcb被回收时,未将其从链表中删除的问题 (#87)

* bugfix: 修复进程pcb被回收时,未将其从链表中删除的问题
new: pcb相关api文档

* 将文档加入目录
This commit is contained in:
login 2022-11-18 17:59:33 +08:00 committed by GitHub
parent 0bfe94f46b
commit 3d729e2069
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 19 deletions

View File

@ -4,4 +4,5 @@
.. toctree::
:maxdepth: 1
kthread
kthread
pcb

View 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

View File

@ -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;

View File

@ -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获取进程的pcbpcb时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;
}

View File

@ -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获取进程的pcbpcb时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

View File

@ -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;