summaryrefslogtreecommitdiffstats
path: root/vm/page.c
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2012-06-19 23:31:28 +0200
committermanuel <manuel@mausz.at>2012-06-19 23:31:28 +0200
commitabd273ce0a9ae9267f8b0a144ea9b56d8912f9b5 (patch)
tree15bf5622a6bf7665dfb53a3f557dfaa246f108aa /vm/page.c
parente88a8c4c379d721e9901752d440a05295087da11 (diff)
downloadprogos-abd273ce0a9ae9267f8b0a144ea9b56d8912f9b5.tar.gz
progos-abd273ce0a9ae9267f8b0a144ea9b56d8912f9b5.tar.bz2
progos-abd273ce0a9ae9267f8b0a144ea9b56d8912f9b5.zip
add dynamic stack growing
Diffstat (limited to 'vm/page.c')
-rw-r--r--vm/page.c76
1 files changed, 46 insertions, 30 deletions
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 @@
6#include "threads/palloc.h" 6#include "threads/palloc.h"
7#include "vm/page.h" 7#include "vm/page.h"
8 8
9static void page_table_entry_free (struct hash_elem *e, void *aux UNUSED);
10static unsigned page_table_hash (const struct hash_elem *e, void *aux UNUSED); 9static unsigned page_table_hash (const struct hash_elem *e, void *aux UNUSED);
11static bool page_table_cmp_less (const struct hash_elem *a, const struct hash_elem *b, 10static bool page_table_cmp_less (const struct hash_elem *a, const struct hash_elem *b,
12 void *aux UNUSED); 11 void *aux UNUSED);
12static void page_table_entry_free (struct hash_elem *e, void *aux UNUSED);
13static bool page_table_insert (struct hash *ht, struct page_table_entry *pte); 13static bool page_table_insert (struct hash *ht, struct page_table_entry *pte);
14static bool page_load_segment (struct page_table_entry *pte); 14static bool page_load_segment (struct page_table_entry *pte);
15static bool page_load_mmf (struct page_table_entry *pte); 15static bool page_load_mmf (struct page_table_entry *pte);
16 16
17/* initialize page table structure */
17void 18void
18page_table_init (struct hash *ht) 19page_table_init (struct hash *ht)
19{ 20{
20 hash_init (ht, page_table_hash, page_table_cmp_less, NULL); 21 hash_init (ht, page_table_hash, page_table_cmp_less, NULL);
21} 22}
22 23
23unsigned 24/* calulcates and returns the hash used as key of the hash/page table */
25static unsigned
24page_table_hash (const struct hash_elem *e, void *aux UNUSED) 26page_table_hash (const struct hash_elem *e, void *aux UNUSED)
25{ 27{
26 const struct page_table_entry *pte = hash_entry (e, struct page_table_entry, elem); 28 const struct page_table_entry *pte = hash_entry (e, struct page_table_entry, elem);
27 return hash_bytes (&pte->uvaddr, sizeof pte->uvaddr); 29 return hash_bytes (&pte->upage, sizeof pte->upage);
28} 30}
29 31
30bool 32/* page table comperator needed by the hash table implementation
33 returns true if A is less than B, or false if A is greater than
34 or equal to B */
35static bool
31page_table_cmp_less (const struct hash_elem *a, const struct hash_elem *b, 36page_table_cmp_less (const struct hash_elem *a, const struct hash_elem *b,
32 void *aux UNUSED) 37 void *aux UNUSED)
33{ 38{
34 const struct page_table_entry *pte1 = hash_entry (a, struct page_table_entry, elem); 39 const struct page_table_entry *pte1 = hash_entry (a, struct page_table_entry, elem);
35 const struct page_table_entry *pte2 = hash_entry (b, struct page_table_entry, elem); 40 const struct page_table_entry *pte2 = hash_entry (b, struct page_table_entry, elem);
36 return (pte1->uvaddr < pte2->uvaddr); 41 return (pte1->upage < pte2->upage);
37} 42}
38 43
44/* frees the content of page table */
39void 45void
40page_table_free (struct hash *ht) 46page_table_free (struct hash *ht)
41{ 47{
42 hash_destroy (ht, page_table_entry_free); 48 hash_destroy (ht, page_table_entry_free);
43} 49}
44 50
45void 51/* frees a single page table entry */
52static void
46page_table_entry_free (struct hash_elem *e, void *aux UNUSED) 53page_table_entry_free (struct hash_elem *e, void *aux UNUSED)
47{ 54{
48 struct page_table_entry *pte = hash_entry (e, struct page_table_entry, elem); 55 struct page_table_entry *pte = hash_entry (e, struct page_table_entry, elem);
49 free (pte); 56 free (pte);
50} 57}
51 58
52bool 59/* inserts a new entry into the page table
60 returns false if entry is invalid or already in the table */
61static bool
53page_table_insert (struct hash *ht, struct page_table_entry *pte) 62page_table_insert (struct hash *ht, struct page_table_entry *pte)
54{ 63{
55 if (pte == NULL) 64 if (pte == NULL)
@@ -57,6 +66,8 @@ page_table_insert (struct hash *ht, struct page_table_entry *pte)
57 return (hash_insert (ht, &pte->elem) == NULL); 66 return (hash_insert (ht, &pte->elem) == NULL);
58} 67}
59 68
69/* inserts a new entry of type segment into the page table
70 returns false if entry is invalid or already in the table */
60bool 71bool
61page_table_insert_segment (struct file *file, off_t ofs, uint8_t *upage, 72page_table_insert_segment (struct file *file, off_t ofs, uint8_t *upage,
62 uint32_t read_bytes, uint32_t zero_bytes, bool writable) 73 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,
65 if (pte == NULL) 76 if (pte == NULL)
66 return false; 77 return false;
67 78
68 pte->uvaddr = upage; 79 pte->upage = upage;
69 pte->type = PAGE_SEGMENT; 80 pte->type = PAGE_SEGMENT;
70 pte->loaded = false; 81 pte->loaded = false;
71 pte->segment.file = file; 82 pte->segment.file = file;
@@ -77,17 +88,20 @@ page_table_insert_segment (struct file *file, off_t ofs, uint8_t *upage,
77 return page_table_insert (&thread_current ()->page_table, pte); 88 return page_table_insert (&thread_current ()->page_table, pte);
78} 89}
79 90
91/* fetch an entry from the page table. returns NULL if not found */
80struct page_table_entry * 92struct page_table_entry *
81page_table_fetch (struct hash *ht, void *uvaddr) 93page_table_fetch (struct hash *ht, void *upage)
82{ 94{
83 struct page_table_entry pte; 95 struct page_table_entry pte;
84 struct hash_elem *e; 96 struct hash_elem *e;
85 97
86 pte.uvaddr = uvaddr; 98 pte.upage = upage;
87 e = hash_find (ht, &pte.elem); 99 e = hash_find (ht, &pte.elem);
88 return ((e != NULL) ? hash_entry (e, struct page_table_entry, elem) : NULL); 100 return ((e != NULL) ? hash_entry (e, struct page_table_entry, elem) : NULL);
89} 101}
90 102
103/* load the page referenced by the page table entry
104 returns true on success or already loaded, false otherwise */
91bool 105bool
92page_load (struct page_table_entry *pte) 106page_load (struct page_table_entry *pte)
93{ 107{
@@ -95,19 +109,20 @@ page_load (struct page_table_entry *pte)
95 return true; 109 return true;
96 110
97 switch (pte->type) 111 switch (pte->type)
98 { 112 {
99 case PAGE_SEGMENT: 113 case PAGE_SEGMENT:
100 return page_load_segment (pte); 114 return page_load_segment (pte);
101 case PAGE_MEMORY_MAPPED_FILE: 115 case PAGE_MEMORY_MAPPED_FILE:
102 return page_load_mmf (pte); 116 return page_load_mmf (pte);
103 default: 117 default:
104 ASSERT (false); 118 ASSERT (false);
105 break; 119 break;
106 } 120 }
107 return false; 121 return false;
108} 122}
109 123
110bool 124/* load the segment data page */
125static bool
111page_load_segment (struct page_table_entry *pte) 126page_load_segment (struct page_table_entry *pte)
112{ 127{
113 struct segment *data = &pte->segment; 128 struct segment *data = &pte->segment;
@@ -122,24 +137,25 @@ page_load_segment (struct page_table_entry *pte)
122 /* Load this page. */ 137 /* Load this page. */
123 if (file_read (data->file, kpage, data->read_bytes) 138 if (file_read (data->file, kpage, data->read_bytes)
124 != (int) data->read_bytes) 139 != (int) data->read_bytes)
125 { 140 {
126 palloc_free_page (kpage); 141 palloc_free_page (kpage);
127 return false; 142 return false;
128 } 143 }
129 memset (kpage + data->read_bytes, 0, data->zero_bytes); 144 memset (kpage + data->read_bytes, 0, data->zero_bytes);
130 145
131 /* Add the page to the process's address space. */ 146 /* Add the page to the process's address space. */
132 if (!process_install_page (pte->uvaddr, kpage, data->writable)) 147 if (!process_install_page (pte->upage, kpage, data->writable))
133 { 148 {
134 palloc_free_page (kpage); 149 palloc_free_page (kpage);
135 return false; 150 return false;
136 } 151 }
137 152
138 pte->loaded = true; 153 pte->loaded = true;
139 return true; 154 return true;
140} 155}
141 156
142bool 157/* load the memory mappged file page */
158static bool
143page_load_mmf (struct page_table_entry *pte) 159page_load_mmf (struct page_table_entry *pte)
144{ 160{
145 //TODO: implement 161 //TODO: implement