diff options
| author | Jake Mannens <jake72360@gmail.com> | 2018-07-12 01:01:10 +1000 |
|---|---|---|
| committer | Jake Mannens <jake72360@gmail.com> | 2018-07-12 01:01:10 +1000 |
| commit | 778301ab212d9bb8ffa527491cbc93955eb0cb92 (patch) | |
| tree | e62a2ee8180966d4fe41f80ba74f63977e51fcff | |
| parent | 6a6d5142d19638177c79c45d828f4b95db14799c (diff) | |
Task state information is no longer manually saved on context switch.
Since the kernel now has it's own stack unique to each address space, we
can now rely on hardware task switching to *also* save the task states.
To accomplish this, most of the code in switch_to() has been elimated.
This includes; the clearing of the busy flag in the old TSS on each
switch, setting the TR register to null prior to each switch and calling
save_state() (which has also been removed entirely), to copy the state
information.
Modified the for loop in reschedule() to account for the fact that the
switch_to() function may now return (which it *always* does when
returning to the task). For the same reason, switch_to() must also be
careful to preserve registers such as EBX and actually make a return
following the far jump.
Added basic definitions for task states in sched.h. These are; running,
interruptible, uninterruptible, zombie and stopped. These states will
(possibly) be used in the future to implement blocking system calls.
| -rw-r--r-- | include/kernel/sched.h | 6 | ||||
| -rw-r--r-- | kernel/asm.s | 14 | ||||
| -rw-r--r-- | kernel/sched.c | 25 |
3 files changed, 12 insertions, 33 deletions
diff --git a/include/kernel/sched.h b/include/kernel/sched.h index a3d95e0..d040886 100644 --- a/include/kernel/sched.h +++ b/include/kernel/sched.h @@ -4,6 +4,12 @@ #include <stdint.h> #include <unistd.h> +#define TSTATE_RUNNING 0 +#define TSTATE_INTERRUPTIBLE 1 +#define TSTATE_UNINTERRUPTIBLE 2 +#define TSTATE_ZOMBIE 3 +#define TSTATE_STOPPED 4 + struct tss_struct { uint32_t prevt; uint32_t esp0; diff --git a/kernel/asm.s b/kernel/asm.s index 6d35334..fc36171 100644 --- a/kernel/asm.s +++ b/kernel/asm.s @@ -11,6 +11,7 @@ extern save_state switch_to: push ebp mov ebp, esp + push ebx ; abort if we're switching to the current task mov ebx, [ctask] cmp ebx, [ebp+12] @@ -18,16 +19,6 @@ switch_to: pop ebp ret .skip: - ; clear the busy flag in the current TSS - mov eax, 0 - str ax - add ax, gdt+5 - mov byte [eax], 0x89 - ; set the current TSS to null so it won't be overwritten by the switch - mov ax, 0 - ltr ax - ; copy the saved state into the previous TSS - call save_state ; update ctask and ctaskn mov ebx, [ebp+12] mov [ctask], ebx @@ -39,6 +30,9 @@ switch_to: shl ebx, 3 mov [.tmp+4], bx jmp far [.tmp] + pop ebx + pop ebp + ret .tmp: dq 0 diff --git a/kernel/sched.c b/kernel/sched.c index c9f0da9..675867c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -208,28 +208,6 @@ void sched_init(void) { switch_to(0, &tasks[0]); } -void save_state(void) { - if(ctask == NULL || cstate == NULL) - return; - - ctask->state.eax = cstate->eax; - ctask->state.ebx = cstate->ebx; - ctask->state.ecx = cstate->ecx; - ctask->state.edx = cstate->edx; - ctask->state.esi = cstate->esi; - ctask->state.edi = cstate->edi; - ctask->state.esp = cstate->esp; - ctask->state.ebp = cstate->ebp; - ctask->state.cs = cstate->cs; - ctask->state.ds = cstate->ds; - ctask->state.es = cstate->ds; - ctask->state.fs = cstate->ds; - ctask->state.gs = cstate->ds; - ctask->state.ss = cstate->ss; - ctask->state.eflags = cstate->eflags; - ctask->state.eip = cstate->eip; -} - void reschedule(void) { int i; uint32_t n; @@ -241,8 +219,9 @@ void reschedule(void) { for(i = 0; i < NRTASKS; i++) { n = (n + 1) % NRTASKS; if(tasks[n].pid) - switch_to(n, &tasks[n]); + break; } + switch_to(n, &tasks[n]); } void sched_tick(void) { |
