This repository was archived by the owner on Aug 18, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathunit_vm.c
More file actions
182 lines (141 loc) · 6.26 KB
/
Copy pathunit_vm.c
File metadata and controls
182 lines (141 loc) · 6.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#ifndef ACUTEST
#define ACUTEST
#include "acutest.h"
#endif
#include "paging.h"
#include "paging_add.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#define UNIT_VM
#include "unit.c"
void test_map_vm_small() {
// Allocate 128 bytes of memory to serve as our store - only one frame!
void *store = malloc(1<<7);
// Initialise our mapping table
void* table = pt_init();
// Add some basic mappings to the table
map_page_to_frame(table, 0, 0, false, false);
map_page_to_frame(table, 1, 0, false, false);
TEST_CHECK(!pt_error(table));
// Try reading from page 0.
char text[] = "Hello, world!";
store_data(table, store, text, 0x0000, sizeof(text));
// Then try reading from page 1. This should evict page 0 to disk.
char buffer[128] = "";
read_data(table, store, buffer, 0x0080, sizeof(buffer));
// Then try re-reading from page 0. This should fault page 0 back into memory.
read_data(table, store, buffer, 0x0000, sizeof(buffer));
TEST_CHECK(strcmp(text, buffer) == 0);
pt_free(table);
free(store);
}
void test_demand_paging() {
// Allocate 32 KiB of memory to serve as our store
void *store = malloc(1<<15);
// Initialise our mapping table
void* table = pt_init();
// Add some basic mappings to the table
map_page_to_frame(table, 0, 4, true, false);
map_page_to_frame(table, 1, 3, true, false);
map_page_to_frame(table, 2, 0, true, false);
map_page_to_frame(table, 3, 2, true, false);
map_page_to_frame(table, 4, 1, true, false);
char text[] = "It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of light, it was the season of darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to heaven, we were all going direct the other way–in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.";
// Write the text to the virtual memory disk file.
// This should be page faulted from the disk when we first read the data.
FILE* vm_file = fopen("./vm.bin", "wb");
fwrite(text, 1, sizeof(text), vm_file);
fclose(vm_file);
char buffer[length(text)] = {0};
read_data(table, store, buffer, 0, length(text));
TEST_CHECK(strcmp(buffer, text) == 0);
TEST_CHECK(!pt_error(table));
pt_free(table);
free(store);
}
// Clone of the test_fib function, but with all the pages mapped to the same frame so
// they need to be swapped out.
void test_fib_vm() {
// Allocate 128 bytes of memory to serve as our store - only one frame!
void *store = malloc(1<<7);
// Initialise our mapping table
void *table = pt_init();
// Add some basic mappings to the table
map_page_to_frame(table, 0, 0, false, false);
map_page_to_frame(table, 1, 0, false, false);
map_page_to_frame(table, 2, 0, false, false);
map_page_to_frame(table, 3, 0, false, false);
uint64_t init = 1;
store_data(table, store, &init, 0, sizeof(uint64_t));
store_data(table, store, &init, sizeof(uint64_t), sizeof(uint64_t));
for(int i = 2; i < 64; i++) {
uint64_t a = 0;
read_data(table, store, &a, (i-2) * sizeof(uint64_t), sizeof(uint64_t));
uint64_t b = 0;
read_data(table, store, &b, (i-1) * sizeof(uint64_t), sizeof(uint64_t));
uint64_t c = a + b;
store_data(table, store, &c, i * sizeof(uint64_t), sizeof(uint64_t));
}
uint64_t data[64] = {0};
read_data(table, store, &data, 0, 64 * sizeof(uint64_t));
for (int i = 0; i < 64; i++) {
printf("%lu, ", data[i]);
}
TEST_CHECK(!pt_error(table));
pt_free(table);
free(store);
}
// Clone of the test_cat function, but with all the pages mapped to the same frame so
// they need to be swapped out.
void test_cat_vm() {
// Allocate 128 bytes of memory to serve as our store - only one frame!
void *store = malloc(1<<7);
// Initialise our mapping table
void *table = pt_init();
// Add some basic mappings to the table
map_page_to_frame(table, 0, 0, false, false);
map_page_to_frame(table, 1, 0, false, false);
map_page_to_frame(table, 2, 0, false, false);
map_page_to_frame(table, 3, 0, false, false);
map_page_to_frame(table, 4, 0, false, false);
map_page_to_frame(table, 5, 0, false, false);
map_page_to_frame(table, 6, 0, false, false);
map_page_to_frame(table, 7, 0, false, false);
char text1[] = "It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of light, it was the season of darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, ";
char text2[] = "we were all going direct to heaven, we were all going direct the other way–in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.";
store_data(table, store, text1, 0x0000, length(text1));
store_data(table, store, text2, 0x0200, length(text2));
int error = page_cat(table, store, 0x0000, 0x0200);
TEST_CHECK(!error);
TEST_CHECK(!pt_error(table));
char buffer[1024] = {0};
read_data(table, store, buffer, 0x0000, 1024);
char text[1024] = {0};
strcpy(text, text1);
strcat(text, text2);
printf("\n%s\n", buffer);
TEST_CHECK(strcmp(text, buffer) == 0);
pt_free(table);
free(store);
}
TEST_LIST = {
{"init", test_init},
{"map", test_map},
{"translate", test_translate},
{"translate_illegal", test_translate_illegal},
{"unmap", test_unmap},
{"alloc_small", test_alloc_small},
{"alloc_larger", test_alloc_larger},
{"store_illegal", test_store_illegal},
{"read_illegal", test_read_illegal},
{"fib", test_fib},
{"cat", test_cat},
{"write_protection", test_write_protection},
{"map_vm_small", test_map_vm_small},
{"demand_paging", test_demand_paging},
{"fib_vm", test_fib_vm},
{"cat_vm", test_cat_vm},
{NULL, NULL}
};