#include #include #include #include "kernel.h" #include "process.h" extern struct RunQ *runq; extern struct PhysPage *first_free_page; extern struct PhysPage *first_busy_page; 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) { printf("[kernel:page_fault] Handling %d started\n", page_no); if (first_free_page) { printf("[kernel:page_fault] Found free page #%d, using it\n", first_free_page->ppn); pt[page_no].ppn = first_free_page->ppn; pt[page_no].p = 1; 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; } } }