Skip to content

Commit

Permalink
[#124] Change supplemental page table from list to hash
Browse files Browse the repository at this point in the history
  • Loading branch information
hangpark committed May 11, 2017
1 parent f7bba13 commit da3af65
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 34 deletions.
71 changes: 40 additions & 31 deletions src/vm/page.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "vm/page.h"
#include <list.h>
#include <hash.h>
#include <string.h>
#include "threads/malloc.h"
#include "threads/thread.h"
Expand All @@ -8,7 +8,9 @@
#include "vm/frame.h"
#include "vm/swap.h"

static void suppl_pt_free_pte (struct suppl_pte *);
static hash_hash_func suppl_pt_hash;
static hash_less_func suppl_pt_less;
static hash_action_func suppl_pt_free_pte;

/* Creates and returns a new supplemental page table. */
struct suppl_pt *
Expand All @@ -18,7 +20,7 @@ suppl_pt_create (void)
if (pt == NULL)
return NULL;

list_init (&pt->list);
hash_init (&pt->hash, suppl_pt_hash, suppl_pt_less, NULL);

return pt;
}
Expand All @@ -30,14 +32,7 @@ suppl_pt_create (void)
void
suppl_pt_destroy (struct suppl_pt *pt)
{
struct list_elem *e;
for (e = list_begin (&pt->list); e != list_end (&pt->list);)
{
struct suppl_pte *pte = list_entry (e, struct suppl_pte, elem);
e = list_next (e);
suppl_pt_free_pte (pte);
}
free (pt);
hash_destroy (&pt->hash, suppl_pt_free_pte);
}

/* Adds a new supplemental page table entry of zero-fill with
Expand All @@ -57,7 +52,7 @@ suppl_pt_set_zero (void *upage)
pte->dirty = false;

struct suppl_pt *pt = thread_current ()->suppl_pt;
list_push_back (&pt->list, &pte->elem);
hash_insert (&pt->hash, &pte->elem);

return true;
}
Expand Down Expand Up @@ -85,7 +80,7 @@ suppl_pt_set_file (void *upage, struct file *file, off_t ofs,
pte->writable = writable;

struct suppl_pt *pt = thread_current ()->suppl_pt;
list_push_back (&pt->list, &pte->elem);
hash_insert (&pt->hash, &pte->elem);

return true;
}
Expand Down Expand Up @@ -166,7 +161,9 @@ suppl_pt_clear_page (void *upage)
{
struct suppl_pte *pte = suppl_pt_get_page (upage);
pagedir_clear_page (pte->pagedir, upage);
suppl_pt_free_pte (pte);
if (pte == NULL)
return;
suppl_pt_free_pte (&pte->elem, thread_current ()->suppl_pt);
}

/* Returns the supplemental page table entry associated with
Expand All @@ -176,15 +173,12 @@ struct suppl_pte *
suppl_pt_get_page (void *upage)
{
struct suppl_pt *pt = thread_current ()->suppl_pt;
struct list_elem *e;
for (e = list_begin (&pt->list); e != list_end (&pt->list);
e = list_next (e))
{
struct suppl_pte *pte = list_entry (e, struct suppl_pte, elem);
if (pte->upage == upage)
return pte;
}
return NULL;
struct suppl_pte pte;
struct hash_elem *e;

pte.upage = upage;
e = hash_find (&pt->hash, &pte.elem);
return e != NULL ? hash_entry (e, struct suppl_pte, elem) : NULL;
}

/* Updates dirty bit at the given supplemental page table entry
Expand All @@ -195,27 +189,42 @@ suppl_pt_update_dirty (struct suppl_pte *pte)
ASSERT (pte != NULL);

if (pte->kpage == NULL)
return;
return pte->dirty;

pte->dirty = pte->dirty || pagedir_is_dirty (pte->pagedir, pte->upage)
|| pagedir_is_dirty (pte->pagedir, pte->kpage);

return pte->dirty;
}

static unsigned
suppl_pt_hash (const struct hash_elem *e, void *aux UNUSED)
{
struct suppl_pte *pte = hash_entry (e, struct suppl_pte, elem);
return hash_bytes (&pte->upage, sizeof pte->upage);
}

static bool
suppl_pt_less (const struct hash_elem *e1, const struct hash_elem *e2,
void *aux UNUSED)
{
struct suppl_pte *pte1 = hash_entry (e1, struct suppl_pte, elem);
struct suppl_pte *pte2 = hash_entry (e2, struct suppl_pte, elem);
return pte1->upage < pte2->upage;
}

/* Frees a supplemental page table entry.
This also removes the frame table entry, but not frees
allocated page. */
This also removes the frame table entry if supplemental page
PT is given, but not frees allocated page. */
static void
suppl_pt_free_pte (struct suppl_pte *pte)
suppl_pt_free_pte (struct hash_elem *e, void *pt)
{
if (pte == NULL)
return;

struct suppl_pte *pte = hash_entry (e, struct suppl_pte, elem);
if (pte->kpage != NULL)
frame_remove (pte->kpage);
else if (pte->type == PAGE_SWAP)
swap_remove (pte->swap_index);
list_remove (&pte->elem);
if (pt != NULL)
hash_delete (&((struct suppl_pt *) pt)->hash, &pte->elem);
free (pte);
}
6 changes: 3 additions & 3 deletions src/vm/page.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef VM_PAGE_H
#define VM_PAGE_H

#include <list.h>
#include <hash.h>
#include "filesys/file.h"
#include "vm/swap.h"

Expand All @@ -16,7 +16,7 @@ enum page_type
/* Supplemental page table. */
struct suppl_pt
{
struct list list; /* List. */
struct hash hash; /* Hash table. */
};

/* Supplemental page table entry. */
Expand Down Expand Up @@ -44,7 +44,7 @@ struct suppl_pte
};
};

struct list_elem elem; /* List element. */
struct hash_elem elem; /* Hash element. */
};

struct suppl_pt *suppl_pt_create (void);
Expand Down
1 change: 1 addition & 0 deletions src/vm/swap.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
void swap_table_init (void);
bool swap_in (void *kpage, size_t idx);
size_t swap_out (void *kpage);
void swap_remove (size_t idx);

#endif /* vm/swap.h */

0 comments on commit da3af65

Please sign in to comment.