1use crate::Size;
2use hal::memory::Properties;
3
4#[derive(Clone, Copy, Debug)]
6pub struct MemoryUtilization {
7 pub used: Size,
9 pub effective: Size,
11}
12
13#[derive(Clone, Copy, Debug)]
15pub struct MemoryHeapUtilization {
16 pub utilization: MemoryUtilization,
18
19 pub size: Size,
21}
22
23#[derive(Clone, Copy, Debug)]
25pub struct MemoryTypeUtilization {
26 pub utilization: MemoryUtilization,
28
29 pub properties: Properties,
31
32 pub heap_index: usize,
34}
35
36#[derive(Clone, Debug)]
38pub struct TotalMemoryUtilization {
39 pub types: Vec<MemoryTypeUtilization>,
41
42 pub heaps: Vec<MemoryHeapUtilization>,
44}
45
46impl std::fmt::Display for TotalMemoryUtilization {
47 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 const MB: Size = 1024 * 1024;
49
50 writeln!(fmt, "!!! Memory utilization !!!")?;
51 for (index, heap) in self.heaps.iter().enumerate() {
52 let size = heap.size;
53 let MemoryUtilization { used, effective } = heap.utilization;
54 let usage_basis_points = used * 10000 / size;
55 let fill = if usage_basis_points > 10000 {
56 50
58 } else {
59 (usage_basis_points / 200) as usize
60 };
61 let effective_basis_points = if used > 0 {
62 effective * 10000 / used
63 } else {
64 10000
65 };
66
67 let line = "|".repeat(fill) + &(" ".repeat(50 - fill));
68 writeln!(
69 fmt,
70 "Heap {}:\n{:6} / {:<6} or{} {{ effective:{} }} [{}]",
71 format!("{}", index),
72 format!("{}MB", used / MB),
73 format!("{}MB", size / MB),
74 format_basis_points(usage_basis_points),
75 format_basis_points(effective_basis_points),
76 line
77 )?;
78
79 for ty in self.types.iter().filter(|ty| ty.heap_index == index) {
80 let properties = ty.properties;
81 let MemoryUtilization { used, effective } = ty.utilization;
82 let usage_basis_points = used * 10000 / size;
83 let effective_basis_points = if used > 0 {
84 effective * 10000 / used
85 } else {
86 0
87 };
88
89 writeln!(
90 fmt,
91 " {:>6} or{} {{ effective:{} }} | {:?}",
92 format!("{}MB", used / MB),
93 format_basis_points(usage_basis_points),
94 format_basis_points(effective_basis_points),
95 properties,
96 )?;
97 }
98 }
99
100 Ok(())
101 }
102}
103
104fn format_basis_points(basis_points: Size) -> String {
105 debug_assert!(basis_points <= 10000);
106 format!("{:>3}.{:02}%", basis_points / 100, basis_points % 100)
107}