1use super::descriptor::AllocationSlotDescriptor;
2use super::memory_manager::{
3 MEMORY_MANAGER_INVALID_ID, MEMORY_MANAGER_MAX_ID, MEMORY_MANAGER_MIN_ID,
4 MemoryManagerSlotError, validate_memory_manager_id,
5};
6use crate::constants::DIAGNOSTIC_STRING_MAX_BYTES;
7use serde::{Deserialize, Serialize};
8
9#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
14#[serde(deny_unknown_fields)]
15pub struct MemoryManagerIdRange {
16 pub(crate) start: u8,
17 pub(crate) end: u8,
18}
19
20impl MemoryManagerIdRange {
21 pub const fn new(start: u8, end: u8) -> Result<Self, MemoryManagerRangeError> {
23 if start > end {
24 return Err(MemoryManagerRangeError::InvalidRange { start, end });
25 }
26 if start == MEMORY_MANAGER_INVALID_ID {
27 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: start });
28 }
29 if end == MEMORY_MANAGER_INVALID_ID {
30 return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: end });
31 }
32 Ok(Self { start, end })
33 }
34
35 #[must_use]
37 pub const fn all_usable() -> Self {
38 Self {
39 start: MEMORY_MANAGER_MIN_ID,
40 end: MEMORY_MANAGER_MAX_ID,
41 }
42 }
43
44 #[must_use]
46 pub const fn contains(&self, id: u8) -> bool {
47 id >= self.start && id <= self.end
48 }
49
50 pub const fn validate(&self) -> Result<(), MemoryManagerRangeError> {
52 match Self::new(self.start, self.end) {
53 Ok(_) => Ok(()),
54 Err(err) => Err(err),
55 }
56 }
57
58 #[must_use]
60 pub const fn start(&self) -> u8 {
61 self.start
62 }
63
64 #[must_use]
66 pub const fn end(&self) -> u8 {
67 self.end
68 }
69}
70
71#[non_exhaustive]
76#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
77pub enum MemoryManagerRangeError {
78 #[error("MemoryManager ID range is invalid: start={start} end={end}")]
80 InvalidRange {
81 start: u8,
83 end: u8,
85 },
86 #[error("MemoryManager ID {id} is not a usable allocation slot")]
88 InvalidMemoryManagerId {
89 id: u8,
91 },
92}
93
94#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
101pub enum MemoryManagerRangeMode {
102 Reserved,
106 Allowed,
110}
111
112#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
117#[serde(deny_unknown_fields)]
118pub struct MemoryManagerAuthorityRecord {
119 pub(crate) range: MemoryManagerIdRange,
121 pub(crate) authority: String,
123 pub(crate) mode: MemoryManagerRangeMode,
125 pub(crate) purpose: Option<String>,
127}
128
129impl MemoryManagerAuthorityRecord {
130 pub fn new(
132 range: MemoryManagerIdRange,
133 authority: impl Into<String>,
134 mode: MemoryManagerRangeMode,
135 purpose: Option<String>,
136 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
137 let record = Self {
138 range,
139 authority: authority.into(),
140 mode,
141 purpose,
142 };
143 validate_authority_record(&record)?;
144 Ok(record)
145 }
146
147 #[must_use]
149 pub const fn range(&self) -> MemoryManagerIdRange {
150 self.range
151 }
152
153 #[must_use]
155 pub fn authority(&self) -> &str {
156 &self.authority
157 }
158
159 #[must_use]
161 pub const fn mode(&self) -> MemoryManagerRangeMode {
162 self.mode
163 }
164
165 #[must_use]
167 pub fn purpose(&self) -> Option<&str> {
168 self.purpose.as_deref()
169 }
170}
171
172#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
187#[serde(deny_unknown_fields)]
188pub struct MemoryManagerRangeAuthority {
189 authorities: Vec<MemoryManagerAuthorityRecord>,
190}
191
192impl MemoryManagerRangeAuthority {
193 #[must_use]
195 pub const fn new() -> Self {
196 Self {
197 authorities: Vec::new(),
198 }
199 }
200
201 pub fn from_records(
206 records: Vec<MemoryManagerAuthorityRecord>,
207 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
208 let mut authority = Self::new();
209 for record in records {
210 authority = authority.insert_record(record)?;
211 }
212 Ok(authority)
213 }
214
215 pub fn reserve(
220 self,
221 range: MemoryManagerIdRange,
222 authority: impl Into<String>,
223 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
224 self.reserve_with_purpose(range, authority, None)
225 }
226
227 pub fn reserve_ids(
232 self,
233 start: u8,
234 end: u8,
235 authority: impl Into<String>,
236 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
237 self.reserve(MemoryManagerIdRange::new(start, end)?, authority)
238 }
239
240 pub fn reserve_with_purpose(
245 self,
246 range: MemoryManagerIdRange,
247 authority: impl Into<String>,
248 purpose: Option<String>,
249 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
250 self.insert(range, authority, MemoryManagerRangeMode::Reserved, purpose)
251 }
252
253 pub fn reserve_ids_with_purpose(
258 self,
259 start: u8,
260 end: u8,
261 authority: impl Into<String>,
262 purpose: Option<String>,
263 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
264 self.reserve_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
265 }
266
267 pub fn allow(
272 self,
273 range: MemoryManagerIdRange,
274 authority: impl Into<String>,
275 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
276 self.allow_with_purpose(range, authority, None)
277 }
278
279 pub fn allow_ids(
284 self,
285 start: u8,
286 end: u8,
287 authority: impl Into<String>,
288 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
289 self.allow(MemoryManagerIdRange::new(start, end)?, authority)
290 }
291
292 pub fn allow_with_purpose(
297 self,
298 range: MemoryManagerIdRange,
299 authority: impl Into<String>,
300 purpose: Option<String>,
301 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
302 self.insert(range, authority, MemoryManagerRangeMode::Allowed, purpose)
303 }
304
305 pub fn allow_ids_with_purpose(
310 self,
311 start: u8,
312 end: u8,
313 authority: impl Into<String>,
314 purpose: Option<String>,
315 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
316 self.allow_with_purpose(MemoryManagerIdRange::new(start, end)?, authority, purpose)
317 }
318
319 pub fn validate_slot_authority(
321 &self,
322 slot: &AllocationSlotDescriptor,
323 expected_authority: &str,
324 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
325 let id = slot
326 .memory_manager_id()
327 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
328 self.validate_id_authority(id, expected_authority)
329 }
330
331 pub fn validate_slot_authority_mode(
333 &self,
334 slot: &AllocationSlotDescriptor,
335 expected_authority: &str,
336 expected_mode: MemoryManagerRangeMode,
337 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
338 let id = slot
339 .memory_manager_id()
340 .map_err(MemoryManagerRangeAuthorityError::Slot)?;
341 self.validate_id_authority_mode(id, expected_authority, expected_mode)
342 }
343
344 pub fn validate_id_authority(
346 &self,
347 id: u8,
348 expected_authority: &str,
349 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
350 validate_diagnostic_string("expected_authority", expected_authority)?;
351 let record = self.covering_record(id)?;
352
353 if record.authority != expected_authority {
354 return Err(MemoryManagerRangeAuthorityError::AuthorityMismatch {
355 id,
356 expected_authority: expected_authority.to_string(),
357 actual_authority: record.authority.clone(),
358 });
359 }
360
361 Ok(record)
362 }
363
364 pub fn validate_id_authority_mode(
366 &self,
367 id: u8,
368 expected_authority: &str,
369 expected_mode: MemoryManagerRangeMode,
370 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
371 let record = self.validate_id_authority(id, expected_authority)?;
372 if record.mode != expected_mode {
373 return Err(MemoryManagerRangeAuthorityError::ModeMismatch {
374 id,
375 authority: record.authority.clone(),
376 expected_mode,
377 actual_mode: record.mode,
378 });
379 }
380 Ok(record)
381 }
382
383 pub fn authority_for_id(
385 &self,
386 id: u8,
387 ) -> Result<Option<&MemoryManagerAuthorityRecord>, MemoryManagerRangeAuthorityError> {
388 validate_memory_manager_id(id).map_err(MemoryManagerRangeAuthorityError::Slot)?;
389 Ok(self
390 .authorities
391 .iter()
392 .find(|record| record.range.contains(id)))
393 }
394
395 #[must_use]
401 pub fn authorities(&self) -> &[MemoryManagerAuthorityRecord] {
402 &self.authorities
403 }
404
405 pub fn validate_complete_coverage(
411 &self,
412 target: MemoryManagerIdRange,
413 ) -> Result<(), MemoryManagerRangeAuthorityError> {
414 if self.authorities.is_empty() {
415 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
416 start: target.start(),
417 end: target.end(),
418 });
419 }
420
421 for record in &self.authorities {
422 if record.range.start() < target.start() || record.range.end() > target.end() {
423 return Err(
424 MemoryManagerRangeAuthorityError::RangeOutsideCoverageTarget {
425 start: record.range.start(),
426 end: record.range.end(),
427 target_start: target.start(),
428 target_end: target.end(),
429 },
430 );
431 }
432 }
433
434 let mut next_uncovered = u16::from(target.start());
435 let target_end = u16::from(target.end());
436 for record in &self.authorities {
437 let record_start = u16::from(record.range.start());
438 let record_end = u16::from(record.range.end());
439
440 if record_start > next_uncovered {
441 let start = u8::try_from(next_uncovered).map_err(|_| {
442 MemoryManagerRangeAuthorityError::MissingCoverage {
443 start: target.start(),
444 end: target.end(),
445 }
446 })?;
447 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
448 start,
449 end: record.range.start() - 1,
450 });
451 }
452
453 if record_end >= next_uncovered {
454 next_uncovered = record_end + 1;
455 }
456 }
457
458 if next_uncovered <= target_end {
459 let start = u8::try_from(next_uncovered).map_err(|_| {
460 MemoryManagerRangeAuthorityError::MissingCoverage {
461 start: target.start(),
462 end: target.end(),
463 }
464 })?;
465 return Err(MemoryManagerRangeAuthorityError::MissingCoverage {
466 start,
467 end: target.end(),
468 });
469 }
470
471 Ok(())
472 }
473
474 fn insert(
475 self,
476 range: MemoryManagerIdRange,
477 authority: impl Into<String>,
478 mode: MemoryManagerRangeMode,
479 purpose: Option<String>,
480 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
481 let record = MemoryManagerAuthorityRecord {
482 range,
483 authority: authority.into(),
484 mode,
485 purpose,
486 };
487 self.insert_record(record)
488 }
489
490 fn insert_record(
491 mut self,
492 record: MemoryManagerAuthorityRecord,
493 ) -> Result<Self, MemoryManagerRangeAuthorityError> {
494 validate_authority_record(&record)?;
495
496 for existing in &self.authorities {
497 if ranges_overlap(existing.range, record.range) {
498 return Err(MemoryManagerRangeAuthorityError::OverlappingRanges {
499 existing_start: existing.range.start(),
500 existing_end: existing.range.end(),
501 candidate_start: record.range.start(),
502 candidate_end: record.range.end(),
503 });
504 }
505 }
506
507 self.authorities.push(record);
508 self.authorities.sort_by_key(|record| record.range.start());
509 Ok(self)
510 }
511
512 fn covering_record(
513 &self,
514 id: u8,
515 ) -> Result<&MemoryManagerAuthorityRecord, MemoryManagerRangeAuthorityError> {
516 let Some(record) = self.authority_for_id(id)? else {
517 return Err(MemoryManagerRangeAuthorityError::UnclaimedId { id });
518 };
519 Ok(record)
520 }
521}
522
523fn validate_authority_record(
524 record: &MemoryManagerAuthorityRecord,
525) -> Result<(), MemoryManagerRangeAuthorityError> {
526 record.range.validate()?;
527 validate_diagnostic_string("authority", &record.authority)?;
528 if let Some(purpose) = &record.purpose {
529 validate_diagnostic_string("purpose", purpose)?;
530 }
531 Ok(())
532}
533
534#[non_exhaustive]
539#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
540pub enum MemoryManagerRangeAuthorityError {
541 #[error(transparent)]
543 Range(#[from] MemoryManagerRangeError),
544 #[error("{0}")]
546 Slot(#[from] MemoryManagerSlotError),
547 #[error(
549 "MemoryManager authority range {candidate_start}-{candidate_end} overlaps existing range {existing_start}-{existing_end}"
550 )]
551 OverlappingRanges {
552 existing_start: u8,
554 existing_end: u8,
556 candidate_start: u8,
558 candidate_end: u8,
560 },
561 #[error("{field} {reason}")]
563 InvalidDiagnosticString {
564 field: &'static str,
566 reason: &'static str,
568 },
569 #[error("MemoryManager ID {id} is not covered by an authority range")]
571 UnclaimedId {
572 id: u8,
574 },
575 #[error(
577 "MemoryManager ID {id} belongs to authority '{actual_authority}', not '{expected_authority}'"
578 )]
579 AuthorityMismatch {
580 id: u8,
582 expected_authority: String,
584 actual_authority: String,
586 },
587 #[error(
589 "MemoryManager ID {id} belongs to authority '{authority}' with mode {actual_mode:?}, not {expected_mode:?}"
590 )]
591 ModeMismatch {
592 id: u8,
594 authority: String,
596 expected_mode: MemoryManagerRangeMode,
598 actual_mode: MemoryManagerRangeMode,
600 },
601 #[error("MemoryManager authority coverage is missing range {start}-{end}")]
603 MissingCoverage {
604 start: u8,
606 end: u8,
608 },
609 #[error(
611 "MemoryManager authority range {start}-{end} is outside coverage target {target_start}-{target_end}"
612 )]
613 RangeOutsideCoverageTarget {
614 start: u8,
616 end: u8,
618 target_start: u8,
620 target_end: u8,
622 },
623}
624
625const fn ranges_overlap(left: MemoryManagerIdRange, right: MemoryManagerIdRange) -> bool {
626 left.start() <= right.end() && right.start() <= left.end()
627}
628
629fn validate_diagnostic_string(
630 field: &'static str,
631 value: &str,
632) -> Result<(), MemoryManagerRangeAuthorityError> {
633 if value.is_empty() {
634 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
635 field,
636 reason: "must not be empty",
637 });
638 }
639 if value.len() > DIAGNOSTIC_STRING_MAX_BYTES {
640 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
641 field,
642 reason: "must be at most 256 bytes",
643 });
644 }
645 if !value.is_ascii() {
646 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
647 field,
648 reason: "must be ASCII",
649 });
650 }
651 if value.bytes().any(|byte| byte.is_ascii_control()) {
652 return Err(MemoryManagerRangeAuthorityError::InvalidDiagnosticString {
653 field,
654 reason: "must not contain ASCII control characters",
655 });
656 }
657 Ok(())
658}