#define OFFSET_CR3 4
#define OFFSET_KSTACK 8
#define OFFSET_PRIVL 12
+#define OFFSET_STATE 16
.extern _cpu
/* 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:
#include <corax/types.h>
-#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;
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);