-
Notifications
You must be signed in to change notification settings - Fork 41
/
k-alloc.cc
104 lines (90 loc) · 2.56 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
#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.
//
// If `sz` is a multiple of `PAGESIZE`, the returned pointer is guaranteed
// to be page-aligned.
void* kalloc(size_t sz) {
if (sz == 0) {
return nullptr;
}
assert(sz <= PAGESIZE);
auto irqs = page_lock.lock();
void* p = 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
p = pa2ka<void*>(next_free_pa);
next_free_pa += PAGESIZE;
break;
} else {
// move to next range
next_free_pa = range->last();
++range;
}
}
page_lock.unlock(irqs);
return p;
}
// kfree(ptr)
// Free a pointer previously returned by `kalloc`. Does nothing if
// `ptr == nullptr`.
void kfree(void* ptr) {
log_printf("kfree not implemented yet\n");
}
// test_kalloc
// Run unit tests on the kalloc system.
void test_kalloc() {
// do nothing for now
}
// 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, std::align_val_t, size_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, std::align_val_t, size_t) noexcept {
kfree(ptr);
}