Skip to content
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: 0 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,6 @@ jobs:
- x86_64-unknown-linux-gnu
toolchain:
- nightly
features:
- x86-sync-pool
buildtype:
- ""
- "--release"
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added

- Add `Clone` and `PartialEq` implementations to `HistoryBuffer`.
- Added an object pool API. see the `pool::object` module level doc for details

### Changed

- [breaking-change] `IndexMap` and `IndexSet` now require that keys implement the `core::hash::Hash`
trait instead of the `hash32::Hash` (v0.2.0) trait
- move `pool::singleton::Box` to the `pool::box` module
- renamed `pool::singleton::Pool` to `BoxPool` and moved it into the `pool::box` module
- move `pool::singleton::arc::Arc` to the `pool::arc` module
- renamed `pool::singleton::arc::Pool` to `ArcPool` and moved it into the `pool::arc` module
- [breaking-change] changed the target support of memory pool API to only support 32-bit x86 and a
subset of ARM targets. See the module level documentation of the `pool` module for details

- [breaking-change] this crate now depends on `atomic-polyfill` v1.0.1, meaning that targets that
require a polyfill need a `critical-section` **v1.x.x** implementation.
Expand All @@ -26,6 +33,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [breaking-change] this crate no longer has a Minimum Supported Rust Version (MSRV) guarantee and
should be used with the latest stable version of the Rust toolchain.

- [breaking-change] removed the `Init` and `Uninint` type states from `pool::singleton::Box`
- [breaking-change] removed the following `pool::singleton::Box` methods: `freeze`, `forget` and `init`
- [breaking-change] removed the `pool::singleton::arc::ArcInner` type
- [breaking-change] removed support for attributes from `pool!` and `arc_pool!`

## [v0.7.16] - 2022-08-09

### Added
Expand Down
2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ version = "0.8.0"
default = ["cas"]
cas = ["atomic-polyfill"]
ufmt-impl = ["ufmt-write"]
# read the docs before enabling: makes `Pool` Sync on x86_64
x86-sync-pool = []
# only for tests
__trybuild = []
# Enable larger MPMC sizes.
Expand Down
66 changes: 65 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#![deny(warnings)]

use std::{env, error::Error};
use std::{
env,
error::Error,
fs,
path::Path,
process::{Command, ExitStatus, Stdio},
};

use rustc_version::Channel;

Expand Down Expand Up @@ -89,5 +95,63 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("cargo:rustc-cfg=unstable_channel");
}

match compile_probe(ARM_LLSC_PROBE) {
Some(status) if status.success() => println!("cargo:rustc-cfg=arm_llsc"),
_ => {}
}

Ok(())
}

const ARM_LLSC_PROBE: &str = r#"
#![no_std]

// `no_mangle` forces codegen, which makes llvm check the contents of the `asm!` macro
#[no_mangle]
unsafe fn asm() {
core::arch::asm!("clrex");
}
"#;

// this function was taken from anyhow v1.0.63 build script
// https://crates.io/crates/anyhow/1.0.63 (last visited 2022-09-02)
// the code is licensed under 'MIT or APACHE-2.0'
fn compile_probe(source: &str) -> Option<ExitStatus> {
let rustc = env::var_os("RUSTC")?;
let out_dir = env::var_os("OUT_DIR")?;
let probefile = Path::new(&out_dir).join("probe.rs");
fs::write(&probefile, source).ok()?;

// Make sure to pick up Cargo rustc configuration.
let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") {
let mut cmd = Command::new(wrapper);
// The wrapper's first argument is supposed to be the path to rustc.
cmd.arg(rustc);
cmd
} else {
Command::new(rustc)
};

cmd.stderr(Stdio::null())
.arg("--edition=2018")
.arg("--crate-name=probe")
.arg("--crate-type=lib")
.arg("--out-dir")
.arg(out_dir)
.arg(probefile);

if let Some(target) = env::var_os("TARGET") {
cmd.arg("--target").arg(target);
}

// If Cargo wants to set RUSTFLAGS, use that.
if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") {
if !rustflags.is_empty() {
for arg in rustflags.split('\x1f') {
cmd.arg(arg);
}
}
}

