Repository navigation
Allocator Designs #1016
Replies: 50 comments 5 replies
|
Great! |
|
Thanks for the post! As usual, it is very interesting!
looks like typo |
|
The Or, if you use powers of two as argument instead: |
|
I should mention that when using a First, while you normally can't delete entries from the allocator, you can delete the last entry. In other words, if you know what you are doing, you can allow a Second, it is common practice to allocate from both the front and the back of the memory region. This is useful where some of the allocations are temporary. You put temporary allocations at the end, while longer-lasting allocation are put in the front. Anyway, both these methods are quite dangerous, but in terms of raw speed, there's no comparison. |
|
Thanks for your comments!
Good point! I'll extend that section. The fastest variant I'm aware of is relying on the optimized #[no_mangle]
fn align_up(addr: usize, align: usize) -> usize {
let offset = (addr as *const u8).align_offset(align);
addr + offset
}
One could also check in deallocate whether the end address of the freed allocation equals
Good point! While this is difficult to implement for a global allocator, it definitely works for manual allocations. I try to update the bump allocator discussion section with both your suggestions. |
|
@MikailBag Thank you! Could you maybe clarify what the typo is? I don't see it right now⦠|
|
Nice comparison, thanks! For more on bump allocation, see this post (in Rust, even): Also small typo in the beginning: |
|
@amosonn Thanks for you comment!
I already link this post in the Dicussion section as "can be optimized to just a few assembly operations". I deliberatly decided against bumping from the end because the intention of the post is to explain a basic implementation, not to maximally optimize it. Regarding the alignment function: I think the
Good point! I'll prepare a PR to fix this.
Thanks! Fixed in 4b8c902. |
|
Ah sorry, I missed the link :). Regarding the various alignment implementations: |
|
Thanks for investigating! I'll update #721 to use the |
|
In the code for LinkedListAllocator, |
|
@Menschenkindlein Thanks! Fixed in 00fedc8 and 670ac60. |
|
@diminishedprime Thanks for reporting! I pushed 10d84fa to fix this issue. |
|
As small note, |
|
@jiayihu Sorry for the late reply!
This depends on whether you declare the See: blog_os/src/allocator/fixed_size_block.rs Lines 14 to 20 in ca3dfc7 |
|
I found an issue with the allocators which was caused by using a mutable reference in a constant function (both in linked list allocator and in fixed size allocator), and removing that caused the issue |
|
@DeathBySpork Thanks for sharing your problem and solution. Yes, adding
(See https://os.phil-opp.com/allocator-designs/#the-allocator-type and https://os.phil-opp.com/allocator-designs/#the-allocator-type-1) |
|
ah, I guess I didnt notice the change, I am sorry! |
|
@DeathBySpork No worries, thanks for reporting your problems! |
|
I still got error "calls in statics are limited to constant functions, tuple structs and tuple variants". I've add #![feature(const_in_array_repeat_expressions)] and #![feature(const_mut_refs)] in main.rs but still got error how to solve it ? My Code in https://github.com/Ananta98/PetraOS. Thank you. |
|
@Ananta98 Looks like you forgot to make your diff --git a/src/mm/allocator.rs b/src/mm/allocator.rs
index 1ee24e3..8b911b1 100644
--- a/src/mm/allocator.rs
+++ b/src/mm/allocator.rs
@@ -15,7 +15,7 @@ pub struct Locked<A> {
}
impl<A> Locked<A> {
- pub fn new(inner : A) -> Self {
+ pub const fn new(inner : A) -> Self {
Locked {
inner : Mutex::new(inner),
}After this change, it works for me. |
|
Thank you @phil-opp it works now. sorry this is human fault. |
|
Great to hear that! No worries, I'm happy to help. |
|
Thank you so much for your work on this post series and the supporting crates! It's been extremely educational, following along. I'm either confused, or this is input: the below asserts in the fixed block allocator // verify that block has size and alignment required for storing node
assert!(mem::size_of::<ListNode>() <= BLOCK_SIZES[index]);
assert!(mem::align_of::<ListNode>() <= BLOCK_SIZES[index]);seem like they'll never be useful.
If I'm right, then we run these assertions each time we deallocate memory, paying runtime cost for no value, I think? There is a useful assertion to be made (once, maybe in |
|
How can I translate the posts in Korean |
|
Amazing article, thank you. |
|
instead of doing all that just to be able to update next, why not just make next a static mut variable? like i did this in my code use alloc::alloc::{GlobalAlloc, Layout};
#[global_allocator]
pub static mut ALLOCATOR: BumpAllocator = BumpAllocator::new();
static mut NEXT: usize = 0;
pub struct BumpAllocator {
heap_start: usize,
heap_end: usize,
}
impl BumpAllocator {
pub const fn new() -> Self {
Self {
heap_start: 0,
heap_end: 0,
}
}
pub unsafe fn init(&mut self, heap_start: usize, heap_end: usize) {
self.heap_start = heap_start;
self.heap_end = heap_end;
*next() = heap_start;
}
}
unsafe impl GlobalAlloc for BumpAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let alloc_start = *next();
*next() += layout.size();
alloc_start as *mut u8
}
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {
todo!();
}
}
pub fn next() -> &'static mut usize {
unsafe { &mut NEXT }
} |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
This is a general purpose comment thread for the Allocator Designs post.
All reactions