diff --git a/2020301918-李懋良-试点班第6个报告.docx b/2020301918-李懋良-试点班第6个报告.docx new file mode 100644 index 0000000..936cf21 Binary files /dev/null and b/2020301918-李懋良-试点班第6个报告.docx differ diff --git a/kern/fork.c b/kern/fork.c index 479e3bd..f340b86 100644 --- a/kern/fork.c +++ b/kern/fork.c @@ -127,6 +127,7 @@ kern_fork(PROCESS_0 *p_fa) xchg(&p_fa->lock, 0); return -EAGAIN; } + assert(proc_child->pcb.lock == 0); while (xchg(&proc_child->pcb.lock, 1) == 1) schedule(); PROCESS_0 *p_child = &proc_child->pcb; @@ -150,7 +151,7 @@ kern_fork(PROCESS_0 *p_fa) // p_fa shares the same base addr as its padding // anyways, copy the whole proc_table item(8K?) DISABLE_INT(); // make sure this process is never interrupted - memset(proc_child, 0, sizeof(PROCESS)); // clear child's kernel stack + // memset(proc_child, 0, sizeof(PROCESS)); // clear child's kernel stack //? seem to be useless // the commented fields below will be set later // p_child->cr3 p_child->exit_code = p_fa->exit_code; @@ -163,7 +164,7 @@ kern_fork(PROCESS_0 *p_fa) p_child->statu = INITING; //! important!!! if you copied this from parent, haha, waste one hour p_child->ticks = p_fa->ticks; p_child->user_regs = p_fa->user_regs; - ENABLE_INT(); + ENABLE_INT(); // TODO: may be a useless atomic block, try to remove and test again //? 2. ALLOC PAGES AND COPY PHYSICAL MEMORY copy_parent_pages(p_child, p_fa); // panic("Unimplement! soul torture1"); diff --git a/kern/wait.c b/kern/wait.c index e958e5d..1c66c21 100644 --- a/kern/wait.c +++ b/kern/wait.c @@ -21,18 +21,6 @@ on failure, -1 is returned. ssize_t kern_wait(int *wstatus) { - // 相比于fork来说,wait的实现简单很多 - // 语义实现比较清晰,没有fork那么多难点要处理,所以这里并不会给大家太多引导 - // 需要大家自己思考wait怎么实现。 - - // 在实现之前你必须得读一遍文档`man 2 wait` - // 了解到wait大概要做什么 - // panic("Unimplement! Read The F**king Manual"); - - // 当然读文档是一方面,最重要的还是代码实现 - // wait系统调用与exit系统调用关系密切,所以在实现wait之前需要先读一遍exit为好 - // 可能读完exit的代码你可能知道wait该具体做什么了 - // panic("Unimplement! Read The F**king Source Code"); again: while (xchg(&p_proc_ready->pcb.lock, 1) == 1) schedule(); @@ -44,8 +32,6 @@ again: return -ECHILD; } assert(p_son->pre == NULL); // make sure it is the head of the list - while (p_son != NULL) { - if (p_son->p_son->statu == ZOMBIE) { /* struct s_proc { user_regs; // let it be @@ -61,6 +47,8 @@ ticks; // let it be fork_tree; // already cleared }; */ + while (p_son != NULL) { + if (p_son->p_son->statu == ZOMBIE) { while (xchg(&p_son->p_son->lock, 1) == 1) schedule(); // just use this value, which is '(status & 0xFF) << 8' in exit.c::do_exit @@ -68,8 +56,6 @@ fork_tree; // already cleared *wstatus = p_son->p_son->exit_code; // recycle_pages in pmap.c recycle_pages(p_son->p_son->page_list); - // free it in proc table, 'cause in fork I judge free by statu - p_son->p_son->statu = IDLE; // remove p_son from p_fa's son list if (p_son->pre != NULL) { p_son->pre->nxt = p_son->nxt; @@ -82,14 +68,16 @@ fork_tree; // already cleared } // keep p_son's pid for retval, 'cause the pointer will get freed before return child_pid = p_son->p_son->pid; - xchg(&p_son->p_son->lock, 0); kfree(p_son); + // free it in proc table, 'cause in fork I judge free by statu + xchg(&proc_table[child_pid].pcb.lock, 0); + proc_table[child_pid].pcb.statu = IDLE; // ! set status be the last state, or die goto done; } p_son = p_son->nxt; } - p_fa->statu = SLEEP; xchg(&p_fa->lock, 0); + p_fa->statu = SLEEP; //! sleep after release lock, or it will deadlock schedule(); goto again; // 接下来就是你自己的实现了,我们在设计的时候这段代码不会有太大问题