diff options
Diffstat (limited to 'kernel/proc')
-rw-r--r-- | kernel/proc/fork.c | 75 | ||||
-rw-r--r-- | kernel/proc/kthread.c | 40 | ||||
-rw-r--r-- | kernel/proc/proc.c | 33 |
3 files changed, 124 insertions, 24 deletions
diff --git a/kernel/proc/fork.c b/kernel/proc/fork.c index 28f9f9c..cbf5e30 100644 --- a/kernel/proc/fork.c +++ b/kernel/proc/fork.c @@ -57,6 +57,77 @@ static uintptr_t fork_setup_stack(const regs_t *regs, void *kstack) */ long do_fork(struct regs *regs) { - NOT_YET_IMPLEMENTED("VM: do_fork"); - return -1; + // NOT_YET_IMPLEMENTED("VM: do_fork"); + + // Create a new process + proc_t *child_proc = proc_create("child from fork"); + if (child_proc == NULL) + { + return -ENOMEM; + } + // Create a new thread + kthread_t *child_thread = kthread_clone(curthr); + if (child_thread == NULL) + { + proc_destroy(child_proc); + return -ENOMEM; + } + + // Set the child process's parent to the current process + // child_thread->kt_proc = child_proc; + // list_insert_head(&child_proc->p_threads, &child_thread->kt_plink); + + // Get the new vmmap_t for the child process + // vmmap_t *child_vmmap = vmmap_clone(curproc->p_vmmap); + // if (child_vmmap == NULL) + // { + // kthread_destroy(child_thread); + // proc_destroy(child_proc); + // return -ENOMEM; + // } + + // Set the new vmmap_t for the child process + // child_proc->p_vmmap = child_vmmap; + // // Set the vmmap to the child process + // child_thread->kt_proc = child_proc; + + // Set the working directory of the child process to the current process + // vref(curproc->p_cwd); + // child_proc->p_cwd = curproc->p_cwd; + + // Copy over each file descriptor from the parent to the child + // for (int i = 0; i < NFILES; i++) + // { + // if (curproc->p_files[i] != NULL) + // { + // fref(curproc->p_files[i]); + // child_proc->p_files[i] = curproc->p_files[i]; + // } + // } + + // Fix the values of the registers and the rest of the kthread's ctx + regs->r_rax = 0; // Set the return value to 0 for the child + child_thread->kt_ctx.c_rsp = fork_setup_stack(regs, child_thread->kt_kstack); // Set the stack pointer for the child + child_thread->kt_ctx.c_rip = (uintptr_t) userland_entry; // Set the instruction pointer to userland_entry + // child_thread->kt_ctx.c_rbp = curthr->kt_ctx.c_rbp; // Set the current thread's base pointer to the child's base pointer + child_thread->kt_ctx.c_pml4 = curproc->p_pml4; // Set the current thread's page table to the current proc's + child_thread->kt_proc = child_proc; // Set the child process to the child thread + + // Update the list + list_insert_tail(&child_proc->p_threads, &child_thread->kt_plink); + + + // Update the brks for the child process + // child_proc->p_brk = curproc->p_brk; + // child_proc->p_start_brk = curproc->p_start_brk; + + // Unmap the parent's page table and flush the TLB + pt_unmap_range(curproc->p_pml4, USER_MEM_LOW, USER_MEM_HIGH); + tlb_flush_all(); + + // Prepare the child process to be run on the CPU + sched_make_runnable(child_thread); + + // Return the child's process id to the parent + return child_proc->p_pid; } diff --git a/kernel/proc/kthread.c b/kernel/proc/kthread.c index d066dac..b614ac3 100644 --- a/kernel/proc/kthread.c +++ b/kernel/proc/kthread.c @@ -121,8 +121,42 @@ kthread_t *kthread_create(proc_t *proc, kthread_func_t func, long arg1, */ kthread_t *kthread_clone(kthread_t *thr) { - NOT_YET_IMPLEMENTED("VM: kthread_clone"); - return NULL; + // NOT_YET_IMPLEMENTED("VM: kthread_clone"); + + kthread_t *new_thread = slab_obj_alloc(kthread_allocator); + if (new_thread == NULL) + { + return NULL; + } + new_thread->kt_state = KT_NO_STATE; + + // copy the stack + new_thread->kt_ctx.c_kstack = alloc_stack(); + if (new_thread->kt_kstack == NULL) + { + slab_obj_free(kthread_allocator, new_thread); + return NULL; + } + new_thread->kt_kstack = new_thread->kt_ctx.c_kstack; + new_thread->kt_ctx.c_kstacksz = DEFAULT_STACK_SIZE; + + // context_setup(&new_thread->kt_ctx, NULL, 0, NULL, new_thread->kt_kstack, + // DEFAULT_STACK_SIZE, thr->kt_proc->p_pml4); (done in fork, I hope) + + // set the retval, errno, cancelled + new_thread->kt_retval = thr->kt_retval; + new_thread->kt_errno = thr->kt_errno; + new_thread->kt_cancelled = thr->kt_cancelled; + new_thread->kt_preemption_count = 0; + new_thread->kt_recent_core = ~0UL; + new_thread->kt_wchan = NULL; + // freshly initialize the rest of the fields + list_init(&new_thread->kt_mutexes); + list_link_init(&new_thread->kt_plink); + list_link_init(&new_thread->kt_qlink); + // list_insert_tail(&thr->kt_proc->p_threads, &new_thread->kt_plink); (done in fork) + + return new_thread; } /* @@ -162,7 +196,7 @@ void kthread_cancel(kthread_t *thr, void *retval) // NOT_YET_IMPLEMENTED("PROCS: kthread_cancel"); KASSERT(thr != curthr); - // FIXME: ask about the use of check_curthr_cancelled() in syscall_handler() + // ask about the use of check_curthr_cancelled() in syscall_handler() int status = (int) retval; dbg(DBG_THR, "Cancelling thread with proc name=%s, id=%d, status=%d\n", thr->kt_proc->p_name, thr->kt_proc->p_pid, status); diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index eab6556..f7878a2 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -265,19 +265,21 @@ void proc_cleanup(long status) // NOT_YET_IMPLEMENTED("PROCS: proc_cleanup"); dbg(DBG_PROC, "proc_cleanup called on proc with pid=%d with exit status=%d\n", curproc->p_pid, status); -#ifdef __VFS__ + curproc->p_state = PROC_DEAD; + + // update state and status + // if (curthr->kt_cancelled) { + // curproc->p_status = curthr->kt_retval; + // } else { + // } + curproc->p_status = status; + for (int fd = 0; fd < NFILES; fd++) { - if (curproc->p_files[fd]) - { - fput(curproc->p_files + fd); - } + do_close(fd); } - if (curproc->p_cwd) - { - vput(&curproc->p_cwd); - } -#endif + vput(&curproc->p_cwd); + vmmap_destroy(&curproc->p_vmmap); if (curproc->p_pid == PID_INIT) { @@ -297,16 +299,8 @@ void proc_cleanup(long status) // remove & insert to init process child->p_pproc = proc_initproc; list_remove(&child->p_child_link); - list_insert_tail(&curproc->p_pproc->p_children, &child->p_child_link); + list_insert_head(&proc_initproc->p_children, &child->p_child_link); } - - // update state and status - curproc->p_state = PROC_DEAD; - // if (curthr->kt_cancelled) { - // curproc->p_status = curthr->kt_retval; - // } else { - curproc->p_status = status; - // } } /* @@ -371,6 +365,7 @@ void proc_kill_all() p->p_pproc->p_pid != PID_IDLE ) { + // proc_kill(p, curproc->p_status); proc_kill(p, -1); } } |