Struct MapleTreeAlloc

Source
pub struct MapleTreeAlloc<T: ForeignOwnable> { /* private fields */ }
Expand description

A maple tree with MT_FLAGS_ALLOC_RANGE set.

All methods on MapleTree are also accessible on this type.

Implementations§

Source§

impl<T: ForeignOwnable> MapleTreeAlloc<T>

Source

pub fn project<'__pin>( self: Pin<&'__pin mut Self>, ) -> MapleTreeAllocProjection<'__pin, T>

Pin-projects all fields of Self.

These fields are structurally pinned:

  • tree

These fields are not structurally pinned:

Source§

impl<T: ForeignOwnable> MapleTreeAlloc<T>

Source

pub fn new() -> impl PinInit<Self>

Create a new allocation tree.

Source

pub fn alloc_range<R>( &self, size: usize, value: T, range: R, gfp: Flags, ) -> Result<usize, AllocError<T>>
where R: RangeBounds<usize>,

Insert an entry with the given size somewhere in the given range.

The maple tree will search for a location in the given range where there is space to insert the new range. If there is not enough available space, then an error will be returned.

The index of the new range is returned.

§Examples
use kernel::maple_tree::{MapleTreeAlloc, AllocErrorKind};

let tree = KBox::pin_init(MapleTreeAlloc::<KBox<i32>>::new(), GFP_KERNEL)?;

let ten = KBox::new(10, GFP_KERNEL)?;
let twenty = KBox::new(20, GFP_KERNEL)?;
let thirty = KBox::new(30, GFP_KERNEL)?;
let hundred = KBox::new(100, GFP_KERNEL)?;

// Allocate three ranges.
let idx1 = tree.alloc_range(100, ten, ..1000, GFP_KERNEL)?;
let idx2 = tree.alloc_range(100, twenty, ..1000, GFP_KERNEL)?;
let idx3 = tree.alloc_range(100, thirty, ..1000, GFP_KERNEL)?;

assert_eq!(idx1, 0);
assert_eq!(idx2, 100);
assert_eq!(idx3, 200);

// This will fail because the remaining space is too small.
assert_eq!(
    tree.alloc_range(800, hundred, ..1000, GFP_KERNEL).unwrap_err().cause,
    AllocErrorKind::Busy,
);

Methods from Deref<Target = MapleTree<T>>§

Source

pub fn project<'__pin>( self: Pin<&'__pin mut Self>, ) -> MapleTreeProjection<'__pin, T>

Pin-projects all fields of Self.

These fields are structurally pinned:

  • tree

These fields are not structurally pinned:

  • _p
Source

pub fn insert( &self, index: usize, value: T, gfp: Flags, ) -> Result<(), InsertError<T>>

Insert the value at the given index.

§Errors

If the maple tree already contains a range using the given index, then this call will return an InsertErrorKind::Occupied. It may also fail if memory allocation fails.

§Examples
use kernel::maple_tree::{InsertErrorKind, MapleTree};

let tree = KBox::pin_init(MapleTree::<KBox<i32>>::new(), GFP_KERNEL)?;

let ten = KBox::new(10, GFP_KERNEL)?;
let twenty = KBox::new(20, GFP_KERNEL)?;
let the_answer = KBox::new(42, GFP_KERNEL)?;

// These calls will succeed.
tree.insert(100, ten, GFP_KERNEL)?;
tree.insert(101, twenty, GFP_KERNEL)?;

// This will fail because the index is already in use.
assert_eq!(
    tree.insert(100, the_answer, GFP_KERNEL).unwrap_err().cause,
    InsertErrorKind::Occupied,
);
Source

pub fn insert_range<R>( &self, range: R, value: T, gfp: Flags, ) -> Result<(), InsertError<T>>
where R: RangeBounds<usize>,

Insert a value to the specified range, failing on overlap.

This accepts the usual types of Rust ranges using the .. and ..= syntax for exclusive and inclusive ranges respectively. The range must not be empty, and must not overlap with any existing range.

§Errors

If the maple tree already contains an overlapping range, then this call will return an InsertErrorKind::Occupied. It may also fail if memory allocation fails or if the requested range is invalid (e.g. empty).

§Examples
use kernel::maple_tree::{InsertErrorKind, MapleTree};

let tree = KBox::pin_init(MapleTree::<KBox<i32>>::new(), GFP_KERNEL)?;

let ten = KBox::new(10, GFP_KERNEL)?;
let twenty = KBox::new(20, GFP_KERNEL)?;
let the_answer = KBox::new(42, GFP_KERNEL)?;
let hundred = KBox::new(100, GFP_KERNEL)?;

// Insert the value 10 at the indices 100 to 499.
tree.insert_range(100..500, ten, GFP_KERNEL)?;

// Insert the value 20 at the indices 500 to 1000.
tree.insert_range(500..=1000, twenty, GFP_KERNEL)?;

// This will fail due to overlap with the previous range on index 1000.
assert_eq!(
    tree.insert_range(1000..1200, the_answer, GFP_KERNEL).unwrap_err().cause,
    InsertErrorKind::Occupied,
);

// When using .. to specify the range, you must be careful to ensure that the range is
// non-empty.
assert_eq!(
    tree.insert_range(72..72, hundred, GFP_KERNEL).unwrap_err().cause,
    InsertErrorKind::InvalidRequest,
);
Source

pub fn erase(&self, index: usize) -> Option<T>

Erase the range containing the given index.

§Examples
use kernel::maple_tree::MapleTree;

let tree = KBox::pin_init(MapleTree::<KBox<i32>>::new(), GFP_KERNEL)?;

let ten = KBox::new(10, GFP_KERNEL)?;
let twenty = KBox::new(20, GFP_KERNEL)?;

tree.insert_range(100..500, ten, GFP_KERNEL)?;
tree.insert(67, twenty, GFP_KERNEL)?;

assert_eq!(tree.erase(67).map(|v| *v), Some(20));
assert_eq!(tree.erase(275).map(|v| *v), Some(10));

// The previous call erased the entire range, not just index 275.
assert!(tree.erase(127).is_none());
Source

pub fn lock(&self) -> MapleGuard<'_, T>

Lock the internal spinlock.

Trait Implementations§

Source§

impl<T: ForeignOwnable> Deref for MapleTreeAlloc<T>

Source§

type Target = MapleTree<T>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &MapleTree<T>

Dereferences the value.
Source§

impl<T: ForeignOwnable> HasPinData for MapleTreeAlloc<T>

Source§

type PinData = __ThePinData<T>

Source§

unsafe fn __pin_data() -> Self::PinData

Auto Trait Implementations§

§

impl<T> !Freeze for MapleTreeAlloc<T>

§

impl<T> !RefUnwindSafe for MapleTreeAlloc<T>

§

impl<T> !Send for MapleTreeAlloc<T>

§

impl<T> !Sync for MapleTreeAlloc<T>

§

impl<T> UnwindSafe for MapleTreeAlloc<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where 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> Init<T> for T

Source§

unsafe fn __init(self, slot: *mut T) -> Result<(), Infallible>

Initializes slot. Read more
Source§

fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
where F: FnOnce(&mut T) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

impl<T, U> Into<U> for T
where 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> PinInit<T> for T

Source§

unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), Infallible>

Initializes slot. Read more
Source§

fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
where F: FnOnce(Pin<&mut T>) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

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

Source§

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 T
where U: TryFrom<T>,

Source§

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.