[MULTITASKING] Preemptive multitasking

This commit is contained in:
Thomas Lovén 2016-11-18 10:36:21 +01:00
parent d3d065b2e2
commit 664379b35c
7 changed files with 26 additions and 8 deletions

View File

@ -18,8 +18,6 @@ void thread_function()
while(1) while(1)
{ {
debug((char *)0x10000); debug((char *)0x10000);
schedule();
pit_delay(100);
} }
} }

View File

@ -14,3 +14,6 @@ uint64_t read_cr4();
#define CR4_OSFXSR (1<<9) #define CR4_OSFXSR (1<<9)
#define CR4_OSXMMEXCPT (1<<10) #define CR4_OSXMMEXCPT (1<<10)
#define RFLAGS_IF (1<<9)

View File

@ -3,11 +3,13 @@ typedef struct thread_st thread_t;
#include <stdint.h> #include <stdint.h>
#include <list.h> #include <list.h>
#include <process.h> #include <process.h>
#include <int.h>
#define THREAD_STACK_SIZE 0x1000-sizeof(thread_t) #define THREAD_STACK_SIZE 0x1000-sizeof(thread_t)
typedef struct thread_st typedef struct thread_st
{ {
registers_t r;
uint64_t stack_pointer; // Top of the kernel stack for thread uint64_t stack_pointer; // Top of the kernel stack for thread
uint64_t tid; uint64_t tid;
uint64_t state; uint64_t state;
@ -32,6 +34,7 @@ typedef struct thread_stack_st
uint64_t R13; uint64_t R13;
uint64_t R14; uint64_t R14;
uint64_t R15; uint64_t R15;
uint64_t thread;
uint64_t zero_frame; uint64_t zero_frame;
uint64_t function_address; uint64_t function_address;
thread_t tcb; thread_t tcb;

View File

@ -3,6 +3,7 @@
#include <msr.h> #include <msr.h>
#include <debug.h> #include <debug.h>
#include <mem.h> #include <mem.h>
#include <scheduler.h>
#define APIC_MSR_ENABLE 0x800 #define APIC_MSR_ENABLE 0x800
@ -62,8 +63,7 @@ registers_t *apic_timer_handler(registers_t *r)
{ {
// APIC timer timeout occurred // APIC timer timeout occurred
APIC(R_EOI) = 0; APIC(R_EOI) = 0;
debug_putch('-'); schedule();
apic_timer(1000000);
return r; return r;
} }
void apic_timer(uint64_t us) void apic_timer(uint64_t us)
@ -112,6 +112,4 @@ void apic_init()
// Register temporary timer handler to go off every 10 ms // Register temporary timer handler to go off every 10 ms
register_int_handler(INT_APIC_TIMER, apic_timer_handler); register_int_handler(INT_APIC_TIMER, apic_timer_handler);
apic_timer(1000000);
} }

View File

@ -2,6 +2,7 @@
#include <list.h> #include <list.h>
#include <debug.h> #include <debug.h>
#include <sse.h> #include <sse.h>
#include <apic.h>
LIST(thread_t, ready_queue); LIST(thread_t, ready_queue);
@ -39,6 +40,7 @@ void scheduler()
{ {
while(1) while(1)
{ {
apic_timer_stop();
thread_t *old = 0, *new = 0; thread_t *old = 0, *new = 0;
if((old = get_last_thread())) if((old = get_last_thread()))
{ {
@ -51,7 +53,8 @@ void scheduler()
} }
} }
while(!(new = scheduler_next())); while(!(new = scheduler_next()))asm("sti");
asm("cli");
if(!process_alive(new->process)) if(!process_alive(new->process))
{ {
@ -62,6 +65,7 @@ void scheduler()
set_last_thread(new); set_last_thread(new);
switch_process(new->process); switch_process(new->process);
sse_restore(new->sse_registers); sse_restore(new->sse_registers);
apic_timer(1000000);
switch_thread(scheduler_th, new); switch_thread(scheduler_th, new);
} }
} }
@ -71,6 +75,8 @@ void schedule()
// This function handles swithing to the next thread in the ready queue // This function handles swithing to the next thread in the ready queue
thread_t *old = get_current_thread(); thread_t *old = get_current_thread();
if(old == scheduler_th)
return;
if(old) if(old)
{ {

View File

@ -7,6 +7,7 @@ swtch:
# Switches stacks preserving callee preserved registers according to System V ABI # Switches stacks preserving callee preserved registers according to System V ABI
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push rdi
push r15 push r15
push r14 push r14
push r13 push r13
@ -24,5 +25,6 @@ swtch:
pop r13 pop r13
pop r14 pop r14
pop r15 pop r15
pop rdi
leaveq leaveq
ret ret

View File

@ -4,6 +4,7 @@
#include <mem.h> #include <mem.h>
#include <list.h> #include <list.h>
#include <debug.h> #include <debug.h>
#include <registers.h>
thread_t *current_thread = 0; thread_t *current_thread = 0;
@ -16,9 +17,16 @@ thread_t *new_thread(void (*func)(void))
thread_stack_t *stack = kcalloc(1, sizeof(thread_stack_t)); thread_stack_t *stack = kcalloc(1, sizeof(thread_stack_t));
thread_t *th = &stack->tcb; thread_t *th = &stack->tcb;
stack->function_address = (uint64_t)func; stack->thread = (uint64_t)th;
stack->function_address = (uint64_t)isr_return;
stack->RBP = (uint64_t)&stack->zero_frame; stack->RBP = (uint64_t)&stack->zero_frame;
th->r.rip = (uint64_t)func;
th->r.rflags = RFLAGS_IF;
th->r.cs = 0x8;
th->r.ss = 0x10;
th->r.rsp = (uint64_t)&th->stack_pointer;
th->tid = tid++; th->tid = tid++;
th->state = THREAD_STATE_READY; th->state = THREAD_STATE_READY;
th->stack_pointer = (uint64_t)&stack->RBP; th->stack_pointer = (uint64_t)&stack->RBP;