scheduler: have a separate stack for yield

This commit is contained in:
Matheus
2023-05-03 19:11:40 -03:00
parent 393e34a04e
commit b5d4fc07e2
4 changed files with 15 additions and 7 deletions
+7 -5
View File
@@ -34,17 +34,19 @@ arch_context_switch:
o64 iret o64 iret
; saves context on the stack and passes as the argument to a function ; saves context on the stack and passes as the argument to a function
; since this uses the C system V abi, some registers can be clobbered (in this case, rsi and r11) ; since this uses the C system V abi, some registers can be clobbered (in this case, r10 and r11)
; rdi has the pointer to the function to call ; rdi has the pointer to the function to call
; rsi has the pointer to the stack the function should have on call
; if the main function returns, just return normally ; if the main function returns, just return normally
global arch_context_saveandcall global arch_context_saveandcall
arch_context_saveandcall: arch_context_saveandcall:
mov r11, [rsp] ; save return address on scratch register mov r11, [rsp] ; save return address on scratch register
mov rsi, rsp mov r10, rsp
add rsi, 8 ; stack pointer before the call instruction add r10, 8 ; stack pointer before the call instruction
mov rsp, rsi ; use desired stack
push qword 0x10 ; SS push qword 0x10 ; SS
push rsi ; RSP push r10 ; RSP
pushf ; movs and pushes don't affect flags pushf ; movs and pushes don't affect flags
push qword 0x08 ; CS push qword 0x08 ; CS
push r11 ; return address push r11 ; return address
@@ -73,7 +75,7 @@ arch_context_saveandcall:
mov r11, rdi ; save function to call mov r11, rdi ; save function to call
mov rdi, rsp ; first argument is the context struct mov rdi, rsp ; first argument is the context struct
push rsi ; save old stack push r10 ; save old stack
call r11 ; jump to the desired function call r11 ; jump to the desired function
pop rsp ; restore old stack pop rsp ; restore old stack
+1 -1
View File
@@ -60,7 +60,7 @@ typedef struct {
} }
void arch_context_switch(context_t *context); void arch_context_switch(context_t *context);
void arch_context_saveandcall(void (*fn)(context_t *context)); void arch_context_saveandcall(void (*fn)(context_t *context), void *stack);
#include <string.h> #include <string.h>
+1
View File
@@ -24,6 +24,7 @@ typedef struct cpu_t {
thread_t *thread; thread_t *thread;
thread_t *idlethread; thread_t *idlethread;
timerentry_t schedtimerentry; timerentry_t schedtimerentry;
void *schedulerstack;
} cpu_t; } cpu_t;
#define CPU_HALT() asm volatile("hlt") #define CPU_HALT() asm volatile("hlt")
+6 -1
View File
@@ -7,6 +7,7 @@
#include <kernel/alloc.h> #include <kernel/alloc.h>
#define QUANTUM_US 100000 #define QUANTUM_US 100000
#define SCHEDULER_STACK_SIZE 4096
static scache_t *threadcache; static scache_t *threadcache;
static scache_t *processcache; static scache_t *processcache;
@@ -218,7 +219,7 @@ static void yield(context_t *context) {
void sched_yield() { void sched_yield() {
bool old = interrupt_set(false); bool old = interrupt_set(false);
arch_context_saveandcall(yield); arch_context_saveandcall(yield, _cpu()->schedulerstack);
interrupt_set(old); interrupt_set(old);
} }
@@ -258,6 +259,10 @@ void sched_init() {
processcache = slab_newcache(sizeof(proc_t), 0, NULL, NULL); processcache = slab_newcache(sizeof(proc_t), 0, NULL, NULL);
__assert(processcache); __assert(processcache);
_cpu()->schedulerstack = alloc(SCHEDULER_STACK_SIZE);
__assert(_cpu()->schedulerstack);
_cpu()->schedulerstack = (void *)((uintptr_t)_cpu()->schedulerstack + SCHEDULER_STACK_SIZE);
_cpu()->schedtimerentry.func = timerhook; _cpu()->schedtimerentry.func = timerhook;
_cpu()->schedtimerentry.repeatus = QUANTUM_US; _cpu()->schedtimerentry.repeatus = QUANTUM_US;
SPINLOCK_INIT(runqueuelock); SPINLOCK_INIT(runqueuelock);