vk/memory/
virtual_block.rs1use super::{AllocError, tlsf::Tlsf};
17use std::sync::Arc;
18
19#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
21pub enum PlacementStrategy {
22 #[default]
23 Default,
24 MinMemory,
25 MinTime,
26 MinOffset,
27}
28
29pub struct VirtualAllocation {
31 owner: Arc<()>,
32 index: usize,
33 serial: u64,
34}
35
36#[derive(Clone, Copy, Debug, PartialEq, Eq)]
38pub struct VirtualAllocationInfo {
39 pub offset: u64,
40 pub size: u64,
41}
42
43#[derive(Clone, Copy, Debug, PartialEq, Eq)]
45pub struct VirtualBlockStats {
46 pub size: u64,
47 pub allocation_count: usize,
48 pub allocated_bytes: u64,
49 pub free_bytes: u64,
50 pub free_region_count: usize,
51 pub largest_free_region: u64,
52}
53
54pub struct VirtualBlock {
59 owner: Arc<()>,
60 metadata: Tlsf,
61}
62
63impl VirtualBlock {
64 pub fn new(size: u64) -> Result<Self, AllocError> {
65 Ok(Self {
66 owner: Arc::new(()),
67 metadata: Tlsf::new(size)?,
68 })
69 }
70
71 pub fn allocate(
73 &mut self,
74 size: u64,
75 alignment: u64,
76 strategy: PlacementStrategy,
77 ) -> Result<VirtualAllocation, AllocError> {
78 allocate(self, size, alignment, strategy)
79 }
80
81 pub fn free(&mut self, allocation: &mut VirtualAllocation) -> Result<(), AllocError> {
83 free(self, allocation)
84 }
85
86 pub fn allocation_info(
88 &self,
89 allocation: &VirtualAllocation,
90 ) -> Result<VirtualAllocationInfo, AllocError> {
91 allocation_info(self, allocation)
92 }
93
94 pub fn clear(&mut self) {
97 clear(self)
98 }
99
100 pub fn statistics(&self) -> VirtualBlockStats {
102 statistics(self)
103 }
104}
105
106pub fn allocate(
111 block: &mut VirtualBlock,
112 size: u64,
113 alignment: u64,
114 strategy: PlacementStrategy,
115) -> Result<VirtualAllocation, AllocError> {
116 let (index, serial) = block.metadata.allocate(size, alignment, strategy)?;
117 Ok(VirtualAllocation {
118 owner: block.owner.clone(),
119 index,
120 serial,
121 })
122}
123
124pub fn allocation_info(
126 block: &VirtualBlock,
127 allocation: &VirtualAllocation,
128) -> Result<VirtualAllocationInfo, AllocError> {
129 if !Arc::ptr_eq(&block.owner, &allocation.owner) {
130 return Err(AllocError::WrongAllocator);
131 }
132 block.metadata.info(allocation.index, allocation.serial)
133}
134
135pub fn free(
137 block: &mut VirtualBlock,
138 allocation: &mut VirtualAllocation,
139) -> Result<(), AllocError> {
140 allocation_info(block, allocation)?;
141 block.metadata.free(allocation.index, allocation.serial)?;
142 allocation.index = usize::MAX;
143 Ok(())
144}
145
146pub fn clear(block: &mut VirtualBlock) {
148 block.metadata.clear()
149}
150
151pub fn statistics(block: &VirtualBlock) -> VirtualBlockStats {
153 block.metadata.statistics()
154}