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 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 {
 | 
			
		||||
	size_t ppn;
 | 
			
		||||
	size_t busy_flag;
 | 
			
		||||
	size_t last_accessed;
 | 
			
		||||
	struct PhysPage *prev;
 | 
			
		||||
	struct PhysPage *next;
 | 
			
		||||
	struct PageTableEntry *pt;
 | 
			
		||||
@ -27,4 +28,6 @@ struct PhysPage {
 | 
			
		||||
 | 
			
		||||
void KERNEL_page_fault(struct PageTableEntry *pt, size_t page_no);
 | 
			
		||||
 | 
			
		||||
void KERNEL_update_job(size_t page_amount);
 | 
			
		||||
 | 
			
		||||
#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_busy_page;
 | 
			
		||||
 | 
			
		||||
extern size_t system_time;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct RunQ *
 | 
			
		||||
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);
 | 
			
		||||
		#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
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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->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));
 | 
			
		||||
		pp->ppn = i;
 | 
			
		||||
		pp->busy_flag = 0;
 | 
			
		||||
@ -50,12 +50,13 @@ main(void)
 | 
			
		||||
 | 
			
		||||
	runq = RunQ(10);
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < 5; i++) {
 | 
			
		||||
		RUNQ_add_process(10000, 10 + randint(70));
 | 
			
		||||
	for (size_t i = 0; i < 10; i++) {
 | 
			
		||||
		RUNQ_add_process(10000, 10 + randint(90));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < 20; i++) {
 | 
			
		||||
		PROCESS_run_for(runq->current_proc, 20);
 | 
			
		||||
	for (int i = 0; i < 100; i++) {
 | 
			
		||||
		PROCESS_run_for(runq->current_proc, 50);
 | 
			
		||||
		runq->current_proc = runq->current_proc->next;
 | 
			
		||||
		KERNEL_update_job(8);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user