Refactor: abstract new page allocation to one general function and make helper functions static

This commit is contained in:
EDiasAlberto
2024-11-27 19:41:22 +00:00
parent c74a8c55aa
commit 4f84a83611
4 changed files with 34 additions and 28 deletions

View File

@@ -146,9 +146,9 @@ page_fault (struct intr_frame *f)
write = (f->error_code & PF_W) != 0;
user = (f->error_code & PF_U) != 0;
if (user && needs_new_page (fault_addr, f->esp))
if (user)
{
if (grow_stack (fault_addr))
if (try_alloc_new_page (fault_addr, f->esp))
return;
}

View File

@@ -455,20 +455,6 @@ fd_get_file (int fd)
return hash_entry (e, struct open_file, elem);
}
static bool
try_alloc_new_page (const void *ptr)
{
if (needs_new_page (ptr, thread_current()->curr_esp))
{
if (!grow_stack (ptr))
return 0;
else
return 1;
}
else
return 0;
}
/* Validates if a block of memory starting at START and of size SIZE bytes is
fully contained within user virtual memory. Kills the thread (by exiting with
failure) if the memory is invalid. Otherwise, returns (nothing) normally.
@@ -480,6 +466,8 @@ validate_user_pointer (const void *start, size_t size)
if (size == 0)
return;
struct thread *t = thread_current ();
const void *end = start + size - 1;
/* Check if the start and end pointers are valid user virtual addresses. */
@@ -489,9 +477,9 @@ validate_user_pointer (const void *start, size_t size)
/* We now need to check if the entire memory block is mapped to physical
memory by the page table. */
for (const void *ptr = pg_round_down (start); ptr <= end; ptr += PGSIZE)
if (pagedir_get_page (thread_current ()->pagedir, ptr) == NULL)
if (pagedir_get_page (t->pagedir, ptr) == NULL)
{
if (!try_alloc_new_page (ptr))
if (!try_alloc_new_page (ptr, t->curr_esp))
syscall_exit (EXIT_FAILURE);
}
}
@@ -508,6 +496,7 @@ validate_user_string (const char *str)
/* Calculate the offset of the string within the (first) page. */
size_t offset = (uintptr_t) str % PGSIZE;
struct thread *t = thread_current ();
/* We move page by page, checking if the page is mapped to physical memory. */
for (;;)
@@ -519,8 +508,8 @@ validate_user_string (const char *str)
if (!is_user_vaddr(page))
syscall_exit (EXIT_FAILURE);
if (pagedir_get_page (thread_current ()->pagedir, page) == NULL)
if (!try_alloc_new_page (str))
if (pagedir_get_page (t->pagedir, page) == NULL)
if (!try_alloc_new_page (str, t->curr_esp))
syscall_exit (EXIT_FAILURE);
while (offset < PGSIZE)

View File

@@ -7,9 +7,28 @@
#define MAX_STACK_ACCESS_DIST 32
/* Validates a given address for being <=32 bytes away from the stack pointer or
above the stack */
bool needs_new_page (void *addr, void *esp)
static bool needs_new_page (const void *addr, const void *esp);
static bool grow_stack (const void *addr);
bool
try_alloc_new_page (const void *ptr, const void *esp)
{
if (needs_new_page (ptr, esp))
{
if (!grow_stack (ptr))
return 0;
else
return 1;
}
else
return 0;
}
/* Validates a given address for being a stack query and not a generic erroneous
address
*/
static bool
needs_new_page (const void *addr, const void *esp)
{
return (is_user_vaddr (addr) &&
(uint32_t*)addr >= ((uint32_t*)esp - MAX_STACK_ACCESS_DIST) &&
@@ -18,7 +37,8 @@ bool needs_new_page (void *addr, void *esp)
}
/* Extends the stack by the necessary number of pages */
bool grow_stack (void *addr)
static bool
grow_stack (const void *addr)
{
struct thread *t = thread_current ();
void *last_page = pg_round_down (addr);
@@ -35,6 +55,4 @@ bool grow_stack (void *addr)
return false;
}
return true;
}

View File

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