From ba72345f964ad04aa97ced6e0044d26181a41b51 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Sat, 30 Nov 2024 01:15:50 +0000 Subject: [PATCH] Add data structures for shared executable files along with helper methods for them, w/ G --- src/userprog/exception.c | 8 --- src/vm/page.c | 117 ++++++++++++++++++++++++++++++++++++++- src/vm/page.h | 15 +++++ 3 files changed, 131 insertions(+), 9 deletions(-) diff --git a/src/userprog/exception.c b/src/userprog/exception.c index 1e3ccc0..f4aa2fe 100644 --- a/src/userprog/exception.c +++ b/src/userprog/exception.c @@ -149,14 +149,6 @@ page_fault (struct intr_frame *f) write = (f->error_code & PF_W) != 0; user = (f->error_code & PF_U) != 0; - if (!user) - { - f->eip = (void *)f->eax; - f->eax = 0xffffffff; - return; - } - - /* If the fault address is in a user page that is not present, then it might just need to be lazily loaded. So, we check our SPT to see if the page is expected to have data loaded in memory. */ diff --git a/src/vm/page.c b/src/vm/page.c index 010bd9d..f21a3a7 100644 --- a/src/vm/page.c +++ b/src/vm/page.c @@ -7,6 +7,10 @@ #include "userprog/process.h" #include "vm/frame.h" +static struct hash shared_files; + +static struct shared_file_entry *shared_file_get (struct file *file); + /* Hashing function needed for the SPT table. Returns a hash for an entry, based on its upage. */ unsigned @@ -108,6 +112,117 @@ page_cleanup (struct hash_elem *e, void *aux UNUSED) free (hash_entry (e, struct page_entry, elem)); } +/* Hashing function needed for the shared_file table. Returns a hash for an + entry based on its file pointer. */ +unsigned +shared_file_hash (const struct hash_elem *e, void *aux UNUSED) +{ + return file_hash (hash_entry (e, struct shared_file_entry, elem)->file); +} + +/* Less function needed for the shared_file table. */ +bool +shared_file_less (const struct hash_elem *a_, const struct hash_elem *b_, + void *aux UNUSED) +{ + const struct shared_file_entry *a = hash_entry (a_, struct shared_file_entry, + elem); + const struct shared_file_entry *b = hash_entry (b_, struct shared_file_entry, + elem); + + return file_compare (a->file, b->file); +} + +/* Hashing function needed for the shared pages table. Returns a hash for an + entry based on its user virtual address (upage) pointer. */ +unsigned +shared_page_hash (const struct hash_elem *e, void *aux UNUSED) +{ + return hash_ptr (hash_entry (e, struct shared_page_entry, elem)->upage); +} + +/* Less function needed for the shared pages table. */ +bool +shared_page_less (const struct hash_elem *a_, const struct hash_elem *b_, + void *aux UNUSED) +{ + const struct shared_page_entry *a = hash_entry (a_, struct shared_page_entry, + elem); + const struct shared_page_entry *b = hash_entry (b_, struct shared_page_entry, + elem); + + return a->upage < b->upage; +} + +static struct shared_file_entry * +shared_file_get (struct file *file) +{ + struct shared_file_entry fake_shared_file; + fake_shared_file.file = file; + + struct hash_elem *e = hash_find (&shared_files, &fake_shared_file.elem); + + if (e == NULL) + return NULL; + + return hash_entry (e, struct shared_file_entry, elem); +} + +/* Gets a shared_page_entry from the shared_pages table using the file and upage + of the page. Returns NULL if no such page_entry exists in the hash map.*/ +struct shared_page_entry * +shared_page_get (struct file *file, void *upage) +{ + /* Search first for the file within the shared_pages structure */ + struct shared_file_entry *shared_file = shared_file_get (file); + if (shared_file == NULL) + return NULL; + + /* Search for the page within the shared_file's hash table */ + struct shared_page_entry fake_shared_page_entry; + fake_shared_page_entry.upage = upage; + + struct hash_elem *e = hash_find (&shared_file->pages, &fake_shared_page_entry.elem); + + if (e == NULL) + return NULL; + + return hash_entry (e, struct shared_page_entry, elem); +} + +struct shared_page_entry * +shared_page_insert (struct file *file, void *upage, void *frame) +{ + struct shared_file_entry *shared_file = shared_file_get (file); + /* If shared file doesn't exist in table, also create it. */ + if (shared_file == NULL) + { + shared_file = malloc (sizeof (struct shared_file_entry)); + if (shared_file == NULL) + return NULL; + + shared_file->file = file; + shared_file->ref_count = 0; + if (!hash_init (&shared_file->pages, shared_page_hash, shared_page_less, NULL)) + { + free (shared_file); + return NULL; + } + + hash_insert (&shared_files, &shared_file->elem); + } + + struct shared_page_entry *shared_page + = malloc (sizeof (struct shared_page_entry)); + if (shared_page == NULL) + return NULL; + + shared_page->upage = upage; + shared_page->frame = frame; + hash_insert (&shared_file->pages, &shared_page->elem); + return shared_page; +} + /* 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 entry for later retrieval from disk. */ @@ -124,4 +239,4 @@ size_t page_get_swap (struct thread *owner, void *upage) { -} \ No newline at end of file +} diff --git a/src/vm/page.h b/src/vm/page.h index 481f219..6a9ffe3 100644 --- a/src/vm/page.h +++ b/src/vm/page.h @@ -23,6 +23,21 @@ struct page_entry { struct hash_elem elem; /* An elem for the hash table. */ }; +struct shared_file_entry { + struct file *file; /* Pointer to the file. */ + struct hash pages; + int ref_count; + + struct hash_elem elem; +}; + +struct shared_page_entry { + void *upage; + void *frame; + + struct hash_elem elem; +}; + 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);