feat: implement synchronisation to protecting access to PTEs of SPTs during eviction

This commit is contained in:
Themis Demetriades
2024-12-05 16:51:15 +00:00
parent e779e8ac7c
commit d03e253046
6 changed files with 114 additions and 45 deletions

View File

@@ -2,6 +2,7 @@
#include <inttypes.h>
#include <stdio.h>
#include "stdbool.h"
#include "threads/synch.h"
#include "userprog/gdt.h"
#include "userprog/pagedir.h"
#include "userprog/process.h"
@@ -249,6 +250,12 @@ grow_stack (void *upage)
bool
fetch_page (void *upage, bool write)
{
/* Check if the page is in the supplemental page table. That is, it is a page
that is expected to be in memory. */
struct page_entry *page = page_get (upage);
if (page == NULL)
return false;
/* Check if the non-present user page is in the swap partition.
If so, swap it back into main memory, updating the PTE for
the faulted virtual address to point to the newly allocated
@@ -256,20 +263,25 @@ fetch_page (void *upage, bool write)
struct thread *t = thread_current ();
if (page_in_swap (t, upage))
{
size_t swap_slot = page_get_swap (t, upage);
/* NOTE: This code should be refactored and moved into helper functions
within 'page.c'.*/
void *kpage = frame_alloc (0, upage, t);
lock_acquire (&page->lock);
size_t swap_slot = page_get_swap (t, upage);
swap_in (kpage, swap_slot);
bool writeable = pagedir_is_writable (t->pagedir, upage);
if (pagedir_set_page (t->pagedir, upage, kpage, writeable))
return true;
}
hash_delete (&thread_current ()->pages, &page->elem);
lock_release (&page->lock);
page_cleanup (&page->elem, NULL);
/* Check if the page is in the supplemental page table. That is, it is a page
that is expected to be in memory. */
struct page_entry *page = page_get (upage);
if (page == NULL)
return false;
bool writeable = pagedir_is_writable (t->pagedir, upage);
/* TODO: When this returns false we should quit the page fault,
but currently we continue and check the stack conditions in the
page fault handler. */
return pagedir_set_page (t->pagedir, upage, kpage, writeable);
}
/* An attempt to write to a non-writeable should fail. */
if (write && !page->writable)
@@ -278,8 +290,14 @@ fetch_page (void *upage, bool write)
/* Load the page into memory based on the type of data it is expecting. */
bool success = false;
switch (page->type) {
case PAGE_MMAP:
case PAGE_FILE:
success = page_load (page, page->writable);
success = page_load_file (page, page->writable);
if (success && page->type == PAGE_FILE)
{
hash_delete (&thread_current ()->pages, &page->elem);
page_cleanup (&page->elem, NULL);
}
break;
default:
return false;