Simple scheduler
This commit is contained in:
parent
1e2f81a5d8
commit
251b5f71c9
@ -6,6 +6,7 @@
|
||||
#include <cpu.h>
|
||||
#include <interrupts.h>
|
||||
#include <thread.h>
|
||||
#include <scheduler.h>
|
||||
|
||||
void thread_function()
|
||||
{
|
||||
@ -36,9 +37,9 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
||||
|
||||
debug_ok("Boot \"Complete\"\n");
|
||||
|
||||
new_thread(thread_function);
|
||||
new_thread(thread_function);
|
||||
new_thread(thread_function);
|
||||
ready(new_thread(thread_function));
|
||||
ready(new_thread(thread_function));
|
||||
ready(new_thread(thread_function));
|
||||
yield();
|
||||
|
||||
PANIC("Reached end of kernel main function\n");
|
||||
|
4
src/kernel/include/scheduler.h
Normal file
4
src/kernel/include/scheduler.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void ready(struct thread *th);
|
||||
struct thread *scheduler_next();
|
@ -7,6 +7,7 @@ struct tcb
|
||||
uintptr_t stack_ptr;
|
||||
uint64_t tid;
|
||||
uint64_t state;
|
||||
struct thread *next;
|
||||
};
|
||||
|
||||
#define TCB_OFFSET (PAGE_SIZE - sizeof(struct tcb))
|
||||
@ -31,12 +32,10 @@ struct thread
|
||||
struct tcb tcb;
|
||||
};
|
||||
|
||||
extern struct thread *threads[];
|
||||
int current_tid;
|
||||
struct thread *current_thread;
|
||||
#define CURRENT_THREAD() (current_thread)
|
||||
|
||||
#define CURRENT_THREAD() (threads[current_tid])
|
||||
|
||||
struct thread *new_thread(void (*function)());
|
||||
struct thread *new_thread(void (*function)(void));
|
||||
void yield();
|
||||
int get_tid();
|
||||
|
||||
|
26
src/kernel/proc/scheduler.c
Normal file
26
src/kernel/proc/scheduler.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include <thread.h>
|
||||
|
||||
struct {
|
||||
struct thread *first;
|
||||
struct thread *last;
|
||||
} readyQ = {0,0};
|
||||
|
||||
void ready(struct thread *th)
|
||||
{
|
||||
if(!readyQ.last)
|
||||
{
|
||||
th->tcb.next = 0;
|
||||
readyQ.first = readyQ.last = th;
|
||||
} else {
|
||||
readyQ.last->tcb.next = th;
|
||||
readyQ.last = th;
|
||||
}
|
||||
}
|
||||
|
||||
struct thread *scheduler_next()
|
||||
{
|
||||
struct thread *th = readyQ.first;
|
||||
if(!(readyQ.first = th->tcb.next))
|
||||
readyQ.last = 0;
|
||||
return th;
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
#include <thread.h>
|
||||
|
||||
struct thread *threads[8];
|
||||
int current_tid = -1;
|
||||
int tid = 0;
|
||||
#include <scheduler.h>
|
||||
|
||||
struct thread dummy;
|
||||
struct thread *current_thread = 0;
|
||||
|
||||
struct thread *new_thread(void (*function)())
|
||||
uint64_t tid = 1;
|
||||
struct thread *new_thread(void (*function)(void))
|
||||
{
|
||||
struct thread *th = threads[tid] = P2V(pmm_alloc());
|
||||
struct thread *th = P2V(pmm_alloc());
|
||||
|
||||
th->tcb.tid = tid++;
|
||||
th->RBP = (uint64_t)&th->RBP2;
|
||||
@ -20,22 +19,20 @@ struct thread *new_thread(void (*function)())
|
||||
|
||||
void switch_thread(struct thread *old, struct thread *new)
|
||||
{
|
||||
current_thread = new;
|
||||
swtch(&old->tcb.stack_ptr, &new->tcb.stack_ptr);
|
||||
}
|
||||
|
||||
void yield()
|
||||
{
|
||||
struct thread *old, *new;
|
||||
if(current_tid == -1)
|
||||
old = &dummy;
|
||||
|
||||
old = current_thread;
|
||||
if(old)
|
||||
ready(old);
|
||||
else
|
||||
old = threads[current_tid];
|
||||
|
||||
current_tid++;
|
||||
if(current_tid == tid)
|
||||
current_tid = 0;
|
||||
|
||||
new = threads[current_tid];
|
||||
old = &dummy;
|
||||
while(!(new = scheduler_next()));
|
||||
|
||||
switch_thread(old, new);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user