summaryrefslogtreecommitdiffstats
path: root/vm/mmap.c
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2012-06-21 16:47:23 +0200
committermanuel <manuel@mausz.at>2012-06-21 16:47:23 +0200
commite11b2ef0c606ab516a4344aeea1dbba22cb1fe5d (patch)
treeb4973f4dca916113c82a4a172f6f729d41cf4430 /vm/mmap.c
parente9e69def589375c3d0e51b532268b27d3d403bbf (diff)
downloadprogos-e11b2ef0c606ab516a4344aeea1dbba22cb1fe5d.tar.gz
progos-e11b2ef0c606ab516a4344aeea1dbba22cb1fe5d.tar.bz2
progos-e11b2ef0c606ab516a4344aeea1dbba22cb1fe5d.zip
initial implementation of memory mapped files
Diffstat (limited to 'vm/mmap.c')
-rw-r--r--vm/mmap.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/vm/mmap.c b/vm/mmap.c
new file mode 100644
index 0000000..9e7ae47
--- /dev/null
+++ b/vm/mmap.c
@@ -0,0 +1,116 @@
1#include <string.h>
2#include "filesys/file.h"
3#include "threads/thread.h"
4#include "threads/vaddr.h"
5#include "threads/malloc.h"
6#include "threads/palloc.h"
7#include "vm/mmap.h"
8#include "vm/page.h"
9
10static struct mmap_table_entry *mmap_table_get (struct mmap_table *table,
11 mapid_t mapid);
12
13/* initialize memory mapped files table */
14bool
15mmap_table_init (struct mmap_table *table)
16{
17 table->ids = palloc_get_page (PAL_ZERO);
18 if (table->ids == NULL)
19 return false;
20 table->id_cap = PGSIZE / sizeof (table->ids[0]);
21 table->id_free = 0;
22 table->id_max = -1;
23 return true;
24}
25
26/* frees the content of mmap table */
27void
28mmap_table_free (struct mmap_table *table)
29{
30 //TODO
31 palloc_free_page (table->ids);
32}
33
34/* inserts a new mmap entry in the mmap table
35 returns -1 if entry is invalid or already in the table */
36mapid_t
37mmap_table_insert (struct mmap_table *table, void *addr, struct file *file,
38 off_t len)
39{
40 off_t ofs = 0;
41 size_t page_read_bytes;
42 struct mmap_table_entry *mme;
43 mapid_t mapid;
44
45 /* no more entries left */
46 if (table->id_free >= table->id_cap)
47 return -1;
48
49 mme = malloc (sizeof *mme);
50 if (mme == NULL)
51 return -1;
52
53 mapid = table->id_free++;
54 mme->addr = addr;
55 mme->file = file;
56 table->ids[mapid] = mme;
57
58 /* create needed pages in page table */
59 while (len > 0)
60 {
61 page_read_bytes = (len < PGSIZE) ? len : PGSIZE;
62
63 if (!page_table_insert_segment (&thread_current ()->page_table, file, ofs,
64 addr, page_read_bytes, true))
65 return -1;
66
67 /* Advance. */
68 len -= PGSIZE;
69 ofs += page_read_bytes;
70 addr += PGSIZE;
71 }
72
73 /* update index of free/max mapid index */
74 if (mapid > table->id_max)
75 table->id_max = mapid;
76 while (table->ids[table->id_free] != NULL)
77 {
78 table->id_free++;
79 if (table->id_free >= table->id_cap)
80 break;
81 }
82
83 return mapid;
84}
85
86static struct mmap_table_entry *
87mmap_table_get (struct mmap_table *table, mapid_t mapid)
88{
89 if (mapid < 0 || mapid >= table->id_cap || !table->ids[mapid])
90 return NULL;
91 return table->ids[mapid];
92}
93
94bool
95mmap_table_remove (struct mmap_table *table, mapid_t mapid)
96{
97 struct mmap_table_entry *mme = mmap_table_get(table, mapid);
98 if (mme == NULL)
99 return false;
100
101 table->ids[mapid] = NULL;
102
103 //TODO
104
105 /* update index of free/max file descriptor index */
106 if (mapid < table->id_free)
107 table->id_free = mapid;
108 while (table->ids[table->id_max] == NULL)
109 {
110 table->id_max--;
111 if (table->id_max < 0)
112 break;
113 }
114
115 return true;
116}