1use customizable_buddy::{BuddyAllocator, BuddyError, LinkedListBuddy, UsizeBuddy};
2use std::{
3 alloc::Layout,
4 ptr::{null_mut, NonNull},
5 time::Instant,
6};
7
8type Allocator<const N: usize> = BuddyAllocator<N, UsizeBuddy, LinkedListBuddy>;
9
10#[repr(C, align(4096))]
11struct Page([u8; 4096]);
12
13impl Page {
14 const ZERO: Self = Self([0; 4096]);
15}
16
17static mut MEMORY: [Page; 65536] = [Page::ZERO; 65536];
19
20fn main() -> Result<(), BuddyError> {
21 let mut allocator = Allocator::<12>::new();
22 let ptr = NonNull::new(unsafe { MEMORY.as_mut_ptr() }).unwrap();
23 let len = core::mem::size_of_val(unsafe { &MEMORY });
24 allocator.init(12, ptr);
25 println!(
26 "MEMORY: {:#x}..{:#x}",
27 ptr.as_ptr() as usize,
28 ptr.as_ptr() as usize + len
29 );
30 let t = Instant::now();
31 unsafe { allocator.transfer(ptr, len) };
32 println!("transfer {:?}", t.elapsed());
33
34 assert_eq!(len, allocator.capacity());
35 assert_eq!(len, allocator.free());
36
37 println!(
38 "
39BEFORE
40{allocator:#x?}"
41 );
42
43 let mut blocks = [null_mut::<Page>(); 65536];
44 let layout = Layout::new::<Page>();
45 let t = Instant::now();
46 for block in blocks.iter_mut() {
47 let (ptr, size) = allocator.allocate_type::<Page>()?;
48 debug_assert_eq!(layout.size(), size);
49 *block = ptr.as_ptr();
50 }
51 let ta = t.elapsed();
52
53 println!(
54 "
55EMPTY
56{allocator:#x?}"
57 );
58
59 assert_eq!(len, allocator.capacity());
60 assert_eq!(len - blocks.len() * layout.size(), allocator.free());
61
62 let t = Instant::now();
63 for block in blocks.iter_mut() {
64 allocator.deallocate(NonNull::new(*block).unwrap(), layout.size());
65 *block = null_mut();
66 }
67 let td = t.elapsed();
68
69 assert_eq!(len, allocator.capacity());
70 assert_eq!(len, allocator.free());
71
72 println!(
73 "
74AFTER
75{allocator:#x?}"
76 );
77
78 println!(
79 "allocate {:?} ({} times)",
80 ta / blocks.len() as u32,
81 blocks.len()
82 );
83 println!(
84 "deallocate {:?} ({} times)",
85 td / blocks.len() as u32,
86 blocks.len()
87 );
88
89 Ok(())
90}