forked from xamidev/pepperOS
80 lines
2.3 KiB
C
80 lines
2.3 KiB
C
/*
|
|
* @author xamidev <xamidev@riseup.net>
|
|
* @brief Round-robin scheduler
|
|
* @license GPL-3.0-only
|
|
*/
|
|
|
|
#include <kernel.h>
|
|
#include <sched/process.h>
|
|
#include <mem/paging.h>
|
|
#include <stdint.h>
|
|
#include <io/serial/serial.h>
|
|
|
|
extern struct process_t* processes_list;
|
|
extern struct process_t* current_process;
|
|
extern struct process_t* idle_proc;
|
|
|
|
/*
|
|
* scheduler_init - Choose the first process
|
|
*/
|
|
void scheduler_init()
|
|
{
|
|
current_process = processes_list;
|
|
}
|
|
|
|
/*
|
|
* scheduler_schedule - Main scheduling routine
|
|
* @context: CPU context of previous process
|
|
*
|
|
* Chooses the next process that we should run.
|
|
* The routine is executed every SCHEDULER_QUANTUM ticks.
|
|
*
|
|
* Return:
|
|
* <context> - CPU context for next process
|
|
*/
|
|
struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
|
|
{
|
|
if (context == NULL) {
|
|
panic(NULL, "Scheduler called with NULL context");
|
|
}
|
|
|
|
if (current_process == NULL) {
|
|
// If no more processes, then set IDLE as the current process, that's it.
|
|
current_process = idle_proc;
|
|
}
|
|
|
|
if (current_process == idle_proc && current_process->next == NULL)
|
|
{
|
|
return idle_proc->context;
|
|
}
|
|
|
|
current_process->context = context;
|
|
|
|
for (;;) {
|
|
struct process_t* prev_process = current_process;
|
|
if (current_process->next != NULL) {
|
|
current_process = current_process->next;
|
|
} else {
|
|
current_process = processes_list;
|
|
}
|
|
|
|
if (current_process != NULL && current_process->status == DEAD) {
|
|
process_delete(&prev_process, current_process);
|
|
current_process = NULL;
|
|
return idle_proc->context;
|
|
} else {
|
|
current_process->status = RUNNING;
|
|
/* if (prev_process != current_process) {
|
|
DEBUG("Changed from {pid=%u, name=%s} to {pid=%u, name=%s}", prev_process->pid, prev_process->name, current_process->pid, current_process->name);
|
|
} */
|
|
break;
|
|
}
|
|
}
|
|
|
|
//DEBUG("current_process={pid=%u, name='%s', root_page_table[virt]=%p}", current_process->pid, current_process->name, current_process->root_page_table);
|
|
|
|
load_cr3(VIRT_TO_PHYS((uint64_t)current_process->root_page_table));
|
|
//DEBUG("Loaded process PML4 into CR3");
|
|
|
|
return current_process->context;
|
|
} |