alloc_tester/
alloc-tester.rs1extern crate std;
2
3use std::alloc::Layout;
4use std::ffi::c_char as char;
5
6use ialloc::*;
7use ialloc::allocator::*;
8
9
10
11struct Test<A> {
12 pub name: &'static str,
13 pub create: fn()->A,
14 pub thin: Option<AlignmentRange>,
15 pub fat: Option<AlignmentRange>,
16}
17
18#[derive(Clone, Copy, Debug)] struct AlignmentRange {
19 pub min: Alignment,
20 pub max: Alignment,
21}
22
23impl<A> Test<A> {
24 pub fn new(name: &'static str, create: fn()->A) -> Self {
25 Self { name, create, thin: None, fat: None }
26 }
27
28 pub fn thin(&mut self) -> &mut Self where A : thin::Alloc + thin::Free {
29 let mut thin = AlignmentRange { min: Alignment::MAX, max: Alignment::MAX };
30 for (dst, min_size) in [(&mut thin.min, 1), (&mut thin.max, 4096)] {
31 for _ in 0 .. 100 {
32 let alloc = (self.create)();
33 let addrs = [(); 4096].into_iter().enumerate().map(|(i, _)| alloc.alloc_uninit(i%16+min_size).unwrap()).collect::<Vec<_>>();
34 let addrbits = addrs[..].iter().copied().map(|addr| addr.as_ptr() as usize).reduce(|x,y| x|y).unwrap();
35 addrs.iter().copied().for_each(|addr| unsafe { alloc.free(addr) });
36 let align = Alignment::new(1 << addrbits.trailing_zeros()).unwrap();
37 *dst = align.min(*dst);
38 }
39 }
40 self.thin = Some(thin);
41 self
42 }
43
44 pub fn fat(&mut self) -> &mut Self where A : fat::Alloc + fat::Free {
45 let mut fat = AlignmentRange { min: Alignment::MAX, max: ALIGN_1 };
46
47 for _ in 0 .. 100 {
48 let layout = Layout::new::<u8>(); let alloc = (self.create)();
50 let addrs = [(); 4096].map(|_| alloc.alloc_uninit(layout).unwrap());
51 let addrbits = addrs[..].iter().copied().map(|addr| addr.as_ptr() as usize).reduce(|x,y| x|y).unwrap();
52 addrs.iter().copied().for_each(|addr| unsafe { alloc.free(addr, layout) });
53 let align = Alignment::new(1 << addrbits.trailing_zeros()).unwrap();
54 fat.min = align.min(fat.min);
55 }
56
57 fat.max = fat.min;
58 let alloc = (self.create)();
59 while let Some(next) = fat.max.as_usize().checked_shl(1) {
60 let Some(align) = Alignment::new(next) else { break };
61 let Ok(layout) = Layout::from_size_align(next, next) else { break };
62 let Ok(addr) = alloc.alloc_uninit(layout) else { break };
63 fat.max = align;
64 unsafe { alloc.free(addr, layout) };
65 }
66
67 self.fat = Some(fat);
68 self
69 }
70
71 pub fn print(&self) {
72 let name = self.name;
73 let thin = self.thin.map_or_else(|| format!(""), |t| if t.min == t.max { format!("{:?}", t.min) } else { format!("{:?} ..= {:?}", t.min, t.max) });
74 let fat = self.fat .map_or_else(|| format!(""), |t| if t.min == t.max { format!("{:?}", t.min) } else { format!("{:?} ..= {:?}", t.min, t.max) });
75 println!("{name: <25}{thin: <20}{fat: <20}");
76 }
77}
78
79fn main() {
80 println!("{: <25}{: <20}{: <20}", "", "thin::Alloc", "fat::Alloc", );
81 println!("{: <25}{: <20}{: <20}", "Allocator", "Alignment", "Alignment", );
82 println!("{:=<65}", "");
83 #[cfg(feature = "alloc")] Test::new("Global", || alloc::Global ) .fat().print();
84 #[cfg(c89)] Test::new("Malloc", || c::Malloc ).thin().fat().print();
85 #[cfg(c89)] Test::new("AlignedMalloc", || c::AlignedMalloc ) .fat().print();
86 #[cfg(cpp98)] Test::new("NewDelete", || cpp::NewDelete ).thin().fat().print();
87 #[cfg(cpp98)] Test::new("NewDeleteArray", || cpp::NewDeleteArray ).thin().fat().print();
88 #[cfg(cpp17)] Test::new("NewDeleteAligned", || cpp::NewDeleteAligned ) .fat().print();
89 #[cfg(cpp17)] Test::new("NewDeleteArrayAligned", || cpp::NewDeleteArrayAligned ) .fat().print();
90 #[cfg(cpp98)] Test::new("StdAllocator<char>", || cpp::StdAllocator::<char>::new() ) .fat().print();
91 #[cfg(all(windows, feature = "win32"))] {
92 println!();
93 println!("win32:");
94 Test::new("ProcessHeap", || win32::ProcessHeap ).thin().fat().print();
95 Test::new("Global", || win32::Global ).thin().fat().print();
96 Test::new("Local", || win32::Local ).thin().fat().print();
97 Test::new("CryptMem", || win32::CryptMem ).thin().fat().print();
98 Test::new("CoTaskMem", || win32::CoTaskMem ).thin().fat().print();
99 Test::new("VirtualCommit", || win32::VirtualCommit ).thin().fat().print();
100 }
101}