summaryrefslogtreecommitdiffstats
path: root/userprog/process.c
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2012-06-19 01:44:56 +0200
committermanuel <manuel@mausz.at>2012-06-19 01:44:56 +0200
commite88a8c4c379d721e9901752d440a05295087da11 (patch)
treeb89070c525614267811a10b77a4dbc49ffd96b03 /userprog/process.c
parentd9e0c55d118d0a3923b440b7811f8d1d6db9e1d7 (diff)
downloadprogos-e88a8c4c379d721e9901752d440a05295087da11.tar.gz
progos-e88a8c4c379d721e9901752d440a05295087da11.tar.bz2
progos-e88a8c4c379d721e9901752d440a05295087da11.zip
implement page table and use it for lazy loading of segments
Diffstat (limited to 'userprog/process.c')
-rw-r--r--userprog/process.c35
1 files changed, 12 insertions, 23 deletions
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 @@
18#include "threads/synch.h" 18#include "threads/synch.h"
19#include "threads/thread.h" 19#include "threads/thread.h"
20#include "threads/vaddr.h" 20#include "threads/vaddr.h"
21#include "vm/page.h"
21 22
22/* data structure to communicate with the thread initializing a new process */ 23/* data structure to communicate with the thread initializing a new process */
23struct start_aux_data { 24struct start_aux_data {
@@ -128,6 +129,8 @@ start_process (void *aux)
128 process->parent_tid = aux_data->parent_thread->tid; 129 process->parent_tid = aux_data->parent_thread->tid;
129 thread->process = process; 130 thread->process = process;
130 131
132 page_table_init (&thread->page_table);
133
131 /* Initialize interrupt frame and load executable. */ 134 /* Initialize interrupt frame and load executable. */
132 memset (&if_, 0, sizeof if_); 135 memset (&if_, 0, sizeof if_);
133 if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG; 136 if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG;
@@ -251,6 +254,8 @@ process_exit (void)
251 pagedir_destroy (pd); 254 pagedir_destroy (pd);
252 } 255 }
253 256
257 page_table_free (&thread->page_table);
258
254 /* Destroy the process structure if the parent is not alive 259 /* Destroy the process structure if the parent is not alive
255 * any more. Atomic test and set would be sufficient here. 260 * any more. Atomic test and set would be sufficient here.
256 */ 261 */
@@ -478,8 +483,6 @@ load (const char *args, void (**eip) (void), void **esp)
478 483
479/* load() helpers. */ 484/* load() helpers. */
480 485
481static bool install_page (void *upage, void *kpage, bool writable);
482
483/* Checks whether PHDR describes a valid, loadable segment in 486/* Checks whether PHDR describes a valid, loadable segment in
484 FILE and returns true if so, false otherwise. */ 487 FILE and returns true if so, false otherwise. */
485static bool 488static bool
@@ -556,29 +559,15 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
556 size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE; 559 size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE;
557 size_t page_zero_bytes = PGSIZE - page_read_bytes; 560 size_t page_zero_bytes = PGSIZE - page_read_bytes;
558 561
559 /* Get a page of memory. */ 562 /* add segment to page table for on demand loading */
560 uint8_t *kpage = palloc_get_page (PAL_USER); 563 if (!page_table_insert_segment (file, ofs, upage, page_read_bytes,
561 if (kpage == NULL) 564 page_zero_bytes, writable))
562 return false;
563
564 /* Load this page. */
565 if (file_read (file, kpage, page_read_bytes) != (int) page_read_bytes)
566 {
567 palloc_free_page (kpage);
568 return false; 565 return false;
569 }
570 memset (kpage + page_read_bytes, 0, page_zero_bytes);
571
572 /* Add the page to the process's address space. */
573 if (!install_page (upage, kpage, writable))
574 {
575 palloc_free_page (kpage);
576 return false;
577 }
578 566
579 /* Advance. */ 567 /* Advance. */
580 read_bytes -= page_read_bytes; 568 read_bytes -= page_read_bytes;
581 zero_bytes -= page_zero_bytes; 569 zero_bytes -= page_zero_bytes;
570 ofs += page_read_bytes;
582 upage += PGSIZE; 571 upage += PGSIZE;
583 } 572 }
584 return true; 573 return true;
@@ -602,7 +591,7 @@ setup_stack (uint32_t **esp, const char *args)
602 if (kpage == NULL) 591 if (kpage == NULL)
603 return false; 592 return false;
604 593
605 if (! install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true)) { 594 if (! process_install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true)) {
606 palloc_free_page (kpage); 595 palloc_free_page (kpage);
607 return false; 596 return false;
608 } 597 }
@@ -706,8 +695,8 @@ setup_stack (uint32_t **esp, const char *args)
706 with palloc_get_page(). 695 with palloc_get_page().
707 Returns true on success, false if UPAGE is already mapped or 696 Returns true on success, false if UPAGE is already mapped or
708 if memory allocation fails. */ 697 if memory allocation fails. */
709static bool 698bool
710install_page (void *upage, void *kpage, bool writable) 699process_install_page (void *upage, void *kpage, bool writable)
711{ 700{
712 struct thread *t = thread_current (); 701 struct thread *t = thread_current ();
713 702