From e11b2ef0c606ab516a4344aeea1dbba22cb1fe5d Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 21 Jun 2012 16:47:23 +0200 Subject: initial implementation of memory mapped files --- userprog/process.c | 18 ++++++++++++++-- userprog/process.h | 2 ++ userprog/syscall.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 76 insertions(+), 6 deletions(-) (limited to 'userprog') 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) thread->process = process; page_table_init (&thread->page_table); + if (!mmap_table_init (&process->mmap_table)) + goto signal; /* Initialize interrupt frame and load executable. */ memset (&if_, 0, sizeof if_); @@ -149,6 +151,14 @@ start_process (void *aux) /* If process startup failed, quit. */ if (thread->process == NULL) { if (process != NULL) { + //TODO: free mmap table + page table? + + /* close/free memory mapped files */ + //mmap_table_free (&process->mmap_table); + + /* free page table */ + //page_table_free (&thread->page_table); + if (process->fd_table.fds != NULL) palloc_free_page (process->fd_table.fds); palloc_free_page (process); @@ -232,6 +242,9 @@ process_exit (void) lock_release (&filesys_lock); } + /* close/free memory mapped files */ + mmap_table_free (&proc->mmap_table); + int fd; for (fd = 2; fd <= proc->fd_table.fd_max; fd++) { process_close_file (fd); @@ -254,6 +267,7 @@ process_exit (void) pagedir_destroy (pd); } + /* free page table */ page_table_free (&thread->page_table); /* 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, size_t page_zero_bytes = PGSIZE - page_read_bytes; /* add segment to page table for on demand loading */ - if (!page_table_insert_segment (file, ofs, upage, page_read_bytes, - page_zero_bytes, writable)) + if (!page_table_insert_segment (&thread_current ()->page_table, file, ofs, + upage, page_read_bytes, writable)) return false; /* 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 @@ #define USERPROG_PROCESS_H #include "threads/thread.h" +#include "vm/mmap.h" #define STACK_SIZE (1 << 23) /* 8MB maximum stack size */ @@ -27,6 +28,7 @@ struct process { /* files */ struct file *executable; /* Loaded executable, if any. */ struct fd_table fd_table; /* File descriptor table */ + struct mmap_table mmap_table; /* Memory mapped files table */ /* Owned by syscall.c */ 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 @@ #include "userprog/pagedir.h" #include "userprog/process.h" #include "userprog/syscall.h" -#include "lib/user/syscall.h" +#include "vm/mmap.h" +#include "vm/page.h" #define STACK_SLOT_SIZE sizeof(int) @@ -226,8 +227,8 @@ syscall_handler (struct intr_frame *f) goto fail; } syscall_sp = sp; - result = fp (sp, &segfault); - if (segfault) + result = fp (sp, &segfault); + if (segfault) goto fail; f->eax = result; return; @@ -574,11 +575,64 @@ syscall_close (void *sp, bool *segfault) static int syscall_mmap (void *sp, bool *segfault) { - return 0; + int fd; + void *addr, *offset; + struct file *file, *file2; + off_t len; + + /* get arguments */ + if (! copy_from_user (&fd, STACK_ADDR (sp,1)) || + ! copy_from_user (&addr, STACK_ADDR (sp, 2))) { + *segfault = true; + return -1; + } + + /* address must be valid and page-aligned */ + if (addr == NULL || pg_ofs (addr)) + return -1; + + /* file descriptors 0 and 1 are reserved */ + if (fd == 0 || fd == 1) + return -1; + + /* get file */ + file = process_get_file (fd); + if (file == NULL) + return -1; + + /* file length must be positiv */ + len = file_length (file); + if (len <= 0) + return -1; + + /* check if the pages don't overlap any existing pages */ + offset = addr; + while(offset < addr + len) + { + if (page_table_fetch (&thread_current ()->page_table, offset)) + return -1; + offset += PGSIZE; + } + + process_lock_filesys (); + file2 = file_reopen (file); + process_unlock_filesys (); + + return (file2 == NULL) ? -1 : + mmap_table_insert (&process_current()->mmap_table, addr, file2, len); } static int syscall_munmap (void *sp, bool *segfault) { + mapid_t mapping; + + /* get arguments */ + if (! copy_from_user (&mapping, STACK_ADDR (sp,1))) { + *segfault = true; + return 0; + } + + mmap_table_remove (&process_current()->mmap_table, mapping); return 0; } -- cgit v1.2.3