summaryrefslogtreecommitdiffstats
path: root/vendor/sysinfo/src/apple/macos/system.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sysinfo/src/apple/macos/system.rs')
-rw-r--r--vendor/sysinfo/src/apple/macos/system.rs139
1 files changed, 84 insertions, 55 deletions
diff --git a/vendor/sysinfo/src/apple/macos/system.rs b/vendor/sysinfo/src/apple/macos/system.rs
index 949532234..7c8b957a5 100644
--- a/vendor/sysinfo/src/apple/macos/system.rs
+++ b/vendor/sysinfo/src/apple/macos/system.rs
@@ -1,5 +1,7 @@
// Take a look at the license at the top of the repository in the LICENSE file.
+use crate::SystemExt;
+
#[allow(deprecated)]
use libc::{mach_timebase_info, mach_timebase_info_data_t};
@@ -9,18 +11,52 @@ use libc::{
};
use std::ptr::null_mut;
-unsafe fn free_cpu_load_info(cpu_load: &mut processor_cpu_load_info_t) {
- if !cpu_load.is_null() {
- munmap(*cpu_load as _, vm_page_size);
- *cpu_load = null_mut();
+struct ProcessorCpuLoadInfo {
+ cpu_load: processor_cpu_load_info_t,
+ cpu_count: natural_t,
+}
+
+impl ProcessorCpuLoadInfo {
+ fn new(port: mach_port_t) -> Option<Self> {
+ let mut info_size = std::mem::size_of::<processor_cpu_load_info_t>() as _;
+ let mut cpu_count = 0;
+ let mut cpu_load: processor_cpu_load_info_t = null_mut();
+
+ unsafe {
+ if host_processor_info(
+ port,
+ PROCESSOR_CPU_LOAD_INFO,
+ &mut cpu_count,
+ &mut cpu_load as *mut _ as *mut _,
+ &mut info_size,
+ ) != 0
+ {
+ sysinfo_debug!("host_processor_info failed, not updating CPU ticks usage...");
+ None
+ } else if cpu_count < 1 || cpu_load.is_null() {
+ None
+ } else {
+ Some(Self {
+ cpu_load,
+ cpu_count,
+ })
+ }
+ }
+ }
+}
+
+impl Drop for ProcessorCpuLoadInfo {
+ fn drop(&mut self) {
+ unsafe {
+ munmap(self.cpu_load as _, vm_page_size);
+ }
}
}
pub(crate) struct SystemTimeInfo {
timebase_to_ns: f64,
clock_per_sec: f64,
- old_cpu_load: processor_cpu_load_info_t,
- old_cpu_count: natural_t,
+ old_cpu_info: ProcessorCpuLoadInfo,
}
unsafe impl Send for SystemTimeInfo {}
@@ -49,9 +85,8 @@ impl SystemTimeInfo {
info.denom = 1;
}
- let mut old_cpu_load = null_mut();
- let old_cpu_count = match Self::update_ticks(port, &mut old_cpu_load) {
- Some(c) => c,
+ let old_cpu_info = match ProcessorCpuLoadInfo::new(port) {
+ Some(cpu_info) => cpu_info,
None => {
sysinfo_debug!("host_processor_info failed, using old CPU tick measure system");
return None;
@@ -63,53 +98,23 @@ impl SystemTimeInfo {
Some(Self {
timebase_to_ns: info.numer as f64 / info.denom as f64,
clock_per_sec: nano_per_seconds / clock_ticks_per_sec as f64,
- old_cpu_load,
- old_cpu_count,
+ old_cpu_info,
})
}
}
- fn update_ticks(
- port: mach_port_t,
- cpu_load: &mut processor_cpu_load_info_t,
- ) -> Option<natural_t> {
- let mut info_size = std::mem::size_of::<processor_cpu_load_info_t>() as _;
- let mut cpu_count = 0;
-
- unsafe {
- free_cpu_load_info(cpu_load);
-
- if host_processor_info(
- port,
- PROCESSOR_CPU_LOAD_INFO,
- &mut cpu_count,
- cpu_load as *mut _ as *mut _,
- &mut info_size,
- ) != 0
- {
- sysinfo_debug!("host_processor_info failed, not updating CPU ticks usage...");
- None
- } else if cpu_count < 1 || cpu_load.is_null() {
- None
- } else {
- Some(cpu_count)
- }
- }
- }
-
pub fn get_time_interval(&mut self, port: mach_port_t) -> f64 {
let mut total = 0;
- let mut new_cpu_load = null_mut();
-
- let new_cpu_count = match Self::update_ticks(port, &mut new_cpu_load) {
- Some(c) => c,
+ let new_cpu_info = match ProcessorCpuLoadInfo::new(port) {
+ Some(cpu_info) => cpu_info,
None => return 0.,
};
- let cpu_count = std::cmp::min(self.old_cpu_count, new_cpu_count);
+ let cpu_count = std::cmp::min(self.old_cpu_info.cpu_count, new_cpu_info.cpu_count);
unsafe {
for i in 0..cpu_count {
- let new_load: &processor_cpu_load_info = &*new_cpu_load.offset(i as _);
- let old_load: &processor_cpu_load_info = &*self.old_cpu_load.offset(i as _);
+ let new_load: &processor_cpu_load_info = &*new_cpu_info.cpu_load.offset(i as _);
+ let old_load: &processor_cpu_load_info =
+ &*self.old_cpu_info.cpu_load.offset(i as _);
for (new, old) in new_load.cpu_ticks.iter().zip(old_load.cpu_ticks.iter()) {
if new > old {
total += new - old;
@@ -117,20 +122,44 @@ impl SystemTimeInfo {
}
}
- free_cpu_load_info(&mut self.old_cpu_load);
- self.old_cpu_load = new_cpu_load;
- self.old_cpu_count = new_cpu_count;
+ self.old_cpu_info = new_cpu_info;
- // Now we convert the ticks to nanoseconds:
- total as f64 / self.timebase_to_ns * self.clock_per_sec / cpu_count as f64
+ // Now we convert the ticks to nanoseconds (if the interval is less than
+ // `MINIMUM_CPU_UPDATE_INTERVAL`, we replace it with it instead):
+ let base_interval = total as f64 / cpu_count as f64 * self.clock_per_sec;
+ let smallest =
+ crate::System::MINIMUM_CPU_UPDATE_INTERVAL.as_secs_f64() * 1_000_000_000.0;
+ if base_interval < smallest {
+ smallest
+ } else {
+ base_interval / self.timebase_to_ns
+ }
}
}
}
-impl Drop for SystemTimeInfo {
- fn drop(&mut self) {
- unsafe {
- free_cpu_load_info(&mut self.old_cpu_load);
+#[cfg(test)]
+mod test {
+
+ use super::*;
+
+ /// Regression test for <https://github.com/GuillaumeGomez/sysinfo/issues/956>.
+ #[test]
+ fn test_getting_time_interval() {
+ if !crate::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
}
+
+ let port = unsafe { libc::mach_host_self() };
+ let mut info = SystemTimeInfo::new(port).unwrap();
+ info.get_time_interval(port);
+
+ std::thread::sleep(crate::System::MINIMUM_CPU_UPDATE_INTERVAL.saturating_mul(5));
+
+ let val = info.get_time_interval(port);
+ assert_ne!(
+ val,
+ crate::System::MINIMUM_CPU_UPDATE_INTERVAL.as_secs_f64() * 1_000_000_000.0
+ );
}
}