Skip to content

Commit e37e935

Browse files
authored
Merge pull request #61 from rmja/allocator_api
Implement the Allocator trait from the unstable allocator_api
2 parents 5654f2a + cd44eb2 commit e37e935

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Implemented [`Allocator`] for `Heap` with the `allocator_api` crate feature.
13+
This feature requires a nightly toolchain for the unstable [`allocator_api`]
14+
compiler feature.
15+
16+
[`Allocator`]: https://doc.rust-lang.org/core/alloc/trait.Allocator.html
17+
[`allocator_api`]: https://doc.rust-lang.org/beta/unstable-book/library-features/allocator-api.html
18+
19+
### Changed
20+
1021
- Updated `linked_list_allocator` dependency to 0.10.5, which allows
1122
compiling with stable rust.
1223

Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ license = "MIT OR Apache-2.0"
2323
name = "embedded-alloc"
2424
version = "0.5.0"
2525

26+
[features]
27+
allocator_api = []
28+
2629
[dependencies]
2730
critical-section = "1.0"
2831

src/lib.rs

+38
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![doc = include_str!("../README.md")]
22
#![no_std]
3+
#![cfg_attr(feature = "allocator_api", feature(allocator_api, alloc_layout_extra))]
34

45
use core::alloc::{GlobalAlloc, Layout};
56
use core::cell::RefCell;
@@ -88,3 +89,40 @@ unsafe impl GlobalAlloc for Heap {
8889
});
8990
}
9091
}
92+
93+
#[cfg(feature = "allocator_api")]
94+
mod allocator_api {
95+
use core::{
96+
alloc::{AllocError, Allocator, Layout},
97+
ptr::NonNull,
98+
};
99+
100+
use crate::Heap;
101+
102+
unsafe impl Allocator for Heap {
103+
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
104+
match layout.size() {
105+
0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)),
106+
size => critical_section::with(|cs| {
107+
self.heap
108+
.borrow(cs)
109+
.borrow_mut()
110+
.allocate_first_fit(layout)
111+
.map(|allocation| NonNull::slice_from_raw_parts(allocation, size))
112+
.map_err(|_| AllocError)
113+
}),
114+
}
115+
}
116+
117+
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
118+
if layout.size() != 0 {
119+
critical_section::with(|cs| {
120+
self.heap
121+
.borrow(cs)
122+
.borrow_mut()
123+
.deallocate(NonNull::new_unchecked(ptr.as_ptr()), layout)
124+
});
125+
}
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)