summaryrefslogtreecommitdiff
path: root/kernel/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c56
1 files changed, 23 insertions, 33 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 675867c..efbb80a 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -30,26 +30,8 @@
extern char _usrbin_start;
extern char _usrbin_size;
-struct task_state {
- uint16_t ds;
- uint32_t edi;
- uint32_t esi;
- uint32_t ebp;
- uint32_t esp_garbage;
- uint32_t ebx;
- uint32_t edx;
- uint32_t ecx;
- uint32_t eax;
- uint32_t eip;
- uint32_t cs;
- uint32_t eflags;
- uint32_t esp;
- uint32_t ss;
-} __attribute__((packed));
-
struct task_struct *ctask;
uint32_t ctaskn;
-struct task_state *cstate;
static struct task_struct tasks[NRTASKS];
@@ -79,7 +61,7 @@ struct task_struct *create_proc(void *bin, size_t len) {
if(!tasks[i].pid) {
task = &tasks[i];
/* update the GDT */
- set_tss(i, &tasks[i].state);
+ set_tss(i, &tasks[i].tss);
break;
}
}
@@ -169,21 +151,22 @@ struct task_struct *create_proc(void *bin, size_t len) {
*/
memset(task, 0, sizeof(struct task_struct));
task->pid = nextpid;
- task->state.cr3 = (uint32_t) pdir;
- task->state.cs = 0x1B;
- task->state.ds = 0x23;
- task->state.es = 0x23;
- task->state.fs = 0x23;
- task->state.gs = 0x23;
- task->state.ss = 0x23;
- task->state.eip = (uint32_t) USRSTART;
- task->state.esp = 0xFFFFDFFF;
- task->state.esp0 = 0xFFFFFFFF;
- task->state.ss0 = 0x10;
+ task->state = TSTATE_RUNNING;
+ task->tss.cr3 = (uint32_t) pdir;
+ task->tss.cs = 0x1B;
+ task->tss.ds = 0x23;
+ task->tss.es = 0x23;
+ task->tss.fs = 0x23;
+ task->tss.gs = 0x23;
+ task->tss.ss = 0x23;
+ task->tss.eip = (uint32_t) USRSTART;
+ task->tss.esp = 0xFFFFDFFF;
+ task->tss.esp0 = 0xFFFFFFFF;
+ task->tss.ss0 = 0x10;
__asm__ (
"pushf\n" \
"pop %%eax" \
- : "=a" (task->state.eflags) \
+ : "=a" (task->tss.eflags) \
::);
return task;
@@ -199,7 +182,6 @@ void sched_init(void) {
nextpid = 1;
ctask = NULL;
- cstate = NULL;
create_proc(&_usrbin_start, (size_t) &_usrbin_size);
create_proc(&_usrbin_start, (size_t) &_usrbin_size);
@@ -218,7 +200,7 @@ void reschedule(void) {
n = ctaskn;
for(i = 0; i < NRTASKS; i++) {
n = (n + 1) % NRTASKS;
- if(tasks[n].pid)
+ if(tasks[n].pid && tasks[n].state == TSTATE_RUNNING)
break;
}
switch_to(n, &tasks[n]);
@@ -227,3 +209,11 @@ void reschedule(void) {
void sched_tick(void) {
reschedule();
}
+
+void wake_up(struct task_struct **task) {
+ if(task == NULL || *task == NULL)
+ return;
+
+ (*task)->state = TSTATE_RUNNING;
+ *task = NULL;
+}