Create a stack allocator module

toolchain_update
Philipp Oppermann 8 years ago
parent 3efe54169e
commit 0e3857ca50

@ -6,6 +6,7 @@ use multiboot2::BootInformation;
mod area_frame_allocator;
pub mod heap_allocator;
mod paging;
mod stack_allocator;
pub const PAGE_SIZE: usize = 4096;

@ -30,7 +30,7 @@ impl Page {
Page { number: address / PAGE_SIZE }
}
fn start_address(&self) -> usize {
pub fn start_address(&self) -> usize {
self.number * PAGE_SIZE
}
@ -55,6 +55,7 @@ impl Page {
}
}
#[derive(Clone)]
pub struct PageIter {
start: Page,
end: Page,

@ -0,0 +1,79 @@
use memory::paging::{self, Page, PageIter, ActivePageTable};
use memory::{PAGE_SIZE, FrameAllocator};
pub struct StackAllocator {
range: PageIter,
}
impl StackAllocator {
pub fn new(page_range: PageIter) -> StackAllocator {
StackAllocator { range: page_range }
}
}
impl StackAllocator {
pub fn alloc_stack<FA: FrameAllocator>(&mut self,
active_table: &mut ActivePageTable,
frame_allocator: &mut FA,
size_in_pages: usize)
-> Option<Stack> {
if size_in_pages == 0 {
return None; /* a zero sized stack makes no sense */
}
// clone the range, since we only want to change it on success
let mut range = self.range.clone();
// try to allocate the stack pages and a guard page
let guard_page = range.next();
let stack_start = range.next();
let stack_end = if size_in_pages == 1 {
stack_start
} else {
// choose the (size_in_pages-2)th element, since index
// starts at 0 and we already allocated the start page
range.nth(size_in_pages - 2)
};
match (guard_page, stack_start, stack_end) {
(Some(_), Some(start), Some(end)) => {
// success! write back updated range
self.range = range;
// map stack pages to physical frames
for page in Page::range_inclusive(start, end) {
active_table.map(page, paging::WRITABLE, frame_allocator);
}
// create a new stack
let top_of_stack = end.start_address() + PAGE_SIZE;
Some(Stack::new(top_of_stack, start.start_address()))
}
_ => None, /* not enough pages */
}
}
}
#[derive(Debug)]
pub struct Stack {
top: usize,
bottom: usize,
}
impl Stack {
fn new(top: usize, bottom: usize) -> Stack {
assert!(top > bottom);
Stack {
top: top,
bottom: bottom,
}
}
pub fn top(&self) -> usize {
self.top
}
pub fn bottom(&self) -> usize {
self.bottom
}
}
Loading…
Cancel
Save