From abd273ce0a9ae9267f8b0a144ea9b56d8912f9b5 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 19 Jun 2012 23:31:28 +0200 Subject: add dynamic stack growing --- vm/page.c | 76 ++++++++++++++++++++++++++++++++++++++------------------------- vm/page.h | 35 +++++++++++++++-------------- 2 files changed, 64 insertions(+), 47 deletions(-) (limited to 'vm') diff --git a/vm/page.c b/vm/page.c index fa2433d..336353e 100644 --- a/vm/page.c +++ b/vm/page.c @@ -6,50 +6,59 @@ #include "threads/palloc.h" #include "vm/page.h" -static void page_table_entry_free (struct hash_elem *e, void *aux UNUSED); static unsigned page_table_hash (const struct hash_elem *e, void *aux UNUSED); static bool page_table_cmp_less (const struct hash_elem *a, const struct hash_elem *b, void *aux UNUSED); +static void page_table_entry_free (struct hash_elem *e, void *aux UNUSED); static bool page_table_insert (struct hash *ht, struct page_table_entry *pte); static bool page_load_segment (struct page_table_entry *pte); static bool page_load_mmf (struct page_table_entry *pte); +/* initialize page table structure */ void page_table_init (struct hash *ht) { hash_init (ht, page_table_hash, page_table_cmp_less, NULL); } -unsigned +/* calulcates and returns the hash used as key of the hash/page table */ +static unsigned page_table_hash (const struct hash_elem *e, void *aux UNUSED) { const struct page_table_entry *pte = hash_entry (e, struct page_table_entry, elem); - return hash_bytes (&pte->uvaddr, sizeof pte->uvaddr); + return hash_bytes (&pte->upage, sizeof pte->upage); } -bool +/* page table comperator needed by the hash table implementation + returns true if A is less than B, or false if A is greater than + or equal to B */ +static bool page_table_cmp_less (const struct hash_elem *a, const struct hash_elem *b, void *aux UNUSED) { const struct page_table_entry *pte1 = hash_entry (a, struct page_table_entry, elem); const struct page_table_entry *pte2 = hash_entry (b, struct page_table_entry, elem); - return (pte1->uvaddr < pte2->uvaddr); + return (pte1->upage < pte2->upage); } +/* frees the content of page table */ void page_table_free (struct hash *ht) { hash_destroy (ht, page_table_entry_free); } -void +/* frees a single page table entry */ +static void page_table_entry_free (struct hash_elem *e, void *aux UNUSED) { struct page_table_entry *pte = hash_entry (e, struct page_table_entry, elem); free (pte); } -bool +/* inserts a new entry into the page table + returns false if entry is invalid or already in the table */ +static bool page_table_insert (struct hash *ht, struct page_table_entry *pte) { if (pte == NULL) @@ -57,6 +66,8 @@ page_table_insert (struct hash *ht, struct page_table_entry *pte) return (hash_insert (ht, &pte->elem) == NULL); } +/* inserts a new entry of type segment into the page table + returns false if entry is invalid or already in the table */ bool page_table_insert_segment (struct file *file, off_t ofs, uint8_t *upage, uint32_t read_bytes, uint32_t zero_bytes, bool writable) @@ -65,7 +76,7 @@ page_table_insert_segment (struct file *file, off_t ofs, uint8_t *upage, if (pte == NULL) return false; - pte->uvaddr = upage; + pte->upage = upage; pte->type = PAGE_SEGMENT; pte->loaded = false; pte->segment.file = file; @@ -77,17 +88,20 @@ page_table_insert_segment (struct file *file, off_t ofs, uint8_t *upage, return page_table_insert (&thread_current ()->page_table, pte); } +/* fetch an entry from the page table. returns NULL if not found */ struct page_table_entry * -page_table_fetch (struct hash *ht, void *uvaddr) +page_table_fetch (struct hash *ht, void *upage) { struct page_table_entry pte; struct hash_elem *e; - pte.uvaddr = uvaddr; + pte.upage = upage; e = hash_find (ht, &pte.elem); return ((e != NULL) ? hash_entry (e, struct page_table_entry, elem) : NULL); } +/* load the page referenced by the page table entry + returns true on success or already loaded, false otherwise */ bool page_load (struct page_table_entry *pte) { @@ -95,19 +109,20 @@ page_load (struct page_table_entry *pte) return true; switch (pte->type) - { - case PAGE_SEGMENT: - return page_load_segment (pte); - case PAGE_MEMORY_MAPPED_FILE: - return page_load_mmf (pte); - default: - ASSERT (false); - break; - } + { + case PAGE_SEGMENT: + return page_load_segment (pte); + case PAGE_MEMORY_MAPPED_FILE: + return page_load_mmf (pte); + default: + ASSERT (false); + break; + } return false; } -bool +/* load the segment data page */ +static bool page_load_segment (struct page_table_entry *pte) { struct segment *data = &pte->segment; @@ -122,24 +137,25 @@ page_load_segment (struct page_table_entry *pte) /* Load this page. */ if (file_read (data->file, kpage, data->read_bytes) != (int) data->read_bytes) - { - palloc_free_page (kpage); - return false; - } + { + palloc_free_page (kpage); + return false; + } memset (kpage + data->read_bytes, 0, data->zero_bytes); /* Add the page to the process's address space. */ - if (!process_install_page (pte->uvaddr, kpage, data->writable)) - { - palloc_free_page (kpage); - return false; - } + if (!process_install_page (pte->upage, kpage, data->writable)) + { + palloc_free_page (kpage); + return false; + } pte->loaded = true; return true; } -bool +/* load the memory mappged file page */ +static bool page_load_mmf (struct page_table_entry *pte) { //TODO: implement diff --git a/vm/page.h b/vm/page.h index 29159fb..9cea048 100644 --- a/vm/page.h +++ b/vm/page.h @@ -8,32 +8,33 @@ /* supplemental page table entry */ struct page_table_entry { - void *uvaddr; - bool loaded; + void *upage; /* virtual address of page */ + bool loaded; /* indicates if page is loaded */ enum - { - PAGE_SEGMENT, - PAGE_MEMORY_MAPPED_FILE, - } type; + { + PAGE_SEGMENT, + PAGE_MEMORY_MAPPED_FILE, + } type; /* type of page */ union - { - struct segment { - struct file *file; - off_t ofs; - uint32_t read_bytes; - uint32_t zero_bytes; - bool writable; - } segment; - }; + /* structure needed for lazy loading of data segments */ + struct segment + { + struct file *file; + off_t ofs; + uint32_t read_bytes; + uint32_t zero_bytes; + bool writable; + } segment; + }; - struct hash_elem elem; + struct hash_elem elem; /* Hash element. */ }; void page_table_init (struct hash *ht); void page_table_free (struct hash *ht); -struct page_table_entry *page_table_fetch (struct hash *ht, void *uvaddr); +struct page_table_entry *page_table_fetch (struct hash *ht, void *upage); bool page_table_insert_segment (struct file *file, off_t ofs, uint8_t *upage, uint32_t read_bytes, uint32_t zero_bytes, bool writable); bool page_load (struct page_table_entry *pte); -- cgit v1.2.3