Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix pool macro warnings. #456

Merged
merged 2 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed

- Fixed clippy lints.
- Fixed `{arc,box,object}_pool!` emitting clippy lints for `CamelCase` and `SNAKE_CASE`.
- Fixed `{arc,box,object}_pool!` emitting clippy lints.
- Fixed the list of implemented data structures in the crate docs, by adding `Deque`,
`HistoryBuffer` and `SortedLinkedList` to the list.

Expand Down
6 changes: 3 additions & 3 deletions src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
//!
//! - test program:
//!
//! ``` no_run
//! ```no_run
//! use heapless::box_pool;
//!
//! box_pool!(P: ()); // or `arc_pool!` or `object_pool!`
//! box_pool!(MyBoxPool: ()); // or `arc_pool!` or `object_pool!`
//!
//! bkpt();
//! let res = P.alloc(());
//! let res = MyBoxPool.alloc(());
//! bkpt();
//!
//! if let Ok(boxed) = res {
Expand Down
110 changes: 52 additions & 58 deletions src/pool/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@
//! ```
//! use heapless::{arc_pool, pool::arc::{Arc, ArcBlock}};
//!
//! arc_pool!(P: u128);
//! arc_pool!(MyArcPool: u128);
//!
//! // cannot allocate without first giving memory blocks to the pool
//! assert!(P.alloc(42).is_err());
//! assert!(MyArcPool.alloc(42).is_err());
//!
//! // (some `no_std` runtimes have safe APIs to create `&'static mut` references)
//! let block: &'static mut ArcBlock<u128> = unsafe {
//! static mut B: ArcBlock<u128> = ArcBlock::new();
//! &mut B
//! static mut BLOCK: ArcBlock<u128> = ArcBlock::new();
//! &mut BLOCK
//! };
//!
//! P.manage(block);
//! MyArcPool.manage(block);
//!
//! let arc = P.alloc(1).unwrap();
//! let arc = MyArcPool.alloc(1).unwrap();
//!
//! // number of smart pointers is limited to the number of blocks managed by the pool
//! let res = P.alloc(2);
//! let res = MyArcPool.alloc(2);
//! assert!(res.is_err());
//!
//! // but cloning does not consume an `ArcBlock`
Expand All @@ -34,7 +34,7 @@
//! drop(arc); // release memory
//!
//! // it's now possible to allocate a new `Arc` smart pointer
//! let res = P.alloc(3);
//! let res = MyArcPool.alloc(3);
//!
//! assert!(res.is_ok());
//! ```
Expand All @@ -47,7 +47,7 @@
//! ```
//! use heapless::{arc_pool, pool::arc::ArcBlock};
//!
//! arc_pool!(P: u128);
//! arc_pool!(MyArcPool: u128);
//!
//! const POOL_CAPACITY: usize = 8;
//!
Expand All @@ -58,7 +58,7 @@
//! };
//!
//! for block in blocks {
//! P.manage(block);
//! MyArcPool.manage(block);
//! }
//! ```

