Implement implicitly unmapping all mmapped files when a process exits. Refactor to reduce duplication
This commit is contained in:
@@ -466,35 +466,12 @@ syscall_munmap (mapid_t mapping)
|
|||||||
/* Get the mmap entry from the mapping identifier. */
|
/* Get the mmap entry from the mapping identifier. */
|
||||||
struct mmap_entry *mmap = mmap_get (mapping);
|
struct mmap_entry *mmap = mmap_get (mapping);
|
||||||
|
|
||||||
/* Free all the pages associated with the mapping, writing back to the file
|
/* Delete the mmap entry from the hash table. */
|
||||||
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. */
|
|
||||||
hash_delete (&thread_current ()->mmap_files, &mmap->elem);
|
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,
|
/* Hashing function needed for the open_file table. Returns a hash for an entry,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "threads/malloc.h"
|
#include "threads/malloc.h"
|
||||||
#include "userprog/syscall.h"
|
#include "userprog/syscall.h"
|
||||||
#include "userprog/pagedir.h"
|
#include "userprog/pagedir.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
static unsigned mmap_hash (const struct hash_elem *e, void *aux);
|
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_,
|
static bool mmap_less (const struct hash_elem *a_, const struct hash_elem *b_,
|
||||||
@@ -85,9 +86,6 @@ mmap_unmap (struct mmap_entry *mmap)
|
|||||||
hash_delete (&thread_current ()->pages, &page->elem);
|
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);
|
file_close (mmap->file);
|
||||||
free (mmap);
|
free (mmap);
|
||||||
}
|
}
|
||||||
@@ -120,14 +118,13 @@ mmap_less (const struct hash_elem *a_, const struct hash_elem *b_,
|
|||||||
return a->mapping < b->mapping;
|
return a->mapping < b->mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleans up the mmap table for the current thread. Frees the memory allocated
|
/* Cleans up the mmap table for the current thread. Implicitly unmaps the mmap
|
||||||
for the mmap entry. */
|
entry, freeing pages and writing back to the file if necessary. */
|
||||||
static void
|
static void
|
||||||
mmap_cleanup (struct hash_elem *e, void *aux UNUSED)
|
mmap_cleanup (struct hash_elem *e, void *aux UNUSED)
|
||||||
{
|
{
|
||||||
struct mmap_entry *mmap = hash_entry (e, struct mmap_entry, elem);
|
struct mmap_entry *mmap = hash_entry (e, struct mmap_entry, elem);
|
||||||
file_close (mmap->file);
|
mmap_unmap (mmap);
|
||||||
free (mmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Updates the 'owner' thread's page table entry for virtual address 'upage'
|
/* Updates the 'owner' thread's page table entry for virtual address 'upage'
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ bool mmap_init (struct thread *t);
|
|||||||
struct mmap_entry *mmap_get (mapid_t mapping);
|
struct mmap_entry *mmap_get (mapid_t mapping);
|
||||||
struct mmap_entry *mmap_insert (struct file *file, void *upage);
|
struct mmap_entry *mmap_insert (struct file *file, void *upage);
|
||||||
void mmap_unmap (struct mmap_entry *mmap);
|
void mmap_unmap (struct mmap_entry *mmap);
|
||||||
|
void mmap_umap_all (void);
|
||||||
void mmap_destroy (void);
|
void mmap_destroy (void);
|
||||||
|
|
||||||
#endif /* vm/mmap.h */
|
#endif /* vm/mmap.h */
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ page_get (void *upage)
|
|||||||
|
|
||||||
struct hash_elem *e
|
struct hash_elem *e
|
||||||
= hash_find (&thread_current ()->pages, &fake_page_entry.elem);
|
= hash_find (&thread_current ()->pages, &fake_page_entry.elem);
|
||||||
|
|
||||||
if (e == NULL)
|
if (e == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user