1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
//!
//! 提供内存池管理机制, 支持从堆上动态分配,或者事先分配的一块内存空间,可能在堆上也可能在栈上.
//!
//! # Examples
//!
//! 简单类型,直接传递初始值,会有一次拷贝
//! ```rust
//! use hipool::{ MemPool, Boxed};
//! let pool = MemPool::new(0);
//! let psize = Boxed::new_in(&pool, 100).unwrap();
//! assert_eq!(*psize, 100);
//! ```
//!
//! 复杂类型,避免拷贝的一种方式:
//! ```rust
//! use core::ptr;
//! use hipool::{ MemPool, Boxed};
//! use core::mem::MaybeUninit;
//!
//! let pool = MemPool::new(0);
//! struct Foo {
//! val: i32,
//! }
//! let foo = Boxed::new_then_in(&pool, | obj: &mut MaybeUninit<Foo> | {
//! let obj = obj.as_mut_ptr();
//! unsafe {
//! ptr::addr_of_mut!((*obj).val).write(100);
//! }
//! Ok(())
//! }).unwrap();
//! assert_eq!(foo.val, 100);
//! ```
//!
//! 有时候需要在栈上分配数据,需要把栈空间适配为Pool接口,则可使用BufPool完成适配
//!
//! ```rust
//! use hipool::{ BufPool, Boxed};
//! let mut buf = [0_u8; 100];
//! let mut pool = BufPool::new(&mut buf);
//! let psize = Boxed::new_in(&pool, 100).unwrap();
//! assert_eq!(*psize, 100);
//! ```
//!
//! 有时候分配的Pool也需要在堆上,可以用另外的构造方式,如下:
//!
//! ```rust
//! use hipool::{ MemPool, Boxed };
//! use core::mem::MaybeUninit;
//!
//! let mut pool = MemPool::new_boxed(0).unwrap();
//! let int_array = Boxed::new_slice_then_in(&*pool, 100, |_, ele: &mut MaybeUninit<i32>| {
//! ele.write(0);
//! Ok(())
//! }).unwrap();
//! int_array.iter().for_each(|n| assert_eq!(*n, 0));
//! ```
//!
//! 更多的调用接口
//!
//! ```rust
//! use hipool::{ MemPool, Boxed };
//! use core::mem::MaybeUninit;
//! use core::alloc::Layout;
//!
//! let pool = MemPool::new_boxed(0).unwrap();
//!
//! let val = Boxed::new_in(&*pool, 1).unwrap();
//! assert_eq!(*val, 1);
//!
//! let val = Boxed::new_in(&*pool, 0).unwrap();
//! assert_eq!(*val, 0);
//!
//! let val = Boxed::new_then_in(&*pool, |val: &mut MaybeUninit<i32>| {
//! val.write(100);
//! Ok(())
//! }).unwrap();
//! assert_eq!(*val, 100);
//!
//! let ivals = [0, 1, 2, 3];
//! let vals = Boxed::uninit_slice_in::<i32>(&*pool, ivals.len()).unwrap();
//! let vals = vals.write_slice_then(|n, uninit| {uninit.write(ivals[n]); Ok(())}).unwrap();
//! assert_eq!(vals[0], 0);
//! assert_eq!(vals[1], 1);
//! assert_eq!(vals[2], 2);
//! assert_eq!(vals[3], 3);
//!
//! let vals = unsafe { Boxed::new_buf_in(&*pool,
//! Layout::array::<i32>(2).unwrap()).unwrap().cast_slice::<i32>(2) };
//! vals.iter().for_each(|val| println!(" {:?} ", val));
//!
//! let vals = Boxed::new_slice_then_in(&*pool, 2, | n, val: &mut MaybeUninit<i32> | {
//! val.write(n as i32);
//! Ok(())
//! }).unwrap();
//! assert_eq!(vals[0], 0);
//! assert_eq!(vals[1], 1);
//! ```
//!
#![no_std]
pub use hierr::{Error, prelude};
mod boxed;
mod buf;
mod mem;
pub(crate) mod util;
mod alloc;
pub use crate::boxed::Boxed;
pub use crate::buf::Pool as BufPool;
pub use crate::buf::BoxedPool as BoxedBufPool;
pub use crate::mem::Pool as MemPool;
pub use crate::mem::BoxedPool as BoxedMemPool;
pub use alloc::*;
mod rc;
pub use rc::*;
mod arc;
pub use arc::*;
#[cfg(test)]
mod test {
use crate::{Boxed, BufPool, MemPool};
struct Foo {
val: usize,
}
static mut DROP_CNT: usize = 0;
impl Drop for Foo {
fn drop(&mut self) {
unsafe { DROP_CNT += self.val };
}
}
#[test]
fn test_mem_drop() {
let pool = MemPool::new(0);
unsafe {
DROP_CNT = 0;
}
{
let _ = Boxed::new_in(&pool, Foo { val: 100 });
}
unsafe {
assert_eq!(100, DROP_CNT);
}
}
#[test]
fn test_buf_drop() {
let mut buf = [0_u8; 100];
let pool = BufPool::new(&mut buf);
unsafe {
DROP_CNT = 0;
}
{
let _ = Boxed::new_in(&pool, Foo { val: 100 });
}
unsafe {
assert_eq!(100, DROP_CNT);
}
}
#[test]
fn test_static() {
let pool = MemPool::new_boxed(0).unwrap();
let pool = pool.leak();
let x: Boxed<'static, i32, &'static MemPool> = Boxed::new_in(&*pool, 100).unwrap();
assert_eq!(*x, 100);
}
}