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; write = (f->error_code & PF_W) != 0;
user = (f->error_code & PF_U) != 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; return;
} }

View File

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

View File

@@ -7,9 +7,28 @@
#define MAX_STACK_ACCESS_DIST 32 #define MAX_STACK_ACCESS_DIST 32
/* Validates a given address for being <=32 bytes away from the stack pointer or static bool needs_new_page (const void *addr, const void *esp);
above the stack */ static bool grow_stack (const void *addr);
bool needs_new_page (void *addr, void *esp)
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) && 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) &&
@@ -18,7 +37,8 @@ bool needs_new_page (void *addr, void *esp)
} }
/* Extends the stack by the necessary number of pages */ /* 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 (); struct thread *t = thread_current ();
void *last_page = pg_round_down (addr); void *last_page = pg_round_down (addr);
@@ -35,6 +55,4 @@ bool grow_stack (void *addr)
return false; return false;
} }
return true; return true;
} }

View File

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