summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Mannens <jake72360@gmail.com>2018-07-13 03:51:23 +1000
committerJake Mannens <jake72360@gmail.com>2018-07-13 03:51:23 +1000
commitbe74842e37ad54f4fd18ae647e2bdf3e435a0fb8 (patch)
tree7bf6af7ad55456d8b2a2d620d87cf948d10c1a26
parent778301ab212d9bb8ffa527491cbc93955eb0cb92 (diff)
Added a state field to the task structure to hold the task's run state.
Now, reschedule() requires a task to be in the TSTATE_RUNNING state for it to run. Renamed the TSS structure within the task structure from 'state' to 'tss' to avoid confusion with the task's run state. Removed the task_state structure declaration from sched.c as it is no longer needed due to context switches now being performed entirely in hardware. Removed the cstate pointer from sched.c. Interrupt handlers no longer set a pointer to saved state information on the stack since this was only needed for software task switching. NOTE: This may be re-introduced should it become necessary to access state information on the stack. Added a basic implementation of the wake_up() scheduling primative. This function is currently not used and may be completely re-written in future.
-rw-r--r--include/kernel/sched.h3
-rw-r--r--kernel/asm.s1
-rw-r--r--kernel/sched.c56
-rw-r--r--kernel/timer.s3
4 files changed, 25 insertions, 38 deletions
diff --git a/include/kernel/sched.h b/include/kernel/sched.h
index d040886..42b5b15 100644
--- a/include/kernel/sched.h
+++ b/include/kernel/sched.h
@@ -41,7 +41,8 @@ struct tss_struct {
struct task_struct {
pid_t pid;
- struct tss_struct state;
+ int state;
+ struct tss_struct tss;
} __attribute__((packed));
extern struct task_struct *ctask;
diff --git a/kernel/asm.s b/kernel/asm.s
index fc36171..aced9b4 100644
--- a/kernel/asm.s
+++ b/kernel/asm.s
@@ -1,7 +1,6 @@
global clear_tss
global switch_to
global set_tss
-extern cstate
extern ctask
extern ctaskn
extern gdt
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;
+}
diff --git a/kernel/timer.s b/kernel/timer.s
index 12ea9d0..760bcd7 100644
--- a/kernel/timer.s
+++ b/kernel/timer.s
@@ -1,6 +1,5 @@
global ticks
global timer_init
-extern cstate
extern register_isr
extern sched_tick
@@ -17,8 +16,6 @@ tick_handler:
mov es, ax
mov fs, ax
mov gs, ax
- ; save a pointer to the state information
- mov [cstate], esp
; handle the timer tick
inc dword [ticks]