-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathk-alloc.cc
114 lines (101 loc) · 3.08 KB
/
k-alloc.cc
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
#include "kernel.hh"
#include "k-lock.hh"
static spinlock page_lock;
static uintptr_t next_free_pa;
// init_kalloc
// Initialize stuff needed by `kalloc`. Called from `init_hardware`,
// after `physical_ranges` is initialized.
void init_kalloc() {
// do nothing for now
}
// kalloc(sz)
// Allocate and return a pointer to at least `sz` contiguous bytes of
// memory. Returns `nullptr` if `sz == 0` or on failure.
//
// The caller should initialize the returned memory before using it.
// The handout allocator sets returned memory to 0xCC (this corresponds
// to the x86 `int3` instruction and may help you debug).
//
// If `sz` is a multiple of `PAGESIZE`, the returned pointer is guaranteed
// to be page-aligned.
//
// The handout code does not free memory and allocates memory in units
// of pages.
void* kalloc(size_t sz) {
if (sz == 0 || sz > PAGESIZE) {
return nullptr;
}
auto irqs = page_lock.lock();
void* ptr = nullptr;
// skip over reserved and kernel memory
auto range = physical_ranges.find(next_free_pa);
while (range != physical_ranges.end()) {
if (range->type() == mem_available) {
// use this page
ptr = pa2kptr<void*>(next_free_pa);
next_free_pa += PAGESIZE;
break;
} else {
// move to next range
next_free_pa = range->last();
++range;
}
}
page_lock.unlock(irqs);
if (ptr) {
// tell sanitizers the allocated page is accessible
asan_mark_memory(ka2pa(ptr), PAGESIZE, false);
// initialize to `int3`
memset(ptr, 0xCC, PAGESIZE);
}
return ptr;
}
// kfree(ptr)
// Free a pointer previously returned by `kalloc`. Does nothing if
// `ptr == nullptr`.
void kfree(void* ptr) {
if (ptr) {
// tell sanitizers the freed page is inaccessible
asan_mark_memory(ka2pa(ptr), PAGESIZE, true);
}
log_printf("kfree not implemented yet\n");
}
// operator new, operator delete
// Expressions like `new (std::nothrow) T(...)` and `delete x` work,
// and call kalloc/kfree.
void* operator new(size_t sz, const std::nothrow_t&) noexcept {
return kalloc(sz);
}
void* operator new(size_t sz, std::align_val_t, const std::nothrow_t&) noexcept {
return kalloc(sz);
}
void* operator new[](size_t sz, const std::nothrow_t&) noexcept {
return kalloc(sz);
}
void* operator new[](size_t sz, std::align_val_t, const std::nothrow_t&) noexcept {
return kalloc(sz);
}
void operator delete(void* ptr) noexcept {
kfree(ptr);
}
void operator delete(void* ptr, size_t) noexcept {
kfree(ptr);
}
void operator delete(void* ptr, std::align_val_t) noexcept {
kfree(ptr);
}
void operator delete(void* ptr, size_t, std::align_val_t) noexcept {
kfree(ptr);
}
void operator delete[](void* ptr) noexcept {
kfree(ptr);
}
void operator delete[](void* ptr, size_t) noexcept {
kfree(ptr);
}
void operator delete[](void* ptr, std::align_val_t) noexcept {
kfree(ptr);
}
void operator delete[](void* ptr, size_t, std::align_val_t) noexcept {
kfree(ptr);
}