diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 2a32cd3..2078c9f 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -466,35 +466,12 @@ syscall_munmap (mapid_t mapping) /* Get the mmap entry from the mapping identifier. */ struct mmap_entry *mmap = mmap_get (mapping); - /* Free all the pages associated with the mapping, writing back to the file - if necessary. */ - off_t length = file_length (mmap->file); - for (off_t ofs = 0; ofs < length; ofs += PGSIZE) - { - void *upage = mmap->upage + ofs; - - /* Get the SPT page entry for this page. */ - struct page_entry *page = page_get(upage); - if (page == NULL) - continue; - - /* Write the page back to the file if it is dirty. */ - if (pagedir_is_dirty (thread_current ()->pagedir, upage)) - { - lock_acquire (&filesys_lock); - file_write_at (mmap->file, upage, page->read_bytes, ofs); - lock_release (&filesys_lock); - } - - /* Remove the page from the supplemental page table. */ - hash_delete (&thread_current ()->pages, &page->elem); - } - - /* Remove the mapping from the mmap table. Close the file and free the mmap - entry. */ + /* Delete the mmap entry from the hash table. */ hash_delete (&thread_current ()->mmap_files, &mmap->elem); - file_close (mmap->file); - free(mmap); + + /* Unmap the mmap entry: free the pages and write back to the file if + necessary. NOTE. freeing and cleaning up is also handled by mmap_unmap. */ + mmap_unmap (mmap); } /* Hashing function needed for the open_file table. Returns a hash for an entry, diff --git a/src/vm/mmap.c b/src/vm/mmap.c index b3b16db..c34991d 100644 --- a/src/vm/mmap.c +++ b/src/vm/mmap.c @@ -4,6 +4,7 @@ #include "threads/malloc.h" #include "userprog/syscall.h" #include "userprog/pagedir.h" +#include static unsigned mmap_hash (const struct hash_elem *e, void *aux); static bool mmap_less (const struct hash_elem *a_, const struct hash_elem *b_, @@ -85,11 +86,8 @@ mmap_unmap (struct mmap_entry *mmap) hash_delete (&thread_current ()->pages, &page->elem); } - /* Remove the mapping from the mmap table. Close the file and free the mmap - entry. */ - hash_delete (&thread_current ()->mmap_files, &mmap->elem); file_close (mmap->file); - free(mmap); + free (mmap); } /* Destroys the mmap table for the current thread. Frees all the memory @@ -120,14 +118,13 @@ mmap_less (const struct hash_elem *a_, const struct hash_elem *b_, return a->mapping < b->mapping; } -/* Cleans up the mmap table for the current thread. Frees the memory allocated - for the mmap entry. */ +/* Cleans up the mmap table for the current thread. Implicitly unmaps the mmap + entry, freeing pages and writing back to the file if necessary. */ static void mmap_cleanup (struct hash_elem *e, void *aux UNUSED) { struct mmap_entry *mmap = hash_entry (e, struct mmap_entry, elem); - file_close (mmap->file); - free (mmap); + mmap_unmap (mmap); } /* Updates the 'owner' thread's page table entry for virtual address 'upage' diff --git a/src/vm/mmap.h b/src/vm/mmap.h index 593e070..cba21fc 100644 --- a/src/vm/mmap.h +++ b/src/vm/mmap.h @@ -21,6 +21,7 @@ bool mmap_init (struct thread *t); struct mmap_entry *mmap_get (mapid_t mapping); struct mmap_entry *mmap_insert (struct file *file, void *upage); void mmap_unmap (struct mmap_entry *mmap); +void mmap_umap_all (void); void mmap_destroy (void); #endif /* vm/mmap.h */ diff --git a/src/vm/page.c b/src/vm/page.c index 18f718e..c75fdcc 100644 --- a/src/vm/page.c +++ b/src/vm/page.c @@ -59,7 +59,6 @@ page_get (void *upage) struct hash_elem *e = hash_find (&thread_current ()->pages, &fake_page_entry.elem); - if (e == NULL) return NULL;