#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;
pid_t sender;
} p_inbox[32];
+ enum procstate p_state;
+ int p_status;
+
struct fd p_fds[16];
};
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;
goto cleanup;
}
+ proc->p_state = PROC_STATE_READY;
+
if(sched_enqueue(proc->p_tasks) != 0) {
PANIC("sched_enqueue() failed for a new task\n");
}
{
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);
+}