Skip to content

Heap::extend_with_region() implementation #41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 49 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub struct Heap {
bottom: usize,
size: usize,
used: usize,
contiguous: bool,
holes: HoleList,
}

Expand All @@ -46,6 +47,7 @@ impl Heap {
bottom: 0,
size: 0,
used: 0,
contiguous: false,
holes: HoleList::empty(),
}
}
Expand All @@ -60,6 +62,7 @@ impl Heap {
self.bottom = heap_bottom;
self.size = heap_size;
self.used = 0;
self.contiguous = true;
self.holes = HoleList::new(heap_bottom, heap_size);
}

Expand All @@ -75,6 +78,7 @@ impl Heap {
bottom: heap_bottom,
size: heap_size,
used: 0,
contiguous: true,
holes: HoleList::new(heap_bottom, heap_size),
}
}
Expand Down Expand Up @@ -120,43 +124,79 @@ impl Heap {
self.used -= aligned_layout.size();
}

/// Returns the bottom address of the heap.
pub fn bottom(&self) -> usize {
self.bottom
/// Returns the bottom address of the heap only if it manages
/// contiguous regions
pub fn bottom(&self) -> Option<usize> {
if self.is_contiguous() {
Some(self.bottom)
} else {
None
}
}

/// Returns the size of the heap.
pub fn size(&self) -> usize {
self.size
}

/// Return the top address of the heap
pub fn top(&self) -> usize {
self.bottom + self.size
/// Return the top address of the heap only if it manages
/// contiguous regions
pub fn top(&self) -> Option<usize> {
if self.is_contiguous() {
Some(self.bottom + self.size)
} else {
None
}
}

/// Returns the size of the used part of the heap
pub fn used(&self) -> usize {
self.used
}

/// Returns whether the heap manages contiguous memory
pub fn is_contiguous(&self) -> bool {
self.contiguous
}

/// Returns the size of the free part of the heap
pub fn free(&self) -> usize {
self.size - self.used
}

/// Extends the size of the heap by creating a new hole at the end
/// Extends the size of the heap by creating a new hole at the end.
/// The operation is executed only if `self.is_contiguous()` returns `true`
///
/// # Unsafety
///
/// The new extended area must be valid
pub unsafe fn extend(&mut self, by: usize) {
let top = self.top();
let top = self.top().unwrap();
let layout = Layout::from_size_align(by, 1).unwrap();
self.holes
.deallocate(NonNull::new_unchecked(top as *mut u8), layout);
self.size += by;
}

/// Extends the `Heap`s managed area with a non contiguous region.
///
/// The use of this method invalidates the value returned by
/// `Heap::top(&self)`, consequently is highly recommended to not
/// use `Heap::extend()` after the use of this method
///
/// # Unsafety
/// The given region must be valid and free from other uses
pub unsafe fn extend_with_region(&mut self, start_addr: usize, size: usize) {
let layout = Layout::from_size_align(size, 1).unwrap();
self.holes
.deallocate(NonNull::new(start_addr as *mut u8).unwrap(), layout);
self.size += size;

// check whether the given region is not really contiguous
if self.is_contiguous() && start_addr != self.top().unwrap() {
self.contiguous = false;
}
}
}

#[cfg(feature = "alloc_ref")]
Expand Down Expand Up @@ -197,6 +237,7 @@ impl LockedHeap {
bottom: heap_bottom,
size: heap_size,
used: 0,
contiguous: true,
holes: HoleList::new(heap_bottom, heap_size),
}))
}
Expand Down