Implement dynamic stack growth #54

Merged
td1223 merged 14 commits from ethan-stack-growth into virtual-memory 2024-11-30 23:21:34 +00:00
10 changed files with 68 additions and 353 deletions
Showing only changes of commit 3ef5264b6e - Show all commits

View File

@@ -63,6 +63,7 @@ userprog_SRC += userprog/tss.c # TSS management.
# Virtual memory code. # Virtual memory code.
vm_SRC += devices/swap.c # Swap block manager. vm_SRC += devices/swap.c # Swap block manager.
vm_SRC += vm/stackgrowth.c
#vm_SRC = vm/file.c # Some other file. #vm_SRC = vm/file.c # Some other file.
# Filesystem code. # Filesystem code.

View File

@@ -4,6 +4,7 @@
#include "userprog/gdt.h" #include "userprog/gdt.h"
#include "threads/interrupt.h" #include "threads/interrupt.h"
#include "threads/thread.h" #include "threads/thread.h"
#include "vm/stackgrowth.h"
/* Number of page faults processed. */ /* Number of page faults processed. */
static long long page_fault_cnt; static long long page_fault_cnt;
@@ -145,6 +146,12 @@ 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 (grow_stack (fault_addr))
return;
}
/* To implement virtual memory, delete the rest of the function /* To implement virtual memory, delete the rest of the function
body, and replace it with code that brings in the page to body, and replace it with code that brings in the page to
which fault_addr refers. */ which fault_addr refers. */

38
src/vm/stackgrowth.c Normal file
View File

@@ -0,0 +1,38 @@
#include <stdio.h>
#include "stackgrowth.h"
#include "threads/palloc.h"
#include "threads/thread.h"
#include "threads/vaddr.h"
#include "userprog/pagedir.h"
/* 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)
{
return (is_user_vaddr (addr) &&
(uint32_t*)addr >= ((uint32_t*)esp - 32) &&
((PHYS_BASE - pg_round_down (addr))
<= MAX_STACK_SIZE));
}
/* Extends the stack by the necessary number of pages */
bool grow_stack (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;
}

11
src/vm/stackgrowth.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef GROWSTACK_H
#define GROWSTACK_H
#include <stdio.h>
#define MAX_STACK_SIZE 8388608 // (8MB)
bool needs_new_page (void *addr, void *esp);
bool grow_stack (void *addr);
#endif //GROWSTACK_H