diff options
Diffstat (limited to 'userprog/process.c')
| -rw-r--r-- | userprog/process.c | 35 |
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 */ |
| 23 | struct start_aux_data { | 24 | struct 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 | ||
| 481 | static 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. */ |
| 485 | static bool | 488 | static 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. */ |
| 709 | static bool | 698 | bool |
| 710 | install_page (void *upage, void *kpage, bool writable) | 699 | process_install_page (void *upage, void *kpage, bool writable) |
| 711 | { | 700 | { |
| 712 | struct thread *t = thread_current (); | 701 | struct thread *t = thread_current (); |
| 713 | 702 | ||
