add wsclock and background page analysis job implementations
This commit is contained in:
parent
6078c70649
commit
775eb861ff
3
config.h
3
config.h
|
@ -1,2 +1,3 @@
|
||||||
#define PHYSICAL_PAGE_AMOUNT 64
|
#define PHYSICAL_PAGE_AMOUNT 64
|
||||||
#define PAGE_REPLACEMENT_ALGORITHM 1
|
#define PAGE_REPLACEMENT_ALGORITHM 2
|
||||||
|
#define WSCLOCK_TIME_WINDOW 15
|
||||||
|
|
|
@ -18,6 +18,7 @@ void RUNQ_add_process(size_t max_page_accesses, size_t total_pages_owned);
|
||||||
struct PhysPage {
|
struct PhysPage {
|
||||||
size_t ppn;
|
size_t ppn;
|
||||||
size_t busy_flag;
|
size_t busy_flag;
|
||||||
|
size_t last_accessed;
|
||||||
struct PhysPage *prev;
|
struct PhysPage *prev;
|
||||||
struct PhysPage *next;
|
struct PhysPage *next;
|
||||||
struct PageTableEntry *pt;
|
struct PageTableEntry *pt;
|
||||||
|
@ -27,4 +28,6 @@ struct PhysPage {
|
||||||
|
|
||||||
void KERNEL_page_fault(struct PageTableEntry *pt, size_t page_no);
|
void KERNEL_page_fault(struct PageTableEntry *pt, size_t page_no);
|
||||||
|
|
||||||
|
void KERNEL_update_job(size_t page_amount);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
80
src/kernel.c
80
src/kernel.c
|
@ -12,6 +12,8 @@ extern struct RunQ *runq;
|
||||||
extern struct PhysPage *first_free_page;
|
extern struct PhysPage *first_free_page;
|
||||||
extern struct PhysPage *first_busy_page;
|
extern struct PhysPage *first_busy_page;
|
||||||
|
|
||||||
|
extern size_t system_time;
|
||||||
|
|
||||||
|
|
||||||
struct RunQ *
|
struct RunQ *
|
||||||
RunQ(size_t max_procs)
|
RunQ(size_t max_procs)
|
||||||
|
@ -110,7 +112,83 @@ KERNEL_page_fault(struct PageTableEntry *pt, size_t page_no)
|
||||||
|
|
||||||
printf("[kernel:page_fault:random] Auto-advanced the list of busy pages to ppn %d\n", first_busy_page->ppn);
|
printf("[kernel:page_fault:random] Auto-advanced the list of busy pages to ppn %d\n", first_busy_page->ppn);
|
||||||
#elif PAGE_REPLACEMENT_ALGORITHM == 2
|
#elif PAGE_REPLACEMENT_ALGORITHM == 2
|
||||||
printf("[kernel:page_fault:wsclock] Not implemented\n");
|
|
||||||
|
// first pass (no reference flag + out of time window)
|
||||||
|
for (size_t i = 0; i < PHYSICAL_PAGE_AMOUNT; i++) {
|
||||||
|
if (first_busy_page->pt[first_busy_page->pt_index].r) {
|
||||||
|
printf("[kernel:page_fault:wsclock] ppn %d: r = 1, time %d -> %d\n",
|
||||||
|
first_busy_page->ppn, first_busy_page->last_accessed, system_time);
|
||||||
|
first_busy_page->last_accessed = system_time;
|
||||||
|
first_busy_page->pt[first_busy_page->pt_index].r = 0;
|
||||||
|
|
||||||
|
first_busy_page = first_busy_page->next;
|
||||||
|
} else if ((system_time - first_busy_page->last_accessed) > WSCLOCK_TIME_WINDOW) {
|
||||||
|
printf("[kernel:page_fault:wsclock] ppn %d: r = 0, time_window = %d (> WSCLOCK_TIME_WINDOW), using it\n",
|
||||||
|
first_busy_page->ppn, system_time - first_busy_page->last_accessed);
|
||||||
|
first_busy_page->pt[first_busy_page->pt_index].p = 0;
|
||||||
|
first_busy_page->pt = pt;
|
||||||
|
first_busy_page->pt_index = page_no;
|
||||||
|
pt[page_no].p = 1;
|
||||||
|
pt[page_no].ppn = first_busy_page->ppn;
|
||||||
|
|
||||||
|
first_busy_page = first_busy_page->next;
|
||||||
|
|
||||||
|
goto page_replacement_resolved;
|
||||||
|
} else {
|
||||||
|
printf("[kernel:page_fault:wsclock] ppn %d: r = 0, time_window = %d (<= WSCLOCK_TIME_WINDOW), still active\n",
|
||||||
|
first_busy_page->ppn, system_time - first_busy_page->last_accessed);
|
||||||
|
|
||||||
|
first_busy_page = first_busy_page->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to random
|
||||||
|
printf("[kernel:page_fault:wsclock] Failed to find non-active page, randomly selecting ppn %d\n", first_busy_page->ppn);
|
||||||
|
|
||||||
|
// clear presence 'bit' from old PTE
|
||||||
|
first_busy_page->pt[first_busy_page->pt_index].p = 0;
|
||||||
|
|
||||||
|
// update physical page data
|
||||||
|
first_busy_page->pt = pt;
|
||||||
|
first_busy_page->pt_index = page_no;
|
||||||
|
|
||||||
|
// update PTE data
|
||||||
|
pt[page_no].p = 1;
|
||||||
|
pt[page_no].ppn = first_busy_page->ppn;
|
||||||
|
|
||||||
|
// move hand to next physical page
|
||||||
|
first_busy_page = first_busy_page->next;
|
||||||
|
|
||||||
|
printf("[kernel:page_fault:wsclock] Auto-advanced the list of busy pages to ppn %d\n", first_busy_page->ppn);
|
||||||
|
|
||||||
|
page_replacement_resolved:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KERNEL_update_job(size_t page_amount)
|
||||||
|
{
|
||||||
|
if (first_busy_page == NULL) {
|
||||||
|
printf("[kernel:update_job] No pages to update\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PhysPage *starting_page = first_busy_page;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < page_amount; i++) {
|
||||||
|
if (first_busy_page->pt[first_busy_page->pt_index].r) {
|
||||||
|
printf("[kernel:update_job] ppn %d updated time %d -> %d\n", first_busy_page->ppn, first_busy_page->last_accessed, system_time);
|
||||||
|
first_busy_page->pt[first_busy_page->pt_index].r = 0;
|
||||||
|
first_busy_page->last_accessed = system_time;
|
||||||
|
} else {
|
||||||
|
printf("[kernel:update_job] ppn %d is up-to-date (time = %d)\n", first_busy_page->ppn, first_busy_page->last_accessed);
|
||||||
|
}
|
||||||
|
|
||||||
|
first_busy_page = first_busy_page->next;
|
||||||
|
|
||||||
|
if (first_busy_page == starting_page) {
|
||||||
|
printf("[kernel:update_job] Looped around the busy page list, exiting after %d iterations\n", i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
11
src/main.c
11
src/main.c
|
@ -28,7 +28,7 @@ main(void)
|
||||||
first_free_page->prev = first_free_page;
|
first_free_page->prev = first_free_page;
|
||||||
first_free_page->next = first_free_page;
|
first_free_page->next = first_free_page;
|
||||||
|
|
||||||
for (int i = 1; i <= PHYSICAL_PAGE_AMOUNT; i++) {
|
for (int i = 1; i < PHYSICAL_PAGE_AMOUNT; i++) {
|
||||||
struct PhysPage *pp = malloc(sizeof(struct PhysPage));
|
struct PhysPage *pp = malloc(sizeof(struct PhysPage));
|
||||||
pp->ppn = i;
|
pp->ppn = i;
|
||||||
pp->busy_flag = 0;
|
pp->busy_flag = 0;
|
||||||
|
@ -50,12 +50,13 @@ main(void)
|
||||||
|
|
||||||
runq = RunQ(10);
|
runq = RunQ(10);
|
||||||
|
|
||||||
for (size_t i = 0; i < 5; i++) {
|
for (size_t i = 0; i < 10; i++) {
|
||||||
RUNQ_add_process(10000, 10 + randint(70));
|
RUNQ_add_process(10000, 10 + randint(90));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
PROCESS_run_for(runq->current_proc, 20);
|
PROCESS_run_for(runq->current_proc, 50);
|
||||||
runq->current_proc = runq->current_proc->next;
|
runq->current_proc = runq->current_proc->next;
|
||||||
|
KERNEL_update_job(8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue