From: Matthias Kruk Date: Tue, 29 Oct 2019 05:09:56 +0000 (+0900) Subject: Add process_exit() function X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=31db72afdf47322b3b813aacfcf69f88f69fa5dc;p=corax Add process_exit() function --- diff --git a/kernel/core/process.c b/kernel/core/process.c index e4fb472..8f70ec9 100644 --- a/kernel/core/process.c +++ b/kernel/core/process.c @@ -7,6 +7,13 @@ #include #include #include "fd.h" +#include "sched.h" + +enum procstate { + PROC_STATE_INIT = 0, + PROC_STATE_READY, + PROC_STATE_EXIT +}; struct process { struct pagedir *p_pgdir; @@ -19,6 +26,9 @@ struct process { pid_t sender; } p_inbox[32]; + enum procstate p_state; + int p_status; + struct fd p_fds[16]; }; @@ -30,10 +40,6 @@ struct proc_list { static pid_t _next_pid = 100; static struct proc_list *_procs; -extern int sched_enqueue(task_t*); -extern void sched_wait(pid_t); -extern int sched_signal(pid_t); - static inline int NQ(process_t *p) { struct proc_list *pl; @@ -148,6 +154,8 @@ int process_create(process_t **dst, pid_t pid, u32_t ppl, void *entry) goto cleanup; } + proc->p_state = PROC_STATE_READY; + if(sched_enqueue(proc->p_tasks) != 0) { PANIC("sched_enqueue() failed for a new task\n"); } @@ -400,3 +408,68 @@ pid_t process_get_id(process_t *proc) { return(proc->p_id); } + +int process_exit(process_t *proc, int status) +{ + int ret_val; + + ret_val = -EINVAL; + + if(proc) { + if(proc->p_state == PROC_STATE_EXIT) { + ret_val = -EALREADY; + } else { + task_t *cur; + task_t *t; + int reschedule; + + reschedule = 0; + + cur = task_get_current(); + + /* FIXME: Properly deal with the process's remaining tasks */ + + for(t = proc->p_tasks; t; t = NULL /* t = t->next */) { + t->t_state = TASK_STATE_EXIT; + + /* + * If sched_dequeue() fails, there is a good chance that the + * task pointed to by `t' is currently running (since running + * tasks are neither on the ready queue nor on the wait queue), + * so we have to stop the task. + */ + if(sched_dequeue(t) < 0) { + /* + * However, don't terminate the current task, since we still + * need it - we're not done here, after all. + */ + + if(t == cur) { + reschedule = 1; + } else { + /* FIXME: Stop the task */ + } + } + } + + ret_val = 0; + proc->p_status = status; + + /* + * If this function is called within the context of the + * process, we need to reschedule to make sure we don't + * return to the caller. + */ + if(reschedule) { + /* + * sched_tick() will not put the running task back on the ready + * queue if it is in state TASK_STATE_EXIT, so this is the proper + * way to stop the current task. + */ + sched_tick(); + } + } + } + + return(ret_val); +} diff --git a/kernel/include/process.h b/kernel/include/process.h index ca42c6e..4c3baf3 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -46,5 +46,6 @@ int process_signal(pid_t); void* process_get_tasks(process_t*); pid_t process_get_id(process_t*); +int process_exit(process_t*, int); #endif /* __PROCESS_H */