Struct talc::Talc

source ·
pub struct Talc<O: OomHandler> {
    pub oom_handler: O,
    /* private fields */
}
Expand description

The Talc Allocator!

To get started:

  • Construct with new or with_arena functions (use ErrOnOom to ignore OOM handling).
  • Initialize with init or extend.
  • Call lock to get a Talck which supports the GlobalAlloc and Allocator traits.

Fields§

§oom_handler: O

Implementations§

source§

impl<O: OomHandler> Talc<O>

source

pub unsafe fn malloc(&mut self, layout: Layout) -> Result<NonNull<u8>, ()>

Allocate a contiguous region of memory according to layout, if possible.

Safety

layout.size() must be nonzero.

source

pub unsafe fn free(&mut self, ptr: NonNull<u8>, _: Layout)

Free previously allocated/reallocated memory.

Safety

ptr must have been previously allocated given layout.

source

pub unsafe fn grow( &mut self, ptr: NonNull<u8>, layout: Layout, new_size: usize ) -> Result<NonNull<u8>, ()>

Grow a previously allocated/reallocated region of memory to new_size.

Safety

ptr must have been previously allocated or reallocated given layout. new_size must be larger or equal to layout.size().

source

pub unsafe fn shrink( &mut self, ptr: NonNull<u8>, layout: Layout, new_size: usize )

Shrink a previously allocated/reallocated region of memory to new_size.

This function is infallibe given valid inputs, and the reallocation will always be done in-place, maintaining the validity of the pointer.

Safety
  • ptr must have been previously allocated or reallocated given layout.
  • new_size must be smaller or equal to layout.size().
  • new_size should be nonzero.
source

pub const fn new(oom_handler: O) -> Self

Returns an uninitialized Talc.

If you don’t want to handle OOM, use ErrOnOom.

source

pub unsafe fn with_arena(oom_handler: O, arena: Span) -> Self

Contruct and initialize a Talc with the given OOM handler and arena.

If you don’t want to handle OOM, use ErrOnOom.

Safety

See init for safety requirements.

source

pub const fn get_arena(&self) -> Span

Returns the Span which has been granted to this allocator as allocatable.

source

pub fn get_allocatable_span(&self) -> Span

Returns the Span in which allocations may be placed.

source

pub fn get_allocated_span(&self) -> Span

Returns the minimum Span containing all allocated memory.

source

pub unsafe fn init(&mut self, arena: Span)

Initialize the allocator heap.

Note that metadata will be placed into the bottom of the heap. It should be ~1KiB. Note that if the arena isn’t big enough, this function will not fail. However, no memory will be made available for allocation, and allocations will signal OOM.

Safety
  • The memory within the arena must be valid for reads and writes, and memory therein not allocated to the user must not be mutated for the lifetime of all the allocations of this allocator.
Panics

Panics if arena contains the null address.

source

pub unsafe fn extend(&mut self, new_arena: Span)

Increase the extent of the arena.

Safety

The entire new_arena memory but be readable and writable and unmutated besides that which is allocated. So on and so forth.

Panics

This function panics if:

  • new_arena doesn’t contain the old arena (NB: empty arenas are contained by any arena)
  • new_arena contains the null address

A recommended pattern for satisfying these criteria is:

// compute the new arena as an extention of the old arena
// for the sake of example we avoid the null page too
let new_arena = talc.get_arena().extend(1234, 5678).above(0x1000 as *mut u8);
// SAFETY: be sure not to extend into memory we can't use
unsafe { talc.extend(new_arena); }
source

pub fn truncate(&mut self, new_arena: Span)

Reduce the extent of the arena. The new extent must encompass all current allocations. See below.

Panics:

This function panics if:

  • old arena doesn’t contain new_arena
  • new_arena doesn’t contain all the allocated memory

The recommended pattern for satisfying these criteria is:

// note: lock the allocator otherwise a race condition may occur
// in between get_allocated_span and truncate

// compute the new arena as a reduction of the old arena
let new_arena = talc.get_arena().truncate(1234, 5678).fit_over(talc.get_allocated_span());
// alternatively...
let new_arena = Span::from((1234 as *mut u8)..(5678 as *mut u8))
    .fit_within(talc.get_arena())
    .fit_over(talc.get_allocated_span());
// truncate the arena
talc.truncate(new_arena);
source

pub const fn lock<R: RawMutex>(self) -> Talck<R, O>

Wrap in Talck, a mutex-locked wrapper struct using lock_api.

This implements the GlobalAlloc trait and provides access to the Allocator API.

Examples
use spin::Mutex;
let talc = Talc::new(ErrOnOom);
let talck = talc.lock::<Mutex<()>>();

unsafe {
    talck.alloc(Layout::from_size_align_unchecked(32, 4));
}
source

pub const unsafe fn lock_assume_single_threaded( self ) -> Talck<AssumeUnlockable, O>

Trait Implementations§

source§

impl<O: OomHandler> Debug for Talc<O>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<O: Send + OomHandler> Send for Talc<O>

Auto Trait Implementations§

§

impl<O> RefUnwindSafe for Talc<O>where O: RefUnwindSafe,

§

impl<O> !Sync for Talc<O>

§

impl<O> Unpin for Talc<O>where O: Unpin,

§

impl<O> UnwindSafe for Talc<O>where O: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

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

source§

fn into(self) -> U

Calls U::from(self).

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

source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.