refactor: dynamic stack growth functions to follow code style

This commit is contained in:
Themis Demetriades
2024-12-02 19:50:40 +00:00
parent 05a48cf9c6
commit 6adf2e743b
3 changed files with 33 additions and 23 deletions

View File

@@ -148,12 +148,12 @@ page_fault (struct intr_frame *f)
if (user && not_present) if (user && not_present)
{ {
if (try_alloc_new_page (fault_addr, f->esp)) if (handle_stack_fault (fault_addr, f->esp))
return; return;
} }
else else
{ {
if (try_alloc_new_page (fault_addr, thread_current ()->curr_esp)) if (handle_stack_fault (fault_addr, thread_current ()->curr_esp))
return; return;
f->eip = (void *)f->eax; f->eip = (void *)f->eax;

View File

@@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include "stackgrowth.h" #include "stackgrowth.h"
#include "frame.h"
#include "threads/palloc.h" #include "threads/palloc.h"
#include "threads/thread.h" #include "threads/thread.h"
#include "threads/vaddr.h" #include "threads/vaddr.h"
@@ -7,44 +8,53 @@
#define MAX_STACK_ACCESS_DIST 32 #define MAX_STACK_ACCESS_DIST 32
static bool needs_new_page (const void *addr, const void *esp); static bool is_stack_fault (const void *addr, const void *esp);
static bool grow_stack (const void *addr); static bool grow_stack (const void *addr);
/* Determine whether a particular page fault occured due to a stack
access below the stack pointer that should induce stack growth, and
if so grow the stack by a single page (capped at MAX_STACK_SIZE). */
bool bool
try_alloc_new_page (const void *ptr, const void *esp) handle_stack_fault (const void *ptr, const void *esp)
{ {
return needs_new_page (ptr, esp) && grow_stack (ptr); return is_stack_fault (ptr, esp) && grow_stack (ptr);
} }
/* Validates a given address for being a stack query and not a generic erroneous /* Determines whether a particular page fault appears to be caused by
address a stack access that should induce dynamic stack growth. Stack size
*/ is capped at MAX_STACK_SIZE. */
static bool static bool
needs_new_page (const void *addr, const void *esp) is_stack_fault (const void *addr, const void *esp)
{ {
return (is_user_vaddr (addr) && return (is_user_vaddr (addr) &&
(uint32_t*)addr >= ((uint32_t*)esp - MAX_STACK_ACCESS_DIST) && (uint32_t*)addr >= ((uint32_t*)esp - MAX_STACK_ACCESS_DIST) &&
((PHYS_BASE - pg_round_down (addr)) ((PHYS_BASE - pg_round_down (addr)) <= MAX_STACK_SIZE));
<= MAX_STACK_SIZE));
} }
/* Extends the stack by the necessary number of pages */ /* Grows the stack of the process running inside the current thread by a single
page given a user virtual address inside of the page wherein the new section
of the stack should be allocated. */
static bool static bool
grow_stack (const void *addr) grow_stack (const void *addr)
{ {
struct thread *t = thread_current (); struct thread *t = thread_current ();
void *last_page = pg_round_down (addr); void *last_page = pg_round_down (addr);
uint8_t *new_page = palloc_get_page (PAL_USER | PAL_ZERO); /* This function should only be called when dealing with a faulting stack
access that induces stack growth, so the provided address shouldn't be
present in a page within the current thread's page directory. */
ASSERT (pagedir_get_page (t->pagedir, last_page) == NULL);
uint8_t *new_page = frame_alloc (PAL_ZERO, last_page, t);
if (new_page == NULL) if (new_page == NULL)
return false; return false;
bool added_page = pagedir_get_page (t->pagedir, last_page) == NULL if (!pagedir_set_page (t->pagedir, last_page, new_page, true))
&& pagedir_set_page (t->pagedir, last_page, new_page, true); {
frame_free (new_page);
if (!added_page) {
palloc_free_page (new_page);
return false; return false;
} }
return true; return true;
} }

View File

@@ -5,6 +5,6 @@
#define MAX_STACK_SIZE 8388608 // (8MB) #define MAX_STACK_SIZE 8388608 // (8MB)
bool try_alloc_new_page (const void *ptr, const void *esp); bool handle_stack_fault (const void *ptr, const void *esp);
#endif /* vm/frame.h */ #endif /* vm/frame.h */