Update page_load to create and use the shared read-only pages of executables, w/ G

This commit is contained in:
sBubshait
2024-11-30 01:54:10 +00:00
parent f4910bdefb
commit 0b08893aaf
3 changed files with 49 additions and 8 deletions

View File

@@ -134,9 +134,12 @@ thread_start (void)
t))
PANIC ("Failed to initialise child results table for main thread.");
/* Initialise the shared files table and lock. */
if (!hash_init (&shared_files, shared_file_hash, shared_file_less, NULL))
PANIC ("Failed to initialise shared pages table.");
lock_init (&shared_files_lock);
/* Create the idle thread. */
struct semaphore idle_started;
sema_init (&idle_started, 0);

View File

@@ -3,9 +3,12 @@
#include "filesys/file.h"
#include "threads/malloc.h"
#include "threads/palloc.h"
#include "threads/vaddr.h"
#include "userprog/process.h"
#include "vm/frame.h"
static struct shared_page_entry *shared_page_insert (struct file *file,
void *upage, void *frame);
static struct shared_file_entry *shared_file_get (struct file *file);
static unsigned shared_page_hash (const struct hash_elem *e, void *aux UNUSED);
static bool shared_page_less (const struct hash_elem *a_,
@@ -73,6 +76,23 @@ page_get (void *upage)
bool
page_load (struct page_entry *page, bool writable)
{
/* If the page is read-only, we want to check if it is a shared page already
loaded into memory. If it is, we can just map the page to the frame. */
if (!page->writable)
{
ASSERT (page->read_bytes == PGSIZE);
struct shared_page_entry *shared_page =
shared_page_get (page->file, page->upage);
if (shared_page != NULL)
{
/* Map the page to the shared frame for this read-only portion. */
if (!install_page (page->upage, shared_page->frame, false))
return false;
}
}
/* Allocate a frame for the page. If a frame allocation fails, then
frame_alloc should try to evict a page. If it is still NULL, the OS
panics as this should not happen if eviction is working correctly. */
@@ -81,7 +101,7 @@ page_load (struct page_entry *page, bool writable)
PANIC ("Could not allocate a frame to load page into memory.");
/* Map the page to the frame. */
if (!install_page (page->upage, frame, writable))
if (!install_page (page->upage, frame, page->writable))
{
frame_free (frame);
return false;
@@ -100,6 +120,16 @@ page_load (struct page_entry *page, bool writable)
/* Zero out the remaining bytes in the frame. */
memset (frame + page->read_bytes, 0, page->zero_bytes);
/* If the page is read-only, we need to add it to the shared pages table. */
if (!page->writable)
{
if (shared_page_insert (page->file, page->upage, frame) == NULL)
{
frame_free (frame);
return false;
}
}
/* Mark the page as loaded successfully. */
return true;
}
@@ -190,21 +220,32 @@ shared_page_get (struct file *file, void *upage)
return hash_entry (e, struct shared_page_entry, elem);
}
struct shared_page_entry *
static struct shared_page_entry *
shared_page_insert (struct file *file, void *upage, void *frame)
{
struct shared_file_entry *shared_file = shared_file_get (file);
/* Allocate a new shared_page_entry first for easier error handling. */
struct shared_page_entry *shared_page
= malloc (sizeof (struct shared_page_entry));
if (shared_page == NULL)
return NULL;
/* 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;
{
free (shared_page);
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_page);
free (shared_file);
return NULL;
}
@@ -212,11 +253,6 @@ shared_page_insert (struct file *file, void *upage, void *frame)
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);

View File

@@ -2,9 +2,11 @@
#define VM_PAGE_H
#include "threads/thread.h"
#include "threads/synch.h"
#include "filesys/off_t.h"
struct hash shared_files;
struct lock shared_files_lock;
enum page_type {
PAGE_EXECUTABLE,