feat: implement synchronisation to protecting access to PTEs of SPTs during eviction
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user