-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathuninit.c
68 lines (59 loc) · 2.08 KB
/
uninit.c
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
/* uninit.c: Implementation of uninitialized page.
*
* All of the pages are born as uninit page. When the first page fault occurs,
* the handler chain calls uninit_initialize (page->operations.swap_in).
* The uninit_initialize function transmutes the page into the specific page
* object (anon, file, page_cache), by initializing the page object,and calls
* initialization callback that passed from vm_alloc_page_with_initializer
* function.
* */
#include "vm/vm.h"
#include "vm/uninit.h"
static bool uninit_initialize (struct page *page, void *kva);
static void uninit_destroy (struct page *page);
/* DO NOT MODIFY this struct */
static const struct page_operations uninit_ops = {
.swap_in = uninit_initialize,
.swap_out = NULL,
.destroy = uninit_destroy,
.type = VM_UNINIT,
};
/* DO NOT MODIFY this function */
void
uninit_new (struct page *page, void *va, vm_initializer *init,
enum vm_type type, void *aux,
bool (*initializer)(struct page *, enum vm_type, void *)) {
ASSERT (page != NULL);
*page = (struct page) {
.operations = &uninit_ops,
.va = va,
.frame = NULL, /* no frame for now */
.uninit = (struct uninit_page) {
.init = init,
.type = type,
.aux = aux,
.page_initializer = initializer,
}
};
}
/* Initalize the page on first fault */
static bool
uninit_initialize (struct page *page, void *kva) {
struct uninit_page *uninit = &page->uninit;
/* Fetch first, page_initialize may overwrite the values */
vm_initializer *init = uninit->init;
void *aux = uninit->aux;
/* TODO: You may need to fix this function. */
return uninit->page_initializer (page, uninit->type, kva) &&
(init ? init (page, aux) : true);
}
/* Free the resources hold by uninit_page. Although most of pages are transmuted
* to other page objects, it is possible to have uninit pages when the process
* exit, which are never referenced during the execution.
* PAGE will be freed by the caller. */
static void
uninit_destroy (struct page *page) {
struct uninit_page *uninit UNUSED = &page->uninit;
/* TODO: Fill this function.
* TODO: If you don't have anything to do, just return. */
}