1use customizable_buddy::{BuddyAllocator, BuddyCollection, BuddyLine, OligarchyCollection};
2use std::{collections::BTreeSet, fmt, mem::MaybeUninit, ptr::NonNull};
3
4fn main() {
5 let mut allocator = BuddyAllocator::<16, BuddySet, BuddySet>::new();
6 allocator.init(12, non_null(0x1000));
7 println!();
8 assert!(allocator.allocate_type::<usize>().is_err());
9 println!();
10 unsafe { allocator.transfer(non_null(0x1000), 0x7fff_f000) };
11
12 println!();
13 println!("A {allocator:?}");
14 let (ptr0, size0) = allocator.allocate_type::<[u8; 2048]>().unwrap();
15 println!("B {allocator:?}");
16 let (ptr1, size1) = allocator.allocate_type::<[u8; 4096]>().unwrap();
17 println!("C {allocator:?}");
18 let (ptr2, size2) = allocator.allocate_type::<[u8; 4096 * 3 - 100]>().unwrap();
19 println!("D {allocator:?}");
20
21 assert_eq!(4096, size0);
22 assert_eq!(4096, size1);
23 assert_eq!(4096 * 3, size2);
24
25 println!();
26 println!("{allocator:?}");
27 allocator.deallocate(ptr0, size0);
28 println!("{allocator:?}");
29 allocator.deallocate(ptr1, size1);
30 println!("{allocator:?}");
31 allocator.deallocate(ptr2, size2);
32 println!("{allocator:?}");
33}
34
35#[inline]
36fn non_null(addr: usize) -> NonNull<u8> {
37 NonNull::new(addr as *mut _).unwrap()
38}
39
40struct BuddySet {
41 set: MaybeUninit<BTreeSet<usize>>,
42 order: usize,
43}
44
45impl BuddyLine for BuddySet {
46 const EMPTY: Self = Self {
47 set: MaybeUninit::uninit(),
48 order: 0,
49 };
50
51 fn init(&mut self, order: usize, base: usize) {
52 self.order = order;
53 println!("Buddies[{order}] init as base = {base} order = {order}");
54 }
55
56 fn take(&mut self, idx: usize) -> bool {
57 println!("Buddies[{}] take at {idx}", self.order);
58 unsafe { self.set.assume_init_mut() }.remove(&idx)
59 }
60}
61
62impl OligarchyCollection for BuddySet {
63 fn take_any(&mut self, align_order: usize, count: usize) -> Option<usize> {
64 println!(
65 "Buddies[{}] take {count} with align = {align_order}",
66 self.order
67 );
68 assert!(count == 1);
69 let set = unsafe { self.set.assume_init_mut() };
70 set.iter().next().copied().map(|i| {
71 set.remove(&i);
72 i
73 })
74 }
75
76 fn put(&mut self, idx: usize) {
77 println!("Buddies[{}] put oligarchy at {idx}", self.order);
78
79 unsafe { self.set.assume_init_mut() }.insert(idx);
80 }
81}
82
83impl BuddyCollection for BuddySet {
84 fn take_any(&mut self, align_order: usize) -> Option<usize> {
85 println!("Buddies[{}] take 1 with align = {align_order}", self.order);
86 let set = unsafe { self.set.assume_init_mut() };
87 set.iter().next().copied().map(|i| {
88 set.remove(&i);
89 i
90 })
91 }
92
93 fn put(&mut self, idx: usize) -> Option<usize> {
94 println!("Buddies[{}] put buddy at = {idx}", self.order);
95 let set = unsafe { self.set.assume_init_mut() };
96 if set.remove(&(idx ^ 1)) {
97 Some(idx >> 1)
98 } else {
99 set.insert(idx);
100 None
101 }
102 }
103}
104
105impl fmt::Debug for BuddySet {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 write!(f, "{:?}", unsafe { self.set.assume_init_ref() })
108 }
109}