2025-03-06 21:50:29 +02:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdlib.h>
|
2025-03-06 23:05:21 +02:00
|
|
|
#include <stdio.h>
|
2025-03-06 21:50:29 +02:00
|
|
|
|
|
|
|
#include "kernel.h"
|
|
|
|
#include "process.h"
|
|
|
|
|
2025-03-06 23:05:21 +02:00
|
|
|
|
|
|
|
extern struct RunQ *runq;
|
|
|
|
|
|
|
|
extern struct PhysPage *first_free_page;
|
|
|
|
extern struct PhysPage *first_busy_page;
|
|
|
|
|
|
|
|
|
2025-03-06 21:50:29 +02:00
|
|
|
struct RunQ *
|
|
|
|
RunQ(size_t max_procs)
|
|
|
|
{
|
|
|
|
struct RunQ *runq = malloc(sizeof(struct RunQ));
|
|
|
|
runq->current_proc = NULL;
|
|
|
|
runq->max_procs = max_procs;
|
|
|
|
runq->proc_amount = 0;
|
|
|
|
runq->next_proc_id = 1;
|
|
|
|
|
|
|
|
return runq;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RUNQ_add_process(size_t max_page_accesses,
|
|
|
|
size_t total_pages_owned)
|
|
|
|
{
|
|
|
|
if (runq->proc_amount >= runq->max_procs)
|
|
|
|
return;
|
|
|
|
|
|
|
|
struct Process *new_p = Process(runq->next_proc_id, max_page_accesses, total_pages_owned);
|
|
|
|
|
|
|
|
if (!runq->current_proc) {
|
|
|
|
runq->current_proc = new_p;
|
|
|
|
new_p->next = new_p;
|
|
|
|
new_p->prev = new_p;
|
|
|
|
} else {
|
|
|
|
new_p->next = runq->current_proc;
|
|
|
|
new_p->prev = runq->current_proc->prev;
|
|
|
|
new_p->next->prev = new_p;
|
|
|
|
new_p->prev->next = new_p;
|
|
|
|
runq->current_proc = new_p;
|
|
|
|
}
|
|
|
|
|
|
|
|
runq->proc_amount++;
|
|
|
|
runq->next_proc_id++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
KERNEL_page_fault(struct PageTableEntry *pt, size_t page_no)
|
|
|
|
{
|
2025-03-06 23:05:21 +02:00
|
|
|
printf("[kernel:page_fault] Handling %d started\n", page_no);
|
|
|
|
|
2025-03-06 21:50:29 +02:00
|
|
|
if (first_free_page) {
|
2025-03-06 23:05:21 +02:00
|
|
|
printf("[kernel:page_fault] Found free page #%d, using it\n", first_free_page->ppn);
|
2025-03-06 21:50:29 +02:00
|
|
|
pt[page_no].ppn = first_free_page->ppn;
|
|
|
|
pt[page_no].p = 1;
|
2025-03-06 23:05:21 +02:00
|
|
|
|
|
|
|
first_free_page->busy_flag = 1;
|
|
|
|
first_free_page->pt = pt;
|
|
|
|
first_free_page->pt_index = page_no;
|
|
|
|
|
|
|
|
// ---- free list -> busy list ----
|
|
|
|
struct PhysPage *this_page = first_free_page;
|
|
|
|
|
|
|
|
if (first_free_page->next != first_free_page) {
|
|
|
|
// reconnect free list items together
|
|
|
|
first_free_page->prev->next = first_free_page->next;
|
|
|
|
first_free_page->next->prev = first_free_page->prev;
|
|
|
|
first_free_page = first_free_page->next;
|
|
|
|
} else {
|
|
|
|
// clear list if it only had this page
|
|
|
|
first_free_page = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!first_busy_page) {
|
|
|
|
// initialize the busy list with this page
|
|
|
|
first_busy_page = this_page;
|
|
|
|
} else {
|
|
|
|
// insert this page at the end of the list
|
|
|
|
this_page->next = first_busy_page;
|
|
|
|
this_page->prev = first_busy_page->prev;
|
|
|
|
this_page->prev->next = this_page;
|
|
|
|
this_page->next->prev = this_page;
|
|
|
|
}
|
2025-03-06 21:50:29 +02:00
|
|
|
}
|
|
|
|
}
|