Scheduler and multiple threads
This commit is contained in:
57
src/kernel/proc/scheduler.c
Normal file
57
src/kernel/proc/scheduler.c
Normal file
@@ -0,0 +1,57 @@
|
||||
#include <proc.h>
|
||||
|
||||
static struct {
|
||||
struct thread *first;
|
||||
struct thread *last;
|
||||
} run_q = {0,0};
|
||||
|
||||
static struct thread *scheduler_thread;
|
||||
|
||||
static struct thread *scheduler_next()
|
||||
{
|
||||
struct thread *ret = run_q.first;
|
||||
if(run_q.first && !(run_q.first = run_q.first->q_next))
|
||||
run_q.last = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void scheduler_insert(struct thread *new)
|
||||
{
|
||||
if(run_q.last) {
|
||||
run_q.last->q_next = new;
|
||||
run_q.last = new;
|
||||
} else {
|
||||
run_q.first = run_q.last = new;
|
||||
}
|
||||
new->q_next = 0;
|
||||
}
|
||||
|
||||
void scheduler()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
struct thread *new = 0;
|
||||
while(!(new = scheduler_next()));
|
||||
|
||||
current_thread = new;
|
||||
switch_stack(&scheduler_thread->stack_ptr, &new->stack_ptr);
|
||||
|
||||
scheduler_insert(current_thread);
|
||||
current_thread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
long k_sched_yield(long, long, long, long, long, long)
|
||||
{
|
||||
switch_stack(¤t_thread->stack_ptr, &scheduler_thread->stack_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void start_scheduler()
|
||||
{
|
||||
scheduler_thread = new_thread(scheduler);
|
||||
scheduler_thread->tid = (uint64_t)-1;
|
||||
|
||||
uint64_t stack;
|
||||
switch_stack(&stack, &scheduler_thread->stack_ptr);
|
||||
}
|
||||
@@ -16,18 +16,16 @@ struct swtch_stack
|
||||
|
||||
static uint64_t next_tid = 1;
|
||||
|
||||
static struct thread *run_queue = 0;
|
||||
static struct thread *current_thread;
|
||||
static struct thread *scheduler_thread;
|
||||
struct thread *current_thread;
|
||||
|
||||
struct thread *new_thread(void (*function)(void))
|
||||
{
|
||||
struct thread *th = P2V(pmm_calloc());
|
||||
th->tid = next_tid++;
|
||||
th->stack = incptr(th, PAGE_SIZE - sizeof(struct swtch_stack));
|
||||
th->stack_ptr = incptr(th, PAGE_SIZE - sizeof(struct swtch_stack));
|
||||
th->q_next = 0;
|
||||
|
||||
struct swtch_stack *stck = th->stack;
|
||||
struct swtch_stack *stck = th->stack_ptr;
|
||||
stck->RBP = (uint64_t)&stck->RBP2;
|
||||
stck->ret = (uint64_t)function;
|
||||
|
||||
@@ -37,38 +35,4 @@ struct thread *new_thread(void (*function)(void))
|
||||
struct thread *thread()
|
||||
{
|
||||
return current_thread;
|
||||
}
|
||||
|
||||
void k_yield()
|
||||
{
|
||||
switch_stack(¤t_thread->stack, &scheduler_thread->stack);
|
||||
}
|
||||
|
||||
struct thread *scheduler_next()
|
||||
{
|
||||
if(!current_thread) return run_queue;
|
||||
return current_thread->q_next;
|
||||
}
|
||||
|
||||
void scheduler()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
struct thread *new = 0;
|
||||
while(!(new = scheduler_next()));
|
||||
|
||||
current_thread = new;
|
||||
switch_stack(&scheduler_thread->stack, &new->stack);
|
||||
|
||||
current_thread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void start_scheduler()
|
||||
{
|
||||
scheduler_thread = new_thread(scheduler);
|
||||
scheduler_thread->tid = (uint64_t)-1;
|
||||
|
||||
uint64_t stack;
|
||||
switch_stack(&stack, &scheduler_thread->stack);
|
||||
}
|
||||
Reference in New Issue
Block a user