mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-09-27 12:30:35 +00:00
Merge #96
96: add Pool.grow_exact API r=japaric a=japaric Co-authored-by: Jorge Aparicio <jorge@japaric.io>
This commit is contained in:
commit
8510b0171c
@ -154,17 +154,18 @@
|
|||||||
//!
|
//!
|
||||||
//! [1]: https://static.docs.arm.com/ddi0403/eb/DDI0403E_B_armv7m_arm.pdf
|
//! [1]: https://static.docs.arm.com/ddi0403/eb/DDI0403E_B_armv7m_arm.pdf
|
||||||
|
|
||||||
|
#[cfg(not(armv6m))]
|
||||||
|
use core::{any::TypeId, mem, sync::atomic::Ordering};
|
||||||
use core::{
|
use core::{
|
||||||
cell::UnsafeCell,
|
cell::UnsafeCell,
|
||||||
cmp, fmt,
|
cmp, fmt,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
|
mem::MaybeUninit,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
ptr::{self, NonNull},
|
ptr::{self, NonNull},
|
||||||
sync::atomic::AtomicPtr,
|
sync::atomic::AtomicPtr,
|
||||||
};
|
};
|
||||||
#[cfg(not(armv6m))]
|
|
||||||
use core::{any::TypeId, mem, sync::atomic::Ordering};
|
|
||||||
|
|
||||||
use as_slice::{AsMutSlice, AsSlice};
|
use as_slice::{AsMutSlice, AsSlice};
|
||||||
|
|
||||||
@ -268,6 +269,22 @@ impl<T> Pool<T> {
|
|||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Increases the capacity of the pool
|
||||||
|
///
|
||||||
|
/// Unlike [`Pool.grow`](struct.Pool.html#method.grow) this method fully utilizes the given
|
||||||
|
/// memory block
|
||||||
|
pub fn grow_exact<A>(&self, memory: &'static mut MaybeUninit<A>) -> usize
|
||||||
|
where
|
||||||
|
A: AsMutSlice<Element = Node<T>>,
|
||||||
|
{
|
||||||
|
let nodes = unsafe { (*memory.as_mut_ptr()).as_mut_slice() };
|
||||||
|
let cap = nodes.len();
|
||||||
|
for p in nodes {
|
||||||
|
self.push(NonNull::from(p))
|
||||||
|
}
|
||||||
|
cap
|
||||||
|
}
|
||||||
|
|
||||||
fn pop(&self) -> Option<NonNull<Node<T>>> {
|
fn pop(&self) -> Option<NonNull<Node<T>>> {
|
||||||
// NOTE `Ordering`s come from crossbeam's (v0.6.0) `TreiberStack`
|
// NOTE `Ordering`s come from crossbeam's (v0.6.0) `TreiberStack`
|
||||||
|
|
||||||
@ -314,7 +331,9 @@ impl<T> Pool<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Node<T> {
|
/// Unfortunate implementation detail required to use the
|
||||||
|
/// [`Pool.grow_exact`](struct.Pool.html#method.grow_exact) method
|
||||||
|
pub struct Node<T> {
|
||||||
data: UnsafeCell<T>,
|
data: UnsafeCell<T>,
|
||||||
next: *mut Node<T>,
|
next: *mut Node<T>,
|
||||||
}
|
}
|
||||||
@ -445,11 +464,11 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{
|
use core::{
|
||||||
mem,
|
mem::{self, MaybeUninit},
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::Pool;
|
use super::{Node, Pool};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn grow() {
|
fn grow() {
|
||||||
@ -466,6 +485,23 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn grow_exact() {
|
||||||
|
const SZ: usize = 8;
|
||||||
|
static mut MEMORY: MaybeUninit<[Node<[u8; 128]>; SZ]> = MaybeUninit::uninit();
|
||||||
|
|
||||||
|
static POOL: Pool<[u8; 128]> = Pool::new();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
POOL.grow_exact(&mut MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..SZ {
|
||||||
|
assert!(POOL.alloc().is_some());
|
||||||
|
}
|
||||||
|
assert!(POOL.alloc().is_none());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sanity() {
|
fn sanity() {
|
||||||
static mut MEMORY: [u8; 31] = [0; 31];
|
static mut MEMORY: [u8; 31] = [0; 31];
|
||||||
|
@ -5,14 +5,14 @@ use core::{
|
|||||||
cmp, fmt,
|
cmp, fmt,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
mem,
|
mem::{self, MaybeUninit},
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
ptr,
|
ptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use as_slice::{AsMutSlice, AsSlice};
|
use as_slice::{AsMutSlice, AsSlice};
|
||||||
|
|
||||||
use super::{Init, Uninit};
|
use super::{Init, Node, Uninit};
|
||||||
|
|
||||||
/// Instantiates a pool as a global singleton
|
/// Instantiates a pool as a global singleton
|
||||||
#[cfg(any(armv7m, armv7r, test))]
|
#[cfg(any(armv7m, armv7r, test))]
|
||||||
@ -65,6 +65,17 @@ pub trait Pool {
|
|||||||
fn grow(memory: &'static mut [u8]) -> usize {
|
fn grow(memory: &'static mut [u8]) -> usize {
|
||||||
Self::ptr().grow(memory)
|
Self::ptr().grow(memory)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Increases the capacity of the pool
|
||||||
|
///
|
||||||
|
/// Unlike [`Pool.grow`](trait.Pool.html#method.grow_exact) this method fully utilizes the given
|
||||||
|
/// memory block
|
||||||
|
fn grow_exact<A>(memory: &'static mut MaybeUninit<A>) -> usize
|
||||||
|
where
|
||||||
|
A: AsMutSlice<Element = Node<Self::Data>>,
|
||||||
|
{
|
||||||
|
Self::ptr().grow_exact(memory)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A memory block that belongs to the global memory pool, `POOL`
|
/// A memory block that belongs to the global memory pool, `POOL`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user