fix: do not leak when inserting the same page twice, just update
This commit is contained in:
@@ -292,7 +292,7 @@ fetch_page (void *upage, bool write)
|
|||||||
switch (page->type) {
|
switch (page->type) {
|
||||||
case PAGE_MMAP:
|
case PAGE_MMAP:
|
||||||
case PAGE_FILE:
|
case PAGE_FILE:
|
||||||
success = page_load_file (page, page->writable);
|
success = page_load_file (page);
|
||||||
if (success && page->type == PAGE_FILE)
|
if (success && page->type == PAGE_FILE)
|
||||||
{
|
{
|
||||||
hash_delete (&thread_current ()->pages, &page->elem);
|
hash_delete (&thread_current ()->pages, &page->elem);
|
||||||
|
|||||||
@@ -95,6 +95,16 @@ page_insert_file (struct file *file, off_t ofs, void *upage,
|
|||||||
uint32_t read_bytes, uint32_t zero_bytes, bool writable,
|
uint32_t read_bytes, uint32_t zero_bytes, bool writable,
|
||||||
enum page_type type)
|
enum page_type type)
|
||||||
{
|
{
|
||||||
|
/* If page exists, just update it. */
|
||||||
|
struct page_entry *existing = page_get (upage);
|
||||||
|
if (existing != NULL)
|
||||||
|
{
|
||||||
|
ASSERT (existing->read_bytes == read_bytes);
|
||||||
|
ASSERT (existing->zero_bytes == zero_bytes);
|
||||||
|
existing->writable = existing->writable || writable;
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
struct page_entry *page = malloc(sizeof (struct page_entry));
|
struct page_entry *page = malloc(sizeof (struct page_entry));
|
||||||
if (page == NULL)
|
if (page == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -30,16 +30,14 @@ struct page_entry {
|
|||||||
struct hash_elem elem; /* An elem for the hash table. */
|
struct hash_elem elem; /* An elem for the hash table. */
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned page_hash (const struct hash_elem *e, void *aux);
|
bool init_pages (struct hash *pages);
|
||||||
bool page_less (const struct hash_elem *a_, const struct hash_elem *b_,
|
|
||||||
void *aux);
|
|
||||||
struct page_entry *page_insert_swapped (void *upage, void* kpage,
|
struct page_entry *page_insert_swapped (void *upage, void* kpage,
|
||||||
struct thread *owner);
|
struct thread *owner);
|
||||||
struct page_entry *page_insert_file (struct file *file, off_t ofs, void *upage,
|
struct page_entry *page_insert_file (struct file *file, off_t ofs, void *upage,
|
||||||
uint32_t read_bytes, uint32_t zero_bytes,
|
uint32_t read_bytes, uint32_t zero_bytes,
|
||||||
bool writable, enum page_type);
|
bool writable, enum page_type);
|
||||||
struct page_entry *page_get (void *upage);
|
struct page_entry *page_get (void *upage);
|
||||||
bool page_load_file (struct page_entry *page, bool writable);
|
bool page_load_file (struct page_entry *page);
|
||||||
void page_cleanup (struct hash_elem *e, void *aux);
|
void page_cleanup (struct hash_elem *e, void *aux);
|
||||||
|
|
||||||
bool page_in_swap (struct thread *, void *);
|
bool page_in_swap (struct thread *, void *);
|
||||||
|
|||||||
Reference in New Issue
Block a user