[MULTITASKING] Context switching and scheduler

This commit is contained in:
2016-11-05 19:55:54 +01:00
parent 1f06c0bcf1
commit 5e8fbcbb78
9 changed files with 288 additions and 0 deletions

69
kernel/include/list.h Normal file
View File

@@ -0,0 +1,69 @@
#pragma once
#define LIST(type, name) \
struct { \
type *prev; \
type *next; \
} name;
#define LIST_HEAD_INIT(name) \
name.prev = name.next = 0;
#define LIST_INIT(self, list) \
self->list.prev = self->list.next = 0;
#define LIST_APPEND(head, self, list) \
do { \
self->list.prev = head.prev; \
self->list.next = 0; \
if(self->list.prev) { \
self->list.prev->list.next = self; \
} \
head.prev = self; \
if(!head.next){head.next = head.prev;} \
} while(0);
#define LIST_REMOVE(head, self, list) \
do { \
if(head.next == self) { \
head.next = self->list.next; \
} \
if(head.prev == self) { \
head.prev = self->list.prev; \
} \
if(self->list.next) { \
self->list.next->list.prev = self->list.prev; \
} \
if(self->list.prev) { \
self->list.prev->list.next = self->list.next; \
} \
self->list.prev = self->list.next = 0; \
} while(0);
#define LIST_EMPTY(head) ((head.next) == 0)
#define LIST_FIRST(head) (head.next)
#define LIST_FOREACH(head, type, name, list) \
for(type *name = head.next; name; name = name->list.next)
#define LIST_INSERT_BEFORE(head, self, list, after) \
do { \
self->list.next = after; \
self->list.next = after->list.prev; \
after->list.prev = self; \
if(self->list.prev) \
self->list.prev->list.next = self; \
if(head.next == after) \
head.next = self; \
} while(0);
#define LIST_INSERT_AFTER(head, self, list, before) \
do { \
self->list.prev = before; \
self->list.next = before->list.next; \
before->list.next = self; \
if(self->list.next) \
self->list.next->list.prev = self; \
if(head->prev == before) \
head.prev = self; \
} while(0);

View File

@@ -0,0 +1,6 @@
#pragma once
#include <thread.h>
void schedule();
void scheduler_insert(thread_t *th);
void scheduler_init();

43
kernel/include/thread.h Normal file
View File

@@ -0,0 +1,43 @@
#pragma once
#include <stdint.h>
#include <list.h>
#define THREAD_STACK_SIZE 0x1000-sizeof(thread_t)
typedef struct thread_st
{
uint64_t stack_pointer; // Top of the kernel stack for thread
uint64_t tid;
uint64_t state;
LIST(struct thread_st, ready_queue);
} thread_t;
#define THREAD_STATE_WAITING 0x1
#define THREAD_STATE_READY 0x2
#define THREAD_STATE_RUNNING 0x3
#define THREAD_STATE_FINISHED 0x4
typedef struct thread_stack_st
{
uint8_t stack[THREAD_STACK_SIZE-8*8];
// Stack layout of a new thread
uint64_t RBP;
uint64_t RBX;
uint64_t R12;
uint64_t R13;
uint64_t R14;
uint64_t R15;
uint64_t zero_frame;
uint64_t function_address;
thread_t tcb;
} thread_stack_t;
thread_t *current_thread;
#define get_current_thread() (current_thread)
#define set_current_thread(new) (current_thread = (new))
thread_t *new_thread(void (*func)(void));
void switch_thread(thread_t *old, thread_t *new);
void free_thread(thread_t *th);
void swtch(uint64_t *old, uint64_t *new);