Merge stack growth functions
This commit is contained in:
50
src/vm/stackgrowth.c
Normal file
50
src/vm/stackgrowth.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include "stackgrowth.h"
|
||||
#include "threads/palloc.h"
|
||||
#include "threads/thread.h"
|
||||
#include "threads/vaddr.h"
|
||||
#include "userprog/pagedir.h"
|
||||
|
||||
#define MAX_STACK_ACCESS_DIST 32
|
||||
|
||||
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)
|
||||
{
|
||||
return needs_new_page (ptr, esp) && grow_stack (ptr);
|
||||
}
|
||||
|
||||
/* 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) &&
|
||||
((PHYS_BASE - pg_round_down (addr))
|
||||
<= MAX_STACK_SIZE));
|
||||
}
|
||||
|
||||
/* Extends the stack by the necessary number of pages */
|
||||
static bool
|
||||
grow_stack (const void *addr)
|
||||
{
|
||||
struct thread *t = thread_current ();
|
||||
void *last_page = pg_round_down (addr);
|
||||
|
||||
uint8_t *new_page = palloc_get_page (PAL_USER | PAL_ZERO);
|
||||
if ( new_page == NULL)
|
||||
return false;
|
||||
|
||||
bool added_page = pagedir_get_page (t->pagedir, last_page) == NULL
|
||||
&& pagedir_set_page (t->pagedir, last_page, new_page, true);
|
||||
|
||||
if (!added_page) {
|
||||
palloc_free_page (new_page);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
10
src/vm/stackgrowth.h
Normal file
10
src/vm/stackgrowth.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef VM_GROWSTACK_H
|
||||
#define VM_GROWSTACK_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_STACK_SIZE 8388608 // (8MB)
|
||||
|
||||
bool try_alloc_new_page (const void *ptr, const void *esp);
|
||||
|
||||
#endif /* vm/frame.h */
|
||||
Reference in New Issue
Block a user