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