1pub mod header_store;
19pub mod manager;
20pub mod static_manager;
21
22#[cfg(feature = "alloc")]
23pub mod heap_manager;
24
25#[cfg(feature = "std")]
26pub mod concurrent_manager;
27
28#[non_exhaustive]
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
31pub enum MemoryClass {
32 Host,
34 PinnedHost,
36 Device(u8),
38 Shared,
40}
41
42#[allow(clippy::derivable_impls)]
43impl Default for MemoryClass {
44 fn default() -> Self {
45 MemoryClass::Host
46 }
47}
48
49const HOST_BIT: u32 = 0;
52const PINNED_HOST_BIT: u32 = 1;
53const DEVICE_BASE_BIT: u32 = 2;
54const DEVICE_MAX_ORDINAL: u8 = 15; const SHARED_BIT: u32 = 18;
56
57const fn device_bit(ordinal: u8) -> u32 {
58 DEVICE_BASE_BIT + ordinal as u32
59}
60
61const DEVICE_MASK: u32 = {
62 ((1u32 << ((DEVICE_MAX_ORDINAL as u32) + 1)) - 1) << DEVICE_BASE_BIT
64};
65
66#[non_exhaustive]
70#[derive(Debug, Clone, Copy, PartialEq, Eq)]
71pub struct PlacementAcceptance {
72 bits: u32,
73}
74
75impl Default for PlacementAcceptance {
76 fn default() -> Self {
77 Self::empty().with_host()
79 }
80}
81
82impl PlacementAcceptance {
83 #[inline]
85 pub const fn empty() -> Self {
86 Self { bits: 0 }
87 }
88
89 #[inline]
91 pub const fn from_bits(bits: u32) -> Self {
92 Self { bits }
93 }
94
95 #[inline]
97 pub const fn bits(&self) -> &u32 {
98 &self.bits
99 }
100
101 #[inline]
103 pub const fn is_empty(&self) -> bool {
104 self.bits == 0
105 }
106
107 #[inline]
109 pub const fn union(self, other: Self) -> Self {
110 Self {
111 bits: self.bits | other.bits,
112 }
113 }
114
115 #[inline]
117 pub const fn intersect(self, other: Self) -> Self {
118 Self {
119 bits: self.bits & other.bits,
120 }
121 }
122
123 #[inline]
125 pub const fn contains(self, other: Self) -> bool {
126 (self.bits & other.bits) == other.bits
127 }
128
129 #[inline]
131 pub const fn host_all() -> Self {
132 Self::empty().with_host().with_pinned_host()
133 }
134
135 #[inline]
137 pub const fn with_host(mut self) -> Self {
138 self.bits |= 1 << HOST_BIT;
139 self
140 }
141
142 #[inline]
144 pub const fn with_pinned_host(mut self) -> Self {
145 self.bits |= 1 << PINNED_HOST_BIT;
146 self
147 }
148
149 #[inline]
151 pub const fn with_device(mut self, ordinal: u8) -> Self {
152 let o = (ordinal & DEVICE_MAX_ORDINAL) as u32;
154 self.bits |= 1 << (DEVICE_BASE_BIT + o);
155 self
156 }
157
158 #[inline]
160 pub const fn try_with_device(self, ordinal: u8) -> Option<Self> {
161 if ordinal <= DEVICE_MAX_ORDINAL {
162 Some(self.with_device(ordinal))
163 } else {
164 None
165 }
166 }
167
168 #[inline]
170 pub const fn with_all_devices(mut self) -> Self {
171 self.bits |= DEVICE_MASK;
172 self
173 }
174
175 #[inline]
177 pub const fn with_shared(mut self) -> Self {
178 self.bits |= 1 << SHARED_BIT;
179 self
180 }
181
182 #[inline]
184 pub const fn accepts(&self, class: MemoryClass) -> bool {
185 match class {
186 MemoryClass::Host => (self.bits & (1 << HOST_BIT)) != 0,
187 MemoryClass::PinnedHost => (self.bits & (1 << PINNED_HOST_BIT)) != 0,
188 MemoryClass::Device(o) => {
189 let o = (o & DEVICE_MAX_ORDINAL) as u32;
190 (self.bits & (1 << device_bit(o as u8))) != 0
191 }
192 MemoryClass::Shared => (self.bits & (1 << SHARED_BIT)) != 0,
193 }
194 }
195
196 #[inline]
198 pub const fn exactly(class: MemoryClass) -> Self {
199 match class {
200 MemoryClass::Host => Self::empty().with_host(),
201 MemoryClass::PinnedHost => Self::empty().with_pinned_host(),
202 MemoryClass::Device(o) => Self::empty().with_device(o),
203 MemoryClass::Shared => Self::empty().with_shared(),
204 }
205 }
206}
207
208#[non_exhaustive]
213#[derive(Debug, Clone, Copy, PartialEq, Eq)]
214pub struct BufferDescriptor {
215 bytes: usize,
217}
218
219impl BufferDescriptor {
220 #[inline]
222 pub const fn new(bytes: usize) -> Self {
223 Self { bytes }
224 }
225
226 #[inline]
228 pub const fn bytes(&self) -> &usize {
229 &self.bytes
230 }
231}
232
233#[non_exhaustive]
235#[derive(Debug, Clone, Copy, PartialEq, Eq)]
236pub enum PlacementDecision {
237 ZeroCopy,
239 AdaptRequired,
241}
242
243#[inline]
245pub const fn decide_placement(
246 acceptance: PlacementAcceptance,
247 current: MemoryClass,
248) -> PlacementDecision {
249 if acceptance.accepts(current) {
250 PlacementDecision::ZeroCopy
251 } else {
252 PlacementDecision::AdaptRequired
253 }
254}