Add data structures for shared executable files along with helper methods for them, w/ G

This commit is contained in:
sBubshait
2024-11-30 01:15:50 +00:00
parent 8047c65227
commit ba72345f96
3 changed files with 131 additions and 9 deletions

View File

@@ -149,14 +149,6 @@ page_fault (struct intr_frame *f)
write = (f->error_code & PF_W) != 0; write = (f->error_code & PF_W) != 0;
user = (f->error_code & PF_U) != 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 /* 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 just need to be lazily loaded. So, we check our SPT to see if the page
is expected to have data loaded in memory. */ is expected to have data loaded in memory. */

View File

@@ -7,6 +7,10 @@
#include "userprog/process.h" #include "userprog/process.h"
#include "vm/frame.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, /* Hashing function needed for the SPT table. Returns a hash for an entry,
based on its upage. */ based on its upage. */
unsigned unsigned
@@ -108,6 +112,117 @@ page_cleanup (struct hash_elem *e, void *aux UNUSED)
free (hash_entry (e, struct page_entry, elem)); 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' /* 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 to have a present bit of 0 and stores the specified swap slot value in the
entry for later retrieval from disk. */ entry for later retrieval from disk. */

View File

@@ -23,6 +23,21 @@ struct page_entry {
struct hash_elem elem; /* An elem for the hash table. */ 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); unsigned page_hash (const struct hash_elem *e, void *aux);
bool page_less (const struct hash_elem *a_, const struct hash_elem *b_, bool page_less (const struct hash_elem *a_, const struct hash_elem *b_,
void *aux); void *aux);