summaryrefslogtreecommitdiffstats
path: root/userprog
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2012-06-21 16:47:23 +0200
committermanuel <manuel@mausz.at>2012-06-21 16:47:23 +0200
commite11b2ef0c606ab516a4344aeea1dbba22cb1fe5d (patch)
treeb4973f4dca916113c82a4a172f6f729d41cf4430 /userprog
parente9e69def589375c3d0e51b532268b27d3d403bbf (diff)
downloadprogos-e11b2ef0c606ab516a4344aeea1dbba22cb1fe5d.tar.gz
progos-e11b2ef0c606ab516a4344aeea1dbba22cb1fe5d.tar.bz2
progos-e11b2ef0c606ab516a4344aeea1dbba22cb1fe5d.zip
initial implementation of memory mapped files
Diffstat (limited to 'userprog')
-rw-r--r--userprog/process.c18
-rw-r--r--userprog/process.h2
-rw-r--r--userprog/syscall.c62
3 files changed, 76 insertions, 6 deletions
diff --git a/userprog/process.c b/userprog/process.c
index 2771e76..f399038 100644
--- a/userprog/process.c
+++ b/userprog/process.c
@@ -130,6 +130,8 @@ start_process (void *aux)
130 thread->process = process; 130 thread->process = process;
131 131
132 page_table_init (&thread->page_table); 132 page_table_init (&thread->page_table);
133 if (!mmap_table_init (&process->mmap_table))
134 goto signal;
133 135
134 /* Initialize interrupt frame and load executable. */ 136 /* Initialize interrupt frame and load executable. */
135 memset (&if_, 0, sizeof if_); 137 memset (&if_, 0, sizeof if_);
@@ -149,6 +151,14 @@ start_process (void *aux)
149 /* If process startup failed, quit. */ 151 /* If process startup failed, quit. */
150 if (thread->process == NULL) { 152 if (thread->process == NULL) {
151 if (process != NULL) { 153 if (process != NULL) {
154 //TODO: free mmap table + page table?
155
156 /* close/free memory mapped files */
157 //mmap_table_free (&process->mmap_table);
158
159 /* free page table */
160 //page_table_free (&thread->page_table);
161
152 if (process->fd_table.fds != NULL) 162 if (process->fd_table.fds != NULL)
153 palloc_free_page (process->fd_table.fds); 163 palloc_free_page (process->fd_table.fds);
154 palloc_free_page (process); 164 palloc_free_page (process);
@@ -232,6 +242,9 @@ process_exit (void)
232 lock_release (&filesys_lock); 242 lock_release (&filesys_lock);
233 } 243 }
234 244
245 /* close/free memory mapped files */
246 mmap_table_free (&proc->mmap_table);
247
235 int fd; 248 int fd;
236 for (fd = 2; fd <= proc->fd_table.fd_max; fd++) { 249 for (fd = 2; fd <= proc->fd_table.fd_max; fd++) {
237 process_close_file (fd); 250 process_close_file (fd);
@@ -254,6 +267,7 @@ process_exit (void)
254 pagedir_destroy (pd); 267 pagedir_destroy (pd);
255 } 268 }
256 269
270 /* free page table */
257 page_table_free (&thread->page_table); 271 page_table_free (&thread->page_table);
258 272
259 /* Destroy the process structure if the parent is not alive 273 /* Destroy the process structure if the parent is not alive
@@ -560,8 +574,8 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
560 size_t page_zero_bytes = PGSIZE - page_read_bytes; 574 size_t page_zero_bytes = PGSIZE - page_read_bytes;
561 575
562 /* add segment to page table for on demand loading */ 576 /* add segment to page table for on demand loading */
563 if (!page_table_insert_segment (file, ofs, upage, page_read_bytes, 577 if (!page_table_insert_segment (&thread_current ()->page_table, file, ofs,
564 page_zero_bytes, writable)) 578 upage, page_read_bytes, writable))
565 return false; 579 return false;
566 580
567 /* Advance. */ 581 /* Advance. */
diff --git a/userprog/process.h b/userprog/process.h
index 5fcd80e..bac9a60 100644
--- a/userprog/process.h
+++ b/userprog/process.h
@@ -2,6 +2,7 @@
2#define USERPROG_PROCESS_H 2#define USERPROG_PROCESS_H
3 3
4#include "threads/thread.h" 4#include "threads/thread.h"
5#include "vm/mmap.h"
5 6
6#define STACK_SIZE (1 << 23) /* 8MB maximum stack size */ 7#define STACK_SIZE (1 << 23) /* 8MB maximum stack size */
7 8
@@ -27,6 +28,7 @@ struct process {
27 /* files */ 28 /* files */
28 struct file *executable; /* Loaded executable, if any. */ 29 struct file *executable; /* Loaded executable, if any. */
29 struct fd_table fd_table; /* File descriptor table */ 30 struct fd_table fd_table; /* File descriptor table */
31 struct mmap_table mmap_table; /* Memory mapped files table */
30 32
31 /* Owned by syscall.c */ 33 /* Owned by syscall.c */
32 void* syscall_buffer; 34 void* syscall_buffer;
diff --git a/userprog/syscall.c b/userprog/syscall.c
index 7f8c397..14cbaab 100644
--- a/userprog/syscall.c
+++ b/userprog/syscall.c
@@ -14,7 +14,8 @@
14#include "userprog/pagedir.h" 14#include "userprog/pagedir.h"
15#include "userprog/process.h" 15#include "userprog/process.h"
16#include "userprog/syscall.h" 16#include "userprog/syscall.h"
17#include "lib/user/syscall.h" 17#include "vm/mmap.h"
18#include "vm/page.h"
18 19
19#define STACK_SLOT_SIZE sizeof(int) 20#define STACK_SLOT_SIZE sizeof(int)
20 21
@@ -226,8 +227,8 @@ syscall_handler (struct intr_frame *f)
226 goto fail; 227 goto fail;
227 } 228 }
228 syscall_sp = sp; 229 syscall_sp = sp;
229 result = fp (sp, &segfault); 230 result = fp (sp, &segfault);
230 if (segfault) 231 if (segfault)
231 goto fail; 232 goto fail;
232 f->eax = result; 233 f->eax = result;
233 return; 234 return;
@@ -574,11 +575,64 @@ syscall_close (void *sp, bool *segfault)
574static int 575static int
575syscall_mmap (void *sp, bool *segfault) 576syscall_mmap (void *sp, bool *segfault)
576{ 577{
577 return 0; 578 int fd;
579 void *addr, *offset;
580 struct file *file, *file2;
581 off_t len;
582
583 /* get arguments */
584 if (! copy_from_user (&fd, STACK_ADDR (sp,1)) ||
585 ! copy_from_user (&addr, STACK_ADDR (sp, 2))) {
586 *segfault = true;
587 return -1;
588 }
589
590 /* address must be valid and page-aligned */
591 if (addr == NULL || pg_ofs (addr))
592 return -1;
593
594 /* file descriptors 0 and 1 are reserved */
595 if (fd == 0 || fd == 1)
596 return -1;
597
598 /* get file */
599 file = process_get_file (fd);
600 if (file == NULL)
601 return -1;
602
603 /* file length must be positiv */
604 len = file_length (file);
605 if (len <= 0)
606 return -1;
607
608 /* check if the pages don't overlap any existing pages */
609 offset = addr;
610 while(offset < addr + len)
611 {
612 if (page_table_fetch (&thread_current ()->page_table, offset))
613 return -1;
614 offset += PGSIZE;
615 }
616
617 process_lock_filesys ();
618 file2 = file_reopen (file);
619 process_unlock_filesys ();
620
621 return (file2 == NULL) ? -1 :
622 mmap_table_insert (&process_current()->mmap_table, addr, file2, len);
578} 623}
579 624
580static int 625static int
581syscall_munmap (void *sp, bool *segfault) 626syscall_munmap (void *sp, bool *segfault)
582{ 627{
628 mapid_t mapping;
629
630 /* get arguments */
631 if (! copy_from_user (&mapping, STACK_ADDR (sp,1))) {
632 *segfault = true;
633 return 0;
634 }
635
636 mmap_table_remove (&process_current()->mmap_table, mapping);
583 return 0; 637 return 0;
584} 638}