From: Matthias Kruk Date: Fri, 27 Sep 2019 07:51:46 +0000 (+0900) Subject: Modify task_switch function so it can be used to switch to new tasks which have not... X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=ff1e021c7aed7c38e03beda7b416cdc0e8a73015;p=corax Modify task_switch function so it can be used to switch to new tasks which have not been executed before, but also to return to interrupted tasks --- diff --git a/kernel/arch/task.S b/kernel/arch/task.S index a041b72..43f3b12 100644 --- a/kernel/arch/task.S +++ b/kernel/arch/task.S @@ -28,6 +28,7 @@ #define OFFSET_CR3 4 #define OFFSET_KSTACK 8 #define OFFSET_PRIVL 12 +#define OFFSET_STATE 16 .extern _cpu @@ -219,7 +220,31 @@ task_switch: /* load new ESP */ 3: movl OFFSET_ESP0(%edi), %esp - /* pretend that we're returning from an interrupt */ + /* + * If this is a new task, we have to use _int_restore to return, + * but if this task has been executed before, we can simply ret. + * New tasks have state TASK_STATE_NEW, which is zero. + */ + + movl OFFSET_STATE(%edi), %eax + test %eax, %eax + jz 4f + xorl %eax, %eax + + /* + * If the context has previously executed, it was interrupted in this + * very same function, so by switching back to its stack and page directory + * we have done enough to restore it's context. Everything else will happen + * when the task returns "naturally" to user-space + */ + ret + +4: movl $1, OFFSET_STATE(%edi) + /* + * In the previous line, the task state is set to TASK_STATE_RUNNING. + * This is the only place where a transition from NEW to any other state + * should occur (excluding BROKEN) + */ jmp _int_restore task_get_current: diff --git a/kernel/include/arch.h b/kernel/include/arch.h index 7499bae..fec57bb 100644 --- a/kernel/include/arch.h +++ b/kernel/include/arch.h @@ -21,10 +21,11 @@ #include -#define TASK_STATE_BROKEN 0 +#define TASK_STATE_NEW 0 #define TASK_STATE_RUNNING 1 #define TASK_STATE_READY 2 #define TASK_STATE_WAITING 3 +#define TASK_STATE_BROKEN 4 typedef struct task task_t; @@ -33,11 +34,10 @@ struct task { u32_t t_pgdir; void *t_kstack; u32_t t_privl; + u32_t t_state; u32_t t_tslice; u32_t t_rslice; - - u32_t t_state; } __attribute__((packed)); int cpu_get_id(void);