Refactor: Check if page is in a swap in fetch_page instead of the page fault handler
This commit is contained in:
@@ -24,7 +24,7 @@ static void page_fault (struct intr_frame *);
|
|||||||
|
|
||||||
static bool is_valid_stack_access (const void *fault_addr, const void *esp);
|
static bool is_valid_stack_access (const void *fault_addr, const void *esp);
|
||||||
static bool grow_stack (void *upage);
|
static bool grow_stack (void *upage);
|
||||||
bool try_fetch_page (void *upage, bool write);
|
bool fetch_page (void *upage, bool write);
|
||||||
|
|
||||||
/* Registers handlers for interrupts that can be caused by user
|
/* Registers handlers for interrupts that can be caused by user
|
||||||
programs.
|
programs.
|
||||||
@@ -167,29 +167,14 @@ page_fault (struct intr_frame *f)
|
|||||||
be just that the stack needs to grow or that it needs to be lazily loaded.
|
be just that the stack needs to grow or that it needs to be lazily loaded.
|
||||||
So we attempt to grow the stack. If this does not work, we check our SPT to
|
So we attempt to grow the stack. If this does not work, we check our SPT to
|
||||||
see if the page is expected to have data loaded in memory. */
|
see if the page is expected to have data loaded in memory. */
|
||||||
struct thread *t = thread_current ();
|
|
||||||
void *upage = pg_round_down (fault_addr);
|
void *upage = pg_round_down (fault_addr);
|
||||||
if (not_present && is_user_vaddr (upage) && upage != NULL)
|
if (not_present && is_user_vaddr (upage) && upage != NULL)
|
||||||
{
|
{
|
||||||
/* 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
|
|
||||||
frame. */
|
|
||||||
if (page_in_swap (t, fault_addr))
|
|
||||||
{
|
|
||||||
size_t swap_slot = page_get_swap (t, fault_addr);
|
|
||||||
void *kpage = frame_alloc (0, upage, t);
|
|
||||||
swap_in (kpage, swap_slot);
|
|
||||||
|
|
||||||
bool writeable = pagedir_is_writable (t->pagedir, upage);
|
|
||||||
if (pagedir_set_page (t->pagedir, upage, kpage, writeable)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_valid_stack_access (fault_addr, esp))
|
if (is_valid_stack_access (fault_addr, esp))
|
||||||
if (grow_stack (upage))
|
if (grow_stack (upage))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (try_fetch_page (upage, write))
|
if (fetch_page (upage, write))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,8 +247,24 @@ grow_stack (void *upage)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
try_fetch_page (void *upage, bool write)
|
fetch_page (void *upage, bool write)
|
||||||
{
|
{
|
||||||
|
/* 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
|
||||||
|
frame. */
|
||||||
|
struct thread *t = thread_current ();
|
||||||
|
if (page_in_swap (t, upage))
|
||||||
|
{
|
||||||
|
size_t swap_slot = page_get_swap (t, upage);
|
||||||
|
void *kpage = frame_alloc (0, upage, t);
|
||||||
|
swap_in (kpage, swap_slot);
|
||||||
|
|
||||||
|
bool writeable = pagedir_is_writable (t->pagedir, upage);
|
||||||
|
if (pagedir_set_page (t->pagedir, upage, kpage, writeable))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if the page is in the supplemental page table. That is, it is a page
|
/* Check if the page is in the supplemental page table. That is, it is a page
|
||||||
that is expected to be in memory. */
|
that is expected to be in memory. */
|
||||||
struct page_entry *page = page_get (upage);
|
struct page_entry *page = page_get (upage);
|
||||||
|
|||||||
Reference in New Issue
Block a user