Skip to content
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

Use new nightly GlobalAlloc API #11

Merged
merged 3 commits into from
Apr 18, 2018
Merged

Conversation

weclaw1
Copy link
Contributor

@weclaw1 weclaw1 commented Apr 15, 2018

Current nightly requires the use of new GlobalAlloc trait with #[global_allocator].
You can find more info here: rust-lang/rust#49669

Copy link
Member

@phil-opp phil-opp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot! I left a few comments, but overall this looks good to me.

I wonder why the return type of alloc was changed to a raw pointer instead of a Result? I couldn't find an explanation for it in the rust PRs/issues…

src/lib.rs Outdated
self.allocate_first_fit(layout)
unsafe impl GlobalAlloc for Heap {
unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
ALLOCATOR.allocate_first_fit(layout)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the new ALLOCATOR static?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GlobalAlloc takes &self instead of &mut self, so as far as I know static and RefCell are the only choices here. There's also new Alloc trait, but it can't be used with #[global_allocator]. In that case someone using this library would have to implement GlobalAlloc on his own to be able to use it with #[global_allocator]

src/lib.rs Outdated
self.0.lock().allocate_first_fit(layout)
unsafe impl<'a> GlobalAlloc for &'a LockedHeap {
unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
LOCKED_ALLOCATOR.0.lock().allocate_first_fit(layout)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the new LOCKED_ALLOCATOR static?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as with ALLOCATOR

src/test.rs Outdated
}

#[test]
fn oom() {
let mut heap = new_heap();
let layout = Layout::from_size_align(heap.size() + 1, align_of::<usize>());
let addr = heap.allocate_first_fit(layout.unwrap());
assert!(addr.is_err());
assert!(addr as *mut u8 == core::ptr::null_mut());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can encapsulate the == core::ptr::null_mut() check in some is_err / is_ok functions to avoid the boilerplate? It might also make sense to move all the tests in an inline tests submodule.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea

src/test.rs Outdated
@@ -62,7 +61,7 @@ fn allocate_and_free_double_usize() {
let mut heap = new_heap();

let layout = Layout::from_size_align(size_of::<usize>() * 2, align_of::<usize>()).unwrap();
let x = heap.allocate_first_fit(layout.clone()).unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't just remove the unwrap, because it also checked that the allocation succeeded. When we don't check it we risk deallocating a null pointer. Also applies to the other cases where unwraps are removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like I'll have to add asserts here, or write a function that panics when pointer is null

@weclaw1
Copy link
Contributor Author

weclaw1 commented Apr 16, 2018

I think return type of alloc now uses raw pointer because it makes it easier to use allocators written in C.

@phil-opp
Copy link
Member

I thought a bit more about this and I really don't like the new C-style API. So how about keeping it the old way (i.e. implement the Alloc trait and return Results from almost all methods) and only update LockedHeap to create a GlobalAlloc on top of that? Then users can use LockedHeap as global allocator, use Heap as non-global allocator, or build an own global allocator on top of Heap.

@weclaw1
Copy link
Contributor Author

weclaw1 commented Apr 17, 2018

I implemented the changes you wanted, let me know if I should change anything else.

Copy link
Member

@phil-opp phil-opp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot, looks really good now!

I think we can remove the LOCKED_ALLOCATOR because we use a Mutex in LockedHeap.

src/lib.rs Outdated
self.0.lock().allocate_first_fit(layout)
unsafe impl<'a> GlobalAlloc for &'a LockedHeap {
unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
LOCKED_ALLOCATOR.0.lock().allocate_first_fit(layout).ok().map_or(0 as *mut Opaque, |allocation| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be able to do just self.0.lock without the static LOCKED_ALLOCATOR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, Mutex lock() uses &self and returns MutexGuard, so static is not needed here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the &'a needed in impl? It works without it.

@weclaw1
Copy link
Contributor Author

weclaw1 commented Apr 17, 2018

I removed the LOCKED_ALLOCATOR static, also I removed &'a from impl

@Woyten Woyten mentioned this pull request Apr 18, 2018
1 task
@phil-opp phil-opp merged commit 3d91766 into rust-osdev:master Apr 18, 2018
@phil-opp
Copy link
Member

Thanks a lot!

The &'a was there because the old global allocator API required it that way. So yes, we no longer need it.

@phil-opp
Copy link
Member

Released as version 0.6.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants