From e88a8c4c379d721e9901752d440a05295087da11 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 19 Jun 2012 01:44:56 +0200 Subject: implement page table and use it for lazy loading of segments --- userprog/process.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) (limited to 'userprog/process.c') diff --git a/userprog/process.c b/userprog/process.c index c13c051..15883d9 100644 --- a/userprog/process.c +++ b/userprog/process.c @@ -18,6 +18,7 @@ #include "threads/synch.h" #include "threads/thread.h" #include "threads/vaddr.h" +#include "vm/page.h" /* data structure to communicate with the thread initializing a new process */ struct start_aux_data { @@ -128,6 +129,8 @@ start_process (void *aux) process->parent_tid = aux_data->parent_thread->tid; thread->process = process; + page_table_init (&thread->page_table); + /* Initialize interrupt frame and load executable. */ memset (&if_, 0, sizeof if_); if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG; @@ -251,6 +254,8 @@ process_exit (void) pagedir_destroy (pd); } + page_table_free (&thread->page_table); + /* Destroy the process structure if the parent is not alive * any more. Atomic test and set would be sufficient here. */ @@ -478,8 +483,6 @@ load (const char *args, void (**eip) (void), void **esp) /* load() helpers. */ -static bool install_page (void *upage, void *kpage, bool writable); - /* Checks whether PHDR describes a valid, loadable segment in FILE and returns true if so, false otherwise. */ static bool @@ -556,29 +559,15 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage, size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE; size_t page_zero_bytes = PGSIZE - page_read_bytes; - /* Get a page of memory. */ - uint8_t *kpage = palloc_get_page (PAL_USER); - if (kpage == NULL) - return false; - - /* Load this page. */ - if (file_read (file, kpage, page_read_bytes) != (int) page_read_bytes) - { - palloc_free_page (kpage); + /* add segment to page table for on demand loading */ + if (!page_table_insert_segment (file, ofs, upage, page_read_bytes, + page_zero_bytes, writable)) return false; - } - memset (kpage + page_read_bytes, 0, page_zero_bytes); - - /* Add the page to the process's address space. */ - if (!install_page (upage, kpage, writable)) - { - palloc_free_page (kpage); - return false; - } /* Advance. */ read_bytes -= page_read_bytes; zero_bytes -= page_zero_bytes; + ofs += page_read_bytes; upage += PGSIZE; } return true; @@ -602,7 +591,7 @@ setup_stack (uint32_t **esp, const char *args) if (kpage == NULL) return false; - if (! install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true)) { + if (! process_install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true)) { palloc_free_page (kpage); return false; } @@ -706,8 +695,8 @@ setup_stack (uint32_t **esp, const char *args) with palloc_get_page(). Returns true on success, false if UPAGE is already mapped or if memory allocation fails. */ -static bool -install_page (void *upage, void *kpage, bool writable) +bool +process_install_page (void *upage, void *kpage, bool writable) { struct thread *t = thread_current (); -- cgit v1.2.3