swage_core/memory/
consec_blocks.rs1use std::{collections::VecDeque, ops::Range};
2
3use crate::memory::{BytePointer, GetConsecPfns};
4
5use crate::memory::{Memory, PhysAddr, VictimMemory};
6
7#[derive(Clone, Debug)]
13pub struct ConsecBlocks {
14 pub blocks: Vec<Memory>,
16}
17
18impl ConsecBlocks {
19 pub fn new(blocks: Vec<Memory>) -> Self {
25 ConsecBlocks { blocks }
26 }
27
28 pub fn dealloc(self) {
32 for block in self.blocks {
33 block.dealloc();
34 }
35 }
36}
37
38impl VictimMemory for ConsecBlocks {}
39
40impl BytePointer for ConsecBlocks {
41 fn addr(&self, offset: usize) -> *mut u8 {
42 assert!(offset < self.len(), "Offset {} >= {}", offset, self.len());
43 let mut offset = offset;
44 for block in &self.blocks {
45 if offset < block.len {
46 return block.addr(offset);
47 }
48 offset -= block.len;
49 }
50 unreachable!("block not found for offset 0x{:x}", offset);
51 }
52
53 fn ptr(&self) -> *mut u8 {
54 self.blocks.first().unwrap().ptr()
55 }
56
57 fn len(&self) -> usize {
58 self.blocks.iter().map(|block| block.len).sum()
59 }
60}
61
62impl GetConsecPfns for ConsecBlocks {
63 fn consec_pfns(&self) -> Result<Vec<Range<PhysAddr>>, crate::memory::memblock::Error> {
64 let mut pfns = vec![];
65 for block in &self.blocks {
66 let mut block_pfns = VecDeque::from(block.consec_pfns()?);
67 let is_cons = pfns
68 .last()
69 .is_some_and(|last: &Range<PhysAddr>| last.start == block_pfns[0].end);
70 if is_cons {
71 let prev = pfns.pop();
72 let next = block_pfns.pop_front();
73 pfns.push(prev.unwrap().start..next.unwrap().end);
74 }
75 pfns.extend(block_pfns);
76 }
77 Ok(pfns)
78 }
79}