1#![allow(clippy::bad_bit_mask)] use crate::{Event, MonotonicDuration, NullableHandle, ObjectQuery, Status, Topic, ok};
10use bitflags::bitflags;
11use zx_sys::{self as sys, ZX_MAX_NAME_LEN, zx_duration_mono_t, zx_duration_t};
12
13#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
17#[repr(transparent)]
18pub struct Resource(NullableHandle);
19impl_handle_based!(Resource);
20
21sys::zx_info_kmem_stats_t!(MemStats);
22sys::zx_info_kmem_stats_extended_t!(MemStatsExtended);
23sys::zx_info_kmem_stats_compression_t!(MemStatsCompression);
24sys::zx_info_cpu_stats_t!(PerCpuStats);
25sys::zx_info_resource_t!(ResourceInfo);
26sys::zx_info_memory_stall_t!(MemoryStall);
27
28impl From<sys::zx_info_kmem_stats_t> for MemStats {
29 fn from(info: sys::zx_info_kmem_stats_t) -> MemStats {
30 let sys::zx_info_kmem_stats_t {
31 total_bytes,
32 free_bytes,
33 free_loaned_bytes,
34 wired_bytes,
35 total_heap_bytes,
36 free_heap_bytes,
37 vmo_bytes,
38 mmu_overhead_bytes,
39 ipc_bytes,
40 cache_bytes,
41 slab_bytes,
42 zram_bytes,
43 other_bytes,
44 vmo_reclaim_total_bytes,
45 vmo_reclaim_newest_bytes,
46 vmo_reclaim_oldest_bytes,
47 vmo_reclaim_disabled_bytes,
48 vmo_discardable_locked_bytes,
49 vmo_discardable_unlocked_bytes,
50 } = info;
51 MemStats {
52 total_bytes,
53 free_bytes,
54 free_loaned_bytes,
55 wired_bytes,
56 total_heap_bytes,
57 free_heap_bytes,
58 vmo_bytes,
59 mmu_overhead_bytes,
60 ipc_bytes,
61 cache_bytes,
62 slab_bytes,
63 zram_bytes,
64 other_bytes,
65 vmo_reclaim_total_bytes,
66 vmo_reclaim_newest_bytes,
67 vmo_reclaim_oldest_bytes,
68 vmo_reclaim_disabled_bytes,
69 vmo_discardable_locked_bytes,
70 vmo_discardable_unlocked_bytes,
71 }
72 }
73}
74
75impl From<sys::zx_info_kmem_stats_extended_t> for MemStatsExtended {
76 fn from(info: sys::zx_info_kmem_stats_extended_t) -> MemStatsExtended {
77 let sys::zx_info_kmem_stats_extended_t {
78 total_bytes,
79 free_bytes,
80 wired_bytes,
81 total_heap_bytes,
82 free_heap_bytes,
83 vmo_bytes,
84 vmo_pager_total_bytes,
85 vmo_pager_newest_bytes,
86 vmo_pager_oldest_bytes,
87 vmo_discardable_locked_bytes,
88 vmo_discardable_unlocked_bytes,
89 mmu_overhead_bytes,
90 ipc_bytes,
91 other_bytes,
92 vmo_reclaim_disable_bytes,
93 } = info;
94 MemStatsExtended {
95 total_bytes,
96 free_bytes,
97 wired_bytes,
98 total_heap_bytes,
99 free_heap_bytes,
100 vmo_bytes,
101 vmo_pager_total_bytes,
102 vmo_pager_newest_bytes,
103 vmo_pager_oldest_bytes,
104 vmo_discardable_locked_bytes,
105 vmo_discardable_unlocked_bytes,
106 mmu_overhead_bytes,
107 ipc_bytes,
108 other_bytes,
109 vmo_reclaim_disable_bytes,
110 }
111 }
112}
113
114impl From<sys::zx_info_kmem_stats_compression_t> for MemStatsCompression {
115 fn from(info: sys::zx_info_kmem_stats_compression_t) -> MemStatsCompression {
116 let sys::zx_info_kmem_stats_compression_t {
117 uncompressed_storage_bytes,
118 compressed_storage_bytes,
119 compressed_fragmentation_bytes,
120 compression_time,
121 decompression_time,
122 total_page_compression_attempts,
123 failed_page_compression_attempts,
124 total_page_decompressions,
125 compressed_page_evictions,
126 eager_page_compressions,
127 memory_pressure_page_compressions,
128 critical_memory_page_compressions,
129 pages_decompressed_unit_ns,
130 pages_decompressed_within_log_time,
131 } = info;
132 MemStatsCompression {
133 uncompressed_storage_bytes,
134 compressed_storage_bytes,
135 compressed_fragmentation_bytes,
136 compression_time,
137 decompression_time,
138 total_page_compression_attempts,
139 failed_page_compression_attempts,
140 total_page_decompressions,
141 compressed_page_evictions,
142 eager_page_compressions,
143 memory_pressure_page_compressions,
144 critical_memory_page_compressions,
145 pages_decompressed_unit_ns,
146 pages_decompressed_within_log_time,
147 }
148 }
149}
150
151impl From<sys::zx_info_cpu_stats_t> for PerCpuStats {
152 fn from(info: sys::zx_info_cpu_stats_t) -> PerCpuStats {
153 let sys::zx_info_cpu_stats_t {
154 cpu_number,
155 flags,
156 idle_time,
157 normalized_busy_time,
158 reschedules,
159 context_switches,
160 irq_preempts,
161 preempts,
162 yields,
163 ints,
164 timer_ints,
165 timers,
166 page_faults,
167 exceptions,
168 syscalls,
169 reschedule_ipis,
170 generic_ipis,
171 active_energy_consumption_nj,
172 idle_energy_consumption_nj,
173 } = info;
174 PerCpuStats {
175 cpu_number,
176 flags,
177 idle_time,
178 normalized_busy_time,
179 reschedules,
180 context_switches,
181 irq_preempts,
182 preempts,
183 yields,
184 ints,
185 timer_ints,
186 timers,
187 page_faults,
188 exceptions,
189 syscalls,
190 reschedule_ipis,
191 generic_ipis,
192 active_energy_consumption_nj,
193 idle_energy_consumption_nj,
194 }
195 }
196}
197
198impl From<sys::zx_info_resource_t> for ResourceInfo {
199 fn from(info: sys::zx_info_resource_t) -> ResourceInfo {
200 let sys::zx_info_resource_t { kind, flags, base, size, name } = info;
201 ResourceInfo { kind, flags, base, size, name }
202 }
203}
204
205impl From<sys::zx_info_memory_stall_t> for MemoryStall {
206 fn from(info: sys::zx_info_memory_stall_t) -> MemoryStall {
207 let sys::zx_info_memory_stall_t { stall_time_some, stall_time_full } = info;
208 MemoryStall { stall_time_some, stall_time_full }
209 }
210}
211
212unsafe impl ObjectQuery for MemStats {
213 const TOPIC: Topic = Topic::KMEM_STATS;
214 type InfoTy = MemStats;
215}
216
217unsafe impl ObjectQuery for MemStatsExtended {
218 const TOPIC: Topic = Topic::KMEM_STATS_EXTENDED;
219 type InfoTy = MemStatsExtended;
220}
221
222unsafe impl ObjectQuery for MemStatsCompression {
223 const TOPIC: Topic = Topic::KMEM_STATS_COMPRESSION;
224 type InfoTy = MemStatsCompression;
225}
226
227unsafe impl ObjectQuery for PerCpuStats {
228 const TOPIC: Topic = Topic::CPU_STATS;
229 type InfoTy = PerCpuStats;
230}
231
232unsafe impl ObjectQuery for ResourceInfo {
233 const TOPIC: Topic = Topic::RESOURCE;
234 type InfoTy = ResourceInfo;
235}
236
237unsafe impl ObjectQuery for MemoryStall {
238 const TOPIC: Topic = Topic::MEMORY_STALL;
239 type InfoTy = MemoryStall;
240}
241
242bitflags! {
243 #[repr(transparent)]
244 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
245 pub struct ResourceKind: sys::zx_rsrc_kind_t {
246 const MMIO = sys::ZX_RSRC_KIND_MMIO;
247 const IRQ = sys::ZX_RSRC_KIND_IRQ;
248 const IOPORT = sys::ZX_RSRC_KIND_IOPORT;
249 const ROOT = sys::ZX_RSRC_KIND_ROOT;
250 const SMC = sys::ZX_RSRC_KIND_SMC;
251 const SYSTEM = sys::ZX_RSRC_KIND_SYSTEM;
252 }
253}
254
255bitflags! {
256 #[repr(transparent)]
257 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
258 pub struct ResourceFlag: sys::zx_rsrc_flags_t {
259 const EXCLUSIVE = sys::ZX_RSRC_FLAG_EXCLUSIVE;
260 }
261}
262
263bitflags! {
264 #[repr(transparent)]
265 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
266 pub struct MemoryStallKind: sys::zx_system_memory_stall_type_t {
267 const SOME = sys::ZX_SYSTEM_MEMORY_STALL_SOME;
268 const FULL = sys::ZX_SYSTEM_MEMORY_STALL_FULL;
269 }
270}
271
272impl Resource {
273 pub fn create_child(
279 &self,
280 kind: ResourceKind,
281 flags: Option<ResourceFlag>,
282 base: u64,
283 size: usize,
284 name: &[u8],
285 ) -> Result<Resource, Status> {
286 let mut resource_out = 0;
287 let name_ptr = name.as_ptr();
288 let name_len = name.len();
289 let flag_bits: u32 = match flags {
290 Some(flag) => flag.bits(),
291 None => 0,
292 };
293 let option_bits: u32 = kind.bits() | flag_bits;
294
295 let status = unsafe {
296 sys::zx_resource_create(
297 self.raw_handle(),
298 option_bits,
299 base,
300 size,
301 name_ptr,
302 name_len,
303 &mut resource_out,
304 )
305 };
306 ok(status)?;
307 unsafe { Ok(Resource::from(NullableHandle::from_raw(resource_out))) }
308 }
309
310 pub fn info(&self) -> Result<ResourceInfo, Status> {
314 self.0.get_info_single::<ResourceInfo>()
315 }
316
317 pub fn cpu_stats(&self) -> Result<Vec<PerCpuStats>, Status> {
321 self.0.get_info_vec::<PerCpuStats>()
322 }
323
324 pub fn mem_stats(&self) -> Result<MemStats, Status> {
328 self.0.get_info_single::<MemStats>()
329 }
330
331 pub fn mem_stats_extended(&self) -> Result<MemStatsExtended, Status> {
335 self.0.get_info_single::<MemStatsExtended>()
336 }
337
338 pub fn mem_stats_compression(&self) -> Result<MemStatsCompression, Status> {
342 self.0.get_info_single::<MemStatsCompression>()
343 }
344
345 pub fn memory_stall(&self) -> Result<MemoryStall, Status> {
349 self.0.get_info_single::<MemoryStall>()
350 }
351
352 pub fn watch_memory_stall(
359 &self,
360 kind: MemoryStallKind,
361 threshold: MonotonicDuration,
362 window: MonotonicDuration,
363 ) -> Result<Event, Status> {
364 let mut event_out = 0;
365 let status = unsafe {
366 sys::zx_system_watch_memory_stall(
367 self.raw_handle(),
368 kind.bits(),
369 threshold.into_nanos(),
370 window.into_nanos(),
371 &mut event_out,
372 )
373 };
374 ok(status)?;
375 unsafe { Ok(Event::from(NullableHandle::from_raw(event_out))) }
376 }
377}