Allocator

Struct Allocator 

Source
pub struct Allocator<const N: usize> { /* private fields */ }
Expand description

The memory allocator for embedded systems.

This is the core type of this crate: it is an allocator with a predefined heap size. Therefore the heap memory usage is statically limited to an upper value, which also helps to prevent issues with heap/stack-smashes, as the heap is counted to the static memory (e.g. .data/.bss-sections). Such a smash might still happen though, if the stack pointer grows into the heap, but the heap cannot grow into the stack pointer.

Its usage is simple: just copy and paste the following in the binary crate you’re developing. The memory size of the heap is 4096 bytes (4K) in this example. Adjust that value to your needs.

#[global_allocator]
static ALLOCATOR: emballoc::Allocator<4096> = emballoc::Allocator::new();

Also please refer to the crate-level-documentation for recommendations on the buffer size and general usage.

Implementations§

Source§

impl<const N: usize> Allocator<N>

Source

pub const fn new() -> Self

Create a new Allocator with exactly N bytes heap space.

Note, that the usable size is less than the heap size, since there is some bookkeeping-overhead stored in that area as well. Please see the crate-level-documentation for recommendations on the buffer size and general usage.

This function is a const fn, therefore you can call it directly when creating the allocator.

§Example

Normally one would use a static variable to assign the result of this function to. When using this, the size is specified in the type and does not need to be repeated in the call to this function.

static ALLOCATOR: emballoc::Allocator<4096> = emballoc::Allocator::new();

Note: don’t use a const, as this would freshly instantiate the allocator every time used and dropping the allocation state.

If the allocator is used locally, then the size has to be specified like this:

let allocator = emballoc::Allocator::<64>::new(); // note: smaller size!

Be careful to use a smaller size, since this allocator will be created on the stack! Therefore it is possible to easily blow up the stack, so this usage is discouraged and only should be done in special cases.

§Panics

This function will panic, if the supplied buffer size, i.e. N, is less than 8 or not divisible by 4.

emballoc::Allocator::<63>::new(); // not divisible by 4
emballoc::Allocator::<4>::new(); // less than 8

Trait Implementations§

Source§

impl<const N: usize> GlobalAlloc for Allocator<N>

Source§

unsafe fn alloc(&self, layout: Layout) -> *mut u8

Allocates memory as described by the given layout. Read more
Source§

unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout)

Deallocates the block of memory at the given ptr pointer with the given layout. Read more
1.28.0§

unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8

Behaves like alloc, but also ensures that the contents are set to zero before being returned. Read more
1.28.0§

unsafe fn realloc( &self, ptr: *mut u8, layout: Layout, new_size: usize, ) -> *mut u8

Shrinks or grows a block of memory to the given new_size in bytes. The block is described by the given ptr pointer and layout. Read more

Auto Trait Implementations§

§

impl<const N: usize> !Freeze for Allocator<N>

§

impl<const N: usize> !RefUnwindSafe for Allocator<N>

§

impl<const N: usize> Send for Allocator<N>

§

impl<const N: usize> Sync for Allocator<N>

§

impl<const N: usize> Unpin for Allocator<N>

§

impl<const N: usize> UnwindSafe for Allocator<N>

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.