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