Expand All @@ -83,13 +83,14 @@ use super::treiber::{NonNullPtr, Stack, UnionNode};
#[macro_export]
macro_rules! arc_pool {
($name:ident: $data_type:ty) => {
#[allow(non_camel_case_types)]
pub struct $name;

impl $crate::pool::arc::ArcPool for $name {
type Data = $data_type;

fn singleton() -> &'static $crate::pool::arc::ArcPoolImpl<$data_type> {
// Even though the static variable is not exposed to user code, it is
// still useful to have a descriptive symbol name for debugging.
#[allow(non_upper_case_globals)]
static $name: $crate::pool::arc::ArcPoolImpl<$data_type> =
$crate::pool::arc::ArcPoolImpl::new();
Expand Down Expand Up @@ -386,67 +387,67 @@ mod tests {

#[test]
fn cannot_alloc_if_empty() {
arc_pool!(P: i32);
arc_pool!(MyArcPool: i32);

assert_eq!(Err(42), P.alloc(42),);
assert_eq!(Err(42), MyArcPool.alloc(42),);
}

#[test]
fn can_alloc_if_manages_one_block() {
arc_pool!(P: i32);
arc_pool!(MyArcPool: i32);

let block = unsafe {
static mut B: ArcBlock<i32> = ArcBlock::new();
&mut B
static mut BLOCK: ArcBlock<i32> = ArcBlock::new();
&mut BLOCK
};
P.manage(block);
MyArcPool.manage(block);

assert_eq!(42, *P.alloc(42).unwrap());
assert_eq!(42, *MyArcPool.alloc(42).unwrap());
}

#[test]
fn alloc_drop_alloc() {
arc_pool!(P: i32);
arc_pool!(MyArcPool: i32);

let block = unsafe {
static mut B: ArcBlock<i32> = ArcBlock::new();
&mut B
static mut BLOCK: ArcBlock<i32> = ArcBlock::new();
&mut BLOCK
};
P.manage(block);
MyArcPool.manage(block);

let arc = P.alloc(1).unwrap();
let arc = MyArcPool.alloc(1).unwrap();

drop(arc);

assert_eq!(2, *P.alloc(2).unwrap());
assert_eq!(2, *MyArcPool.alloc(2).unwrap());
}

#[test]
fn strong_count_starts_at_one() {
arc_pool!(P: i32);
arc_pool!(MyArcPool: i32);

let block = unsafe {
static mut B: ArcBlock<i32> = ArcBlock::new();
&mut B
static mut BLOCK: ArcBlock<i32> = ArcBlock::new();
&mut BLOCK
};
P.manage(block);
MyArcPool.manage(block);

let arc = P.alloc(1).ok().unwrap();
let arc = MyArcPool.alloc(1).ok().unwrap();

assert_eq!(1, arc.inner().strong.load(Ordering::Relaxed));
}

#[test]
fn clone_increases_strong_count() {
arc_pool!(P: i32);
arc_pool!(MyArcPool: i32);

let block = unsafe {
static mut B: ArcBlock<i32> = ArcBlock::new();
&mut B
static mut BLOCK: ArcBlock<i32> = ArcBlock::new();
&mut BLOCK
};
P.manage(block);
MyArcPool.manage(block);

let arc = P.alloc(1).ok().unwrap();
let arc = MyArcPool.alloc(1).ok().unwrap();

let before = arc.inner().strong.load(Ordering::Relaxed);

Expand All @@ -459,15 +460,15 @@ mod tests {

#[test]
fn drop_decreases_strong_count() {
arc_pool!(P: i32);
arc_pool!(MyArcPool: i32);

let block = unsafe {
static mut B: ArcBlock<i32> = ArcBlock::new();
&mut B
static mut BLOCK: ArcBlock<i32> = ArcBlock::new();
&mut BLOCK
};
P.manage(block);
MyArcPool.manage(block);

let arc = P.alloc(1).ok().unwrap();
let arc = MyArcPool.alloc(1).ok().unwrap();
let arc2 = arc.clone();

let before = arc.inner().strong.load(Ordering::Relaxed);
Expand All @@ -482,23 +483,23 @@ mod tests {
fn runs_destructor_exactly_once_when_strong_count_reaches_zero() {
static COUNT: AtomicUsize = AtomicUsize::new(0);

pub struct S;
pub struct MyStruct;

impl Drop for S {
impl Drop for MyStruct {
fn drop(&mut self) {
COUNT.fetch_add(1, Ordering::Relaxed);
}
}

arc_pool!(P: S);
arc_pool!(MyArcPool: MyStruct);

let block = unsafe {
static mut B: ArcBlock<S> = ArcBlock::new();
&mut B
static mut BLOCK: ArcBlock<MyStruct> = ArcBlock::new();
&mut BLOCK
};
P.manage(block);
MyArcPool.manage(block);

let arc = P.alloc(S).ok().unwrap();
let arc = MyArcPool.alloc(MyStruct).ok().unwrap();

assert_eq!(0, COUNT.load(Ordering::Relaxed));

Expand All @@ -512,24 +513,17 @@ mod tests {
#[repr(align(4096))]
pub struct Zst4096;

arc_pool!(P: Zst4096);
arc_pool!(MyArcPool: Zst4096);

let block = unsafe {
static mut B: ArcBlock<Zst4096> = ArcBlock::new();
&mut B
static mut BLOCK: ArcBlock<Zst4096> = ArcBlock::new();
&mut BLOCK
};
P.manage(block);
MyArcPool.manage(block);

let arc = P.alloc(Zst4096).ok().unwrap();
let arc = MyArcPool.alloc(Zst4096).ok().unwrap();

let raw = &*arc as *const Zst4096;
assert_eq!(0, raw as usize % 4096);
}

#[test]
fn arc_pool_case() {
// https://github.com/rust-embedded/heapless/issues/411
arc_pool!(CamelCaseType: u128);
arc_pool!(SCREAMING_SNAKE_CASE_TYPE: u128);
}
}
Loading
Loading