compiled newlib, need to hook up the system calls
This commit is contained in:
@@ -5,24 +5,30 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "process.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
static process_t* process_table;
|
||||
static spinlock_t process_table_lock = {0};
|
||||
|
||||
static int current_process = 0;
|
||||
static int total_processes = 0;
|
||||
|
||||
extern uint32_t fetch_cr3();
|
||||
|
||||
#define IDLE_TASK_PID 1
|
||||
static void idle_task() {
|
||||
while (1) asm volatile("hlt");
|
||||
}
|
||||
|
||||
uint32_t schedule_next_task(uint32_t current_esp) {
|
||||
spin_lock(&process_table_lock);
|
||||
static void lock_scheduler() {
|
||||
disable_interrupts();
|
||||
}
|
||||
|
||||
static void unlock_scheduler() {
|
||||
enable_interrupts();
|
||||
}
|
||||
|
||||
// called from isr and yield, interrupts are already disabled and re enabled in the isr/yield func
|
||||
uint32_t switch_context(uint32_t current_esp) {
|
||||
process_table[current_process].esp = current_esp;
|
||||
|
||||
for (int i = 0; i < total_processes; i++) {
|
||||
@@ -39,6 +45,7 @@ uint32_t schedule_next_task(uint32_t current_esp) {
|
||||
|
||||
int next_process = current_process;
|
||||
int found_ready = 0;
|
||||
|
||||
while (1) {
|
||||
next_process = (next_process + 1) % total_processes;
|
||||
if (next_process != IDLE_TASK_PID && process_table[next_process].state == STATE_READY) {
|
||||
@@ -66,10 +73,7 @@ uint32_t schedule_next_task(uint32_t current_esp) {
|
||||
load_pd(process_table[current_process].cr3);
|
||||
}
|
||||
|
||||
uint32_t rtn = process_table[current_process].esp;
|
||||
spin_unlock(&process_table_lock);
|
||||
|
||||
return rtn;
|
||||
return process_table[current_process].esp;
|
||||
}
|
||||
|
||||
void init_scheduler() {
|
||||
@@ -94,9 +98,19 @@ int create_task(uint32_t entry_point, uint32_t cr3) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
spin_lock(&process_table_lock);
|
||||
lock_scheduler();
|
||||
|
||||
// default to a new task, but if we find a dead one, re use it
|
||||
process_t* process = &process_table[total_processes];
|
||||
process->pid = total_processes;
|
||||
uint32_t pid = total_processes;
|
||||
for (uint32_t i = 0; i < total_processes; i++) {
|
||||
if (process_table[i].state == STATE_DEAD) {
|
||||
process = &process_table[i];
|
||||
pid = i;
|
||||
}
|
||||
}
|
||||
|
||||
process->pid = pid;
|
||||
process->cr3 = cr3;
|
||||
process->state = STATE_READY;
|
||||
process->sleep = 0;
|
||||
@@ -118,19 +132,24 @@ int create_task(uint32_t entry_point, uint32_t cr3) {
|
||||
*(--esp) = 0; // EDI
|
||||
|
||||
process->esp = (uint32_t)esp;
|
||||
spin_unlock(&process_table_lock);
|
||||
|
||||
total_processes++;
|
||||
unlock_scheduler();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sleep(uint32_t ticks) {
|
||||
if (ticks == 0) return;
|
||||
|
||||
spin_lock(&process_table_lock);
|
||||
process_table[current_process].sleep = ticks;
|
||||
void sleep(uint32_t ms) {
|
||||
if (ms == 0) return;
|
||||
lock_scheduler();
|
||||
process_table[current_process].sleep = ms;
|
||||
process_table[current_process].state = STATE_SLEEPING;
|
||||
spin_unlock(&process_table_lock);
|
||||
|
||||
yield();
|
||||
}
|
||||
unlock_scheduler();
|
||||
}
|
||||
|
||||
void exit() {
|
||||
lock_scheduler();
|
||||
process_table[current_process].state = STATE_DEAD;
|
||||
yield(); // yield forever
|
||||
unlock_scheduler();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user