cmd.status().ok()
}
12 changes: 6 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,15 @@
//!
//! List of currently implemented data structures:
//!
//! - [`Arc`](pool/singleton/arc/struct.Arc.html) -- Thread-safe reference-counting pointer backed by a memory pool
//! - [`Arc`](pool/arc/index.html) -- like `std::sync::Arc` but backed by a lock-free memory pool
//! rather than `#[global_allocator]`
//! - [`Box`](pool/boxed/index.html) -- like `std::boxed::Box` but backed by a lock-free memory pool
//! rather than `#[global_allocator]`
//! - [`BinaryHeap`](binary_heap/struct.BinaryHeap.html) -- priority queue
//! - [`IndexMap`](struct.IndexMap.html) -- hash table
//! - [`IndexSet`](struct.IndexSet.html) -- hash set
//! - [`LinearMap`](struct.LinearMap.html)
//! - [`Pool`](pool/struct.Pool.html) -- lock-free memory pool
//! - [`Object`](pool/object/index.html) -- objects managed by an object pool
//! - [`String`](struct.String.html)
//! - [`Vec`](struct.Vec.html)
//! - [`mpmc::Q*`](mpmc/index.html) -- multiple producer multiple consumer lock-free queue
Expand All @@ -75,16 +78,13 @@
#![deny(rust_2018_compatibility)]
#![deny(rust_2018_idioms)]
#![deny(warnings)]
#![deny(const_err)]

pub use binary_heap::BinaryHeap;
pub use deque::Deque;
pub use histbuf::{HistoryBuffer, OldestOrdered};
pub use indexmap::{Bucket, Entry, FnvIndexMap, IndexMap, OccupiedEntry, Pos, VacantEntry};
pub use indexset::{FnvIndexSet, IndexSet};
pub use linear_map::LinearMap;
#[cfg(all(has_cas, feature = "cas"))]
pub use pool::singleton::arc::Arc;
pub use string::String;
pub use vec::Vec;

Expand All @@ -110,7 +110,7 @@ pub mod binary_heap;
mod defmt;
#[cfg(all(has_cas, feature = "cas"))]
pub mod mpmc;
#[cfg(all(has_cas, feature = "cas"))]
#[cfg(any(arm_llsc, target_arch = "x86"))]
pub mod pool;
pub mod sorted_linked_list;
#[cfg(has_atomics)]
Expand Down
59 changes: 59 additions & 0 deletions src/pool.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//! Memory and object pools
//!
//! # Target support
//!
//! This module / API is only available on these compilation targets:
//!
//! - ARM architectures which instruction set include the LDREX, CLREX and STREX instructions, e.g.
//! `thumbv7m-none-eabi` but not `thumbv6m-none-eabi`
//! - 32-bit x86, e.g. `i686-unknown-linux-gnu`
//!
//! # Benchmarks
//!
//! - compilation settings
//! - `codegen-units = 1`
//! - `lto = 'fat'`
//! - `opt-level = 'z'`
//! - compilation target: `thumbv7em-none-eabihf`
//! - CPU: ARM Cortex-M4F
//!
//! - test program:
//!
//! ``` no_run
//! use heapless::box_pool;
//!
//! box_pool!(P: ()); // or `arc_pool!` or `object_pool!`
//!
//! bkpt();
//! let res = P.alloc(());
//! bkpt();
//!
//! if let Ok(boxed) = res {
//! bkpt();
//! drop(boxed);
//! bkpt();
//! }
//! # fn bkpt() {}
//! ```
//!
//! - measurement method: the cycle counter (CYCCNT) register was sampled each time a breakpoint
//! (`bkpt`) was hit. the difference between the "after" and the "before" value of CYCCNT yields the
//! execution time in clock cycles.
//!
//! | API | clock cycles |
//! |------------------------------|--------------|
//! | `BoxPool::alloc` | 23 |
//! | `pool::boxed::Box::drop` | 23 |
//! | `ArcPool::alloc` | 28 |
//! | `pool::arc::Arc::drop` | 59 |
//! | `ObjectPool::request` | 23 |
//! | `pool::object::Object::drop` | 23 |
//!
//! Note that the execution time won't include `T`'s initialization nor `T`'s destructor which will
//! be present in the general case for `Box` and `Arc`.

mod treiber;

pub mod arc;
pub mod boxed;
pub mod object;
Loading