diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/proc/proc.c | 106 |
1 files changed, 100 insertions, 6 deletions
diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index f8453bd..9837a8a 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -174,8 +174,52 @@ proc_t *proc_lookup(pid_t pid) */ proc_t *proc_create(const char *name) { - NOT_YET_IMPLEMENTED("PROCS: proc_create"); - return NULL; + // NOT_YET_IMPLEMENTED("PROCS: proc_create"); + int proc_pid = _proc_getid(); + if (proc_pid == -1) + { + return NULL; + } + + proc_t *proc = (proc_t *)slab_obj_alloc(proc_allocator); + if (proc == NULL) + { + return NULL; + } + + pml4_t *pml4 = pt_create(); + if (pml4 == NULL) + { + slab_obj_free(proc_allocator, proc); + return NULL; + } + + // if successful building memory, fill the struct + proc->p_pid = proc_pid; + strncpy(proc->p_name, name, PROC_NAME_LEN); + proc->p_pml4 = pml4; + proc->p_state = PROC_RUNNING; // TODO: check if this is correct + proc->p_status = 0; + list_init(&proc->p_threads); + list_init(&proc->p_children); + list_link_init(&proc->p_child_link); + list_link_init(&proc->p_list_link); + sched_queue_init(&proc->p_wait); + + + if (proc_pid == PID_INIT) + { + // if it's init proc, set to global variable + proc_initproc = proc; + } + else + { + // FIXME: ask in hours + // if it's not init proc, set parent proc to the init proc + proc->p_pproc = proc_initproc; + } + + return proc; } /* @@ -197,7 +241,38 @@ proc_t *proc_create(const char *name) */ void proc_cleanup(long status) { - NOT_YET_IMPLEMENTED("PROCS: proc_cleanup"); + // NOT_YET_IMPLEMENTED("PROCS: proc_cleanup"); + + // free resources of this proc (save slab_obj_free for proc_destroy) + pt_destroy(curproc->p_pml4); + + + // NOT_YET_IMPLEMENTED("PROCS: proc_cleanup"); + if (curproc->p_pid == PID_INIT) + { + // if it's init proc, shutdown weenix + initproc_finish(status); + } + else + { + // if it's not init proc, reparent child processes to parent proc + if (curproc->p_pproc == NULL) + { + panic("parent process not found in proc_pleanup"); + } + + list_link_t *link; + list_iterate(&curproc->p_children, child, proc_t, p_child_link) + { + // remove each child from current process and insert to init process + list_remove(&child->p_child_link); + list_insert_tail(&curproc->p_pproc->p_children, &child->p_child_link); + } + + // update state and status + curproc->p_state = PROC_DEAD; + curproc->p_status = status; + } } /* @@ -216,7 +291,13 @@ void proc_cleanup(long status) */ void proc_thread_exiting(void *retval) { - NOT_YET_IMPLEMENTED("PROCS: proc_thread_exiting"); + // NOT_YET_IMPLEMENTED("PROCS: proc_thread_exiting"); + + proc_cleanup((long)retval); + curthr->kt_state = KT_EXITED; + + sched_broadcast_on(&curproc->p_wait); + sched_switch(&curproc->p_wait); } /* @@ -227,7 +308,14 @@ void proc_thread_exiting(void *retval) */ void proc_kill(proc_t *proc, long status) { - NOT_YET_IMPLEMENTED("PROCS: proc_kill"); + // NOT_YET_IMPLEMENTED("PROCS: proc_kill"); + + KASSERT(proc != curproc && "proc_kill called on curproc"); + + list_iterate(&proc->p_threads, thr, kthread_t, kt_plink) + { + kthread_cancel(thr, status); + } } /* @@ -241,7 +329,13 @@ void proc_kill(proc_t *proc, long status) */ void proc_kill_all() { - NOT_YET_IMPLEMENTED("PROCS: proc_kill_all"); + // NOT_YET_IMPLEMENTED("PROCS: proc_kill_all"); + + // TODO: consider children on children + list_iterate(&proc_initproc->p_children, thr, kthread_t, kt_plink) + { + + } } /* |