1use core::ptr::NonNull;
5
6use crate::hal::mem::PhysAddr;
7
8use crate::error::Result;
9
10pub mod bestfit;
11
12#[cfg(any(feature = "metrics", metrics))]
14#[derive(Debug, Clone, Copy, Default)]
15pub struct Metrics {
16 pub total_bytes: usize,
17 pub free_bytes: usize,
18 pub free_blocks: usize,
19 pub alloc_count: u64,
20 pub free_count: u64,
21}
22
23#[cfg(any(feature = "metrics", metrics))]
24impl Metrics {
25 pub const fn new() -> Self {
26 Self {
27 total_bytes: 0,
28 free_bytes: 0,
29 free_blocks: 0,
30 alloc_count: 0,
31 free_count: 0,
32 }
33 }
34
35 pub fn allocated_bytes(&self) -> usize {
36 self.total_bytes.saturating_sub(self.free_bytes)
37 }
38
39 pub(crate) fn record_add_range(&mut self, total: usize, free: usize) {
40 self.total_bytes = self.total_bytes.saturating_add(total);
41 self.free_bytes = self.free_bytes.saturating_add(free);
42 self.free_blocks += 1;
43 }
44
45 pub(crate) fn record_alloc(&mut self, consumed_bytes: usize, blocks_removed: usize) {
46 self.free_bytes = self.free_bytes.saturating_sub(consumed_bytes);
47 self.free_blocks = self.free_blocks.saturating_sub(blocks_removed);
48 self.alloc_count += 1;
49 }
50
51 pub(crate) fn record_free(&mut self, added_bytes: usize) {
52 self.free_bytes = self.free_bytes.saturating_add(added_bytes);
53 self.free_blocks += 1;
54 self.free_count += 1;
55 }
56}
57
58#[cfg(target_pointer_width = "64")]
59pub const MAX_ADDR: usize = 2_usize.pow(48);
60
61#[cfg(target_pointer_width = "32")]
62pub const MAX_ADDR: usize = usize::MAX;
63
64pub trait Allocator {
74 unsafe fn malloc<T>(
75 &mut self,
76 size: usize,
77 align: usize,
78 request: Option<PhysAddr>,
79 ) -> Result<NonNull<T>>;
80 unsafe fn free<T>(&mut self, ptr: NonNull<T>, size: usize);
81}