]> git.corax.cc Git - corax/commitdiff
Add process_exit() function
authorMatthias Kruk <m@m10k.eu>
Tue, 29 Oct 2019 05:09:56 +0000 (14:09 +0900)
committerMatthias Kruk <m@m10k.eu>
Tue, 29 Oct 2019 05:09:56 +0000 (14:09 +0900)
kernel/core/process.c
kernel/include/process.h

index e4fb4721b5079fbc94b2554ee03164168f9421ea..8f70ec9f93cbff2cf44eea8bab22699088b10786 100644 (file)
@@ -7,6 +7,13 @@
 #include <debug.h>
 #include <process.h>
 #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);
+}
index ca42c6e6851fc5f4787dd4e20174402ff62ca7fc..4c3baf303eabec553a2e9ed4ede40e5e48f2d028 100644 (file)
@@ -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 */