Skip to content
This repository has been archived by the owner on Oct 22, 2022. It is now read-only.

Commit

Permalink
Implement round-robin scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
DonaldKellett committed Oct 15, 2022
1 parent e7f4502 commit b55ab70
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 7 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ plic:
process:
$(CC) -c src/process/syscall.c $(CFLAGS) -o syscall.o
$(CC) -c src/process/process.c $(CFLAGS) -o process.o
$(CC) -c src/process/sched.c $(CFLAGS) -o sched.o

kmain:
$(CC) -c src/kmain.c $(CFLAGS) -o kmain.o
Expand Down
Binary file added misc/gallery/05-process/03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added misc/gallery/05-process/04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added misc/gallery/05-process/05.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 19 additions & 6 deletions src/kmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "plic/cpu.h"
#include "plic/plic.h"
#include "process/process.h"
#include "process/sched.h"

extern const size_t INIT_START;
extern const size_t INIT_END;
Expand Down Expand Up @@ -55,12 +56,24 @@ void kmain(void) {
PLIC_ENABLE(PLIC_UART);
PLIC_SET_PRIO(PLIC_UART, 1);

kprintf("Initializing the process scheduler ...\n");
sched_init();

kprintf("Adding a second and third process to test our scheduler ...\n");
sched_enqueue(init_process);
sched_enqueue(init_process);

kprintf("Starting our first process ...\n");
struct process *pid1 = create_process(init_process);
ASSERT(pid1 != NULL,
"kmain(): failed to allocate structure for init process\n");
switch_to_user((size_t)pid1->frame, pid1->pc,
SATP_FROM(MODE_SV39, pid1->pid,
(size_t)pid1->root >> PAGE_ORDER));
struct process *process = sched_schedule();
ASSERT(process != NULL,
"kmain(): process structure returned from scheduler was unexpectedly NULL\n");
kprintf("Our first process has PID = %d\n", process->pid);

kprintf("Issuing our first context switch timer ...\n");
set_timer_interrupt_delay_us(1 * US_PER_SECOND);

switch_to_user((size_t)process->frame, process->pc,
SATP_FROM(MODE_SV39, process->pid,
(size_t)process->root >> PAGE_ORDER));
PANIC("kmain(): failed to start our first process!\n");
}
16 changes: 15 additions & 1 deletion src/plic/trap_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#include "plic.h"
#include "../syscon/syscon.h"
#include "../process/syscall.h"
#include "../process/sched.h"
#include "../process/process.h"
#include "../mm/sv39.h"
#include "../mm/page.h"

// Handle only the following interrupts for now:
//
Expand All @@ -24,7 +28,17 @@ size_t m_mode_trap_handler(size_t epc, size_t tval, size_t cause, size_t hart,
switch (exception_code) {
case 7:
// Timer interrupt
set_timer_interrupt_delay_us(1 * US_PER_SECOND);
{
set_timer_interrupt_delay_us(1 * US_PER_SECOND);
struct process *process = sched_schedule();
ASSERT(process != NULL,
"m_mode_trap_handler(): unexpected got NULL when attempting to schedule next process\n");
kprintf("Context switch: scheduling next process with PID = %d\n",
process->pid);
switch_to_user((size_t)process->frame, process->pc,
SATP_FROM(MODE_SV39, process->pid,
(size_t)process->root >> PAGE_ORDER));
}
break;
case 11:
// External interrupt (UART)
Expand Down
40 changes: 40 additions & 0 deletions src/process/sched.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <stddef.h>
#include "sched.h"
#include "../common/common.h"
#include "process.h"
#include "../mm/kmem.h"

static struct process_ll *PROCESSES = NULL;

void sched_init(void) {
ASSERT(PROCESSES == NULL,
"sched_init(): should only be called once at system startup\n");
sched_enqueue(init_process);
}

void sched_enqueue(void (*func)(void)) {
struct process_ll *nd = kmalloc(sizeof(struct process_ll));
ASSERT(nd != NULL,
"sched_enqueue(): failed to allocate linked list node for new process\n");
nd->process = create_process(func);
if (PROCESSES == NULL) {
nd->prev = nd;
nd->next = nd;
PROCESSES = nd;
} else {
nd->prev = PROCESSES->prev;
nd->next = PROCESSES;
PROCESSES->prev->next = nd;
PROCESSES->prev = nd;
}
}

struct process *sched_schedule(void) {
ASSERT(PROCESSES != NULL,
"sched_schedule(): cannot schedule a process from an empty process list - did you call sched_init()?\n");
struct process *process = PROCESSES->process;
ASSERT(process != NULL,
"sched_schedule(): process structure from head of process list was unexpectedly NULL\n");
PROCESSES = PROCESSES->next;
return process;
}
14 changes: 14 additions & 0 deletions src/process/sched.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef SCHED_H
#define SCHED_H

struct process_ll {
struct process *process;
struct process_ll *prev;
struct process_ll *next;
};

void sched_init(void);
void sched_enqueue(void (*)(void));
struct process *sched_schedule(void);

#endif

0 comments on commit b55ab70

Please sign in to comment.