diff --git a/src/userprog/process.c b/src/userprog/process.c index aa5091c..acc711d 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -24,6 +24,7 @@ #include "threads/vaddr.h" #include "threads/synch.h" #include "devices/timer.h" +#include "vm/page.h" #ifdef VM #include "vm/frame.h" #endif @@ -364,6 +365,7 @@ process_exit (void) /* Clean up all open files */ hash_destroy (&cur->open_files, fd_cleanup); + hash_destroy (&cur->pages, page_cleanup); /* Close the executable file, implicitly allowing it to be written to. */ if (cur->exec_file != NULL) diff --git a/src/vm/page.c b/src/vm/page.c index 9ed026f..9ff0ae3 100644 --- a/src/vm/page.c +++ b/src/vm/page.c @@ -1,4 +1,5 @@ #include "page.h" +#include "threads/malloc.h" /* Hashing function needed for the SPT table. Returns a hash for an entry, based on its upage. */ @@ -12,13 +13,60 @@ page_hash (const struct hash_elem *e, UNUSED void *aux) /* Comparator function for the SPT table. Compares two entries based on their upages. */ bool -page_less (const struct hash_elem *a_, const struct hash_elem *b_, UNUSED void *aux) +page_less (const struct hash_elem *a_, const struct hash_elem *b_, + void *aux UNUSED) { const struct page_entry *a = hash_entry (a_, struct page_entry, elem); const struct page_entry *b = hash_entry (b_, struct page_entry, elem); + return a->upage < b->upage; } +/* Allocate and insert a new page entry into the thread's page table. */ +struct page_entry * +page_insert (struct file *file, off_t ofs, void *upage, uint32_t read_bytes, + uint32_t zero_bytes, bool writable, enum page_type type) +{ + struct page_entry *page = malloc(sizeof (struct page_entry)); + if (page == NULL) + return NULL; + + page->file = file; + page->offset = ofs; + page->upage = upage; + page->read_bytes = read_bytes; + page->zero_bytes = zero_bytes; + page->writable = writable; + page->type = type; + + hash_insert (&thread_current ()->pages, &page->elem); + return page; +} + +/* Gets a page_entry from the starting address of the page. Returns NULL if no + such page_entry exists in the hash map.*/ +static struct page_entry * +page_get (void *upage) +{ + struct page_entry fake_page_entry; + fake_page_entry.upage = upage; + + struct hash_elem *e + = hash_find (&thread_current ()->pages, &fake_page_entry.elem); + + if (e == NULL) + return NULL; + + return hash_entry (e, struct page_entry, elem); +} + +/* Function to clean up a page_entry. Given the elem of that page_entry, frees + the page_entry itself. */ +void +page_cleanup (struct hash_elem *e, void *aux UNUSED) +{ + free (hash_entry (e, struct page_entry, elem)); +} /* Updates the 'owner' thread's page table entry for virtual address 'upage' to have a present bit of 0 and stores the specified swap slot value in the diff --git a/src/vm/page.h b/src/vm/page.h index 81a80ba..d075a13 100644 --- a/src/vm/page.h +++ b/src/vm/page.h @@ -24,8 +24,12 @@ struct page_entry { }; unsigned page_hash (const struct hash_elem *e, void *aux); -bool page_less (const struct hash_elem *a_, const struct hash_elem *b_, void *aux); - +bool page_less (const struct hash_elem *a_, const struct hash_elem *b_, + void *aux); +struct page_entry *page_insert (struct file *file, off_t ofs, void *upage, + uint32_t read_bytes, uint32_t zero_bytes, + bool writable, enum page_type type); +void page_cleanup (struct hash_elem *e, void *aux); void page_set_swap (struct thread *, void *, size_t); size_t page_get_swap (struct thread *, void *);