sim_lib_compute_wgpu/
arena.rs1use std::collections::VecDeque;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
7pub struct WgpuAllocationId(u64);
8
9#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct WgpuArenaAllocation {
12 pub id: WgpuAllocationId,
14 pub bytes: u64,
16}
17
18#[derive(Clone, Debug)]
19struct LiveAllocation {
20 allocation: WgpuArenaAllocation,
21 active: bool,
22}
23
24#[derive(Clone, Debug, Default, PartialEq, Eq)]
26pub struct WgpuArenaSnapshot {
27 pub live_allocations: usize,
29 pub resident_bytes: u64,
31 pub evictions: usize,
33}
34
35#[derive(Clone, Debug)]
37pub struct WgpuResidentArena {
38 max_bytes: u64,
39 next_id: u64,
40 resident_bytes: u64,
41 evictions: usize,
42 allocations: VecDeque<LiveAllocation>,
43}
44
45impl WgpuResidentArena {
46 pub fn new(max_bytes: u64) -> Self {
48 Self {
49 max_bytes,
50 next_id: 0,
51 resident_bytes: 0,
52 evictions: 0,
53 allocations: VecDeque::new(),
54 }
55 }
56
57 pub fn allocate(&mut self, bytes: u64) -> Result<WgpuArenaAllocation, String> {
59 if bytes > self.max_bytes {
60 return Err("wgpu resident allocation exceeds arena".to_owned());
61 }
62 while self.resident_bytes.saturating_add(bytes) > self.max_bytes {
63 let Some(mut allocation) = self.allocations.pop_front() else {
64 break;
65 };
66 if allocation.active {
67 allocation.active = false;
68 self.resident_bytes = self
69 .resident_bytes
70 .saturating_sub(allocation.allocation.bytes);
71 self.evictions += 1;
72 }
73 self.allocations.push_back(allocation);
74 }
75 self.next_id += 1;
76 let allocation = WgpuArenaAllocation {
77 id: WgpuAllocationId(self.next_id),
78 bytes,
79 };
80 self.resident_bytes += bytes;
81 self.allocations.push_back(LiveAllocation {
82 allocation: allocation.clone(),
83 active: true,
84 });
85 Ok(allocation)
86 }
87
88 pub fn contains(&self, id: WgpuAllocationId) -> bool {
90 self.allocations
91 .iter()
92 .any(|allocation| allocation.active && allocation.allocation.id == id)
93 }
94
95 pub fn snapshot(&self) -> WgpuArenaSnapshot {
97 WgpuArenaSnapshot {
98 live_allocations: self
99 .allocations
100 .iter()
101 .filter(|allocation| allocation.active)
102 .count(),
103 resident_bytes: self.resident_bytes,
104 evictions: self.evictions,
105 }
106 }
107}