Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport changes for 0.29.7 #1029

Merged
merged 5 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 0.29.7

* macOS: Fix CPU frequency retrieval for M1 and M2.
* Linux: Add support for cgroups v1/v2 for memory.
* Windows: Fix processes name encoding issues.

# 0.29.6

* Update minimum rust version to 1.63.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sysinfo"
version = "0.29.6"
version = "0.29.7"
authors = ["Guillaume Gomez <[email protected]>"]
description = "Library to get system information such as processes, CPUs, disks, components and networks"
repository = "https://github.com/GuillaumeGomez/sysinfo"
Expand Down
13 changes: 9 additions & 4 deletions examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,22 +189,27 @@ fn interpret_input(input: &str, sys: &mut System) -> bool {
"memory" => {
writeln!(
&mut io::stdout(),
"total memory: {} KB",
"total memory: {: >10} KB",
sys.total_memory() / 1_000
);
writeln!(
&mut io::stdout(),
"used memory : {} KB",
"available memory: {: >10} KB",
sys.available_memory() / 1_000
);
writeln!(
&mut io::stdout(),
"used memory: {: >10} KB",
sys.used_memory() / 1_000
);
writeln!(
&mut io::stdout(),
"total swap : {} KB",
"total swap: {: >10} KB",
sys.total_swap() / 1_000
);
writeln!(
&mut io::stdout(),
"used swap : {} KB",
"used swap: {: >10} KB",
sys.used_swap() / 1_000
);
}
Expand Down
31 changes: 20 additions & 11 deletions src/apple/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,27 @@ impl CpuExt for Cpu {
}
}

pub(crate) fn get_cpu_frequency() -> u64 {
pub(crate) unsafe fn get_cpu_frequency() -> u64 {
let mut speed: u64 = 0;
let mut len = std::mem::size_of::<u64>();
unsafe {
libc::sysctlbyname(
b"hw.cpufrequency\0".as_ptr() as *const c_char,
&mut speed as *mut _ as _,
&mut len,
std::ptr::null_mut(),
0,
);
speed / 1_000_000
if libc::sysctlbyname(
b"hw.cpufrequency\0".as_ptr() as *const _,
&mut speed as *mut _ as _,
&mut len,
std::ptr::null_mut(),
0,
) == 0
{
return speed / 1_000_000;
}

#[cfg(any(target_os = "ios", feature = "apple-sandbox"))]
{
return 0;
}
#[cfg(not(any(target_os = "ios", feature = "apple-sandbox")))]
{
crate::sys::inner::cpu::get_cpu_frequency()
}
}

Expand Down Expand Up @@ -209,7 +218,7 @@ pub(crate) fn init_cpus(

let (vendor_id, brand) = get_vendor_id_and_brand();
let frequency = if refresh_kind.frequency() {
get_cpu_frequency()
unsafe { get_cpu_frequency() }
} else {
global_cpu.frequency
};
Expand Down
4 changes: 4 additions & 0 deletions src/apple/macos/component/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ impl IoService {

unsafe {
let matching_dictionary = ffi::IOServiceMatching(b"AppleSMC\0".as_ptr() as *const i8);
if matching_dictionary.is_null() {
sysinfo_debug!("IOServiceMatching call failed, `AppleSMC` not found");
return None;
}
let result = ffi::IOServiceGetMatchingServices(
ffi::kIOMasterPortDefault,
matching_dictionary,
Expand Down
95 changes: 95 additions & 0 deletions src/apple/macos/cpu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Take a look at the license at the top of the repository in the LICENSE file.

#[cfg(feature = "apple-sandbox")]
pub(crate) unsafe fn get_cpu_frequency() -> u64 {
0
}

#[cfg(not(feature = "apple-sandbox"))]
pub(crate) unsafe fn get_cpu_frequency() -> u64 {
use crate::sys::ffi;
use crate::sys::macos::utils::IOReleaser;
use crate::sys::utils::CFReleaser;

let matching = ffi::IOServiceMatching(b"AppleARMIODevice\0".as_ptr() as *const _);
if matching.is_null() {
sysinfo_debug!("IOServiceMatching call failed, `AppleARMIODevice` not found");
return 0;
}

// Starting from mac M1, the above call returns nothing for the CPU frequency
// so we try to get it from another source. This code comes from
// <https://github.com/giampaolo/psutil/pull/2222>.
let mut iterator: ffi::io_iterator_t = 0;
let result =
ffi::IOServiceGetMatchingServices(ffi::kIOMasterPortDefault, matching, &mut iterator);
if result != ffi::KIO_RETURN_SUCCESS {
sysinfo_debug!("Error: IOServiceGetMatchingServices() = {}", result);
return 0;
}
let iterator = match IOReleaser::new(iterator) {
Some(i) => i,
None => {
sysinfo_debug!(
"Error: IOServiceGetMatchingServices() succeeded but returned invalid descriptor"
);
return 0;
}
};

let mut name: ffi::io_name = std::mem::zeroed();
let entry = loop {
let entry = match IOReleaser::new(ffi::IOIteratorNext(iterator.inner())) {
Some(d) => d,
None => {
sysinfo_debug!("`pmgr` entry was not found in AppleARMIODevice service");
return 0;
}
};
let status = ffi::IORegistryEntryGetName(entry.inner(), name.as_mut_ptr());
if status != libc::KERN_SUCCESS {
continue;
} else if libc::strcmp(name.as_ptr(), b"pmgr\0".as_ptr() as *const _) == 0 {
break entry;
}
};

let node_name = match CFReleaser::new(ffi::CFStringCreateWithCStringNoCopy(
std::ptr::null(),
b"voltage-states5-sram\0".as_ptr() as *const _,
core_foundation_sys::string::kCFStringEncodingUTF8,
core_foundation_sys::base::kCFAllocatorNull as *mut _,
)) {
Some(n) => n,
None => {
sysinfo_debug!("CFStringCreateWithCStringNoCopy failed");
return 0;
}
};

let core_ref = match CFReleaser::new(ffi::IORegistryEntryCreateCFProperty(
entry.inner(),
node_name.inner(),
core_foundation_sys::base::kCFAllocatorDefault,
0,
)) {
Some(c) => c,
None => {
sysinfo_debug!("`voltage-states5-sram` property not found");
return 0;
}
};

let core_length = core_foundation_sys::data::CFDataGetLength(core_ref.inner() as *const _);
if core_length < 8 {
sysinfo_debug!("expected `voltage-states5-sram` buffer to have at least size 8");
return 0;
}
let mut max: u64 = 0;
core_foundation_sys::data::CFDataGetBytes(
core_ref.inner() as *const _,
core_foundation_sys::base::CFRange::init(core_length - 8, 4),
&mut max as *mut _ as *mut _,
);
max / 1_000_000
}
43 changes: 31 additions & 12 deletions src/apple/macos/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@
pub type io_iterator_t = io_object_t;
#[allow(non_camel_case_types)]
pub type io_registry_entry_t = io_object_t;
// This is a hack, `io_name_t` should normally be `[c_char; 128]` but Rust makes it very annoying
// to deal with that so we go around it a bit.
#[allow(non_camel_case_types)]
pub type io_name = [c_char; 128];

Check warning on line 21 in src/apple/macos/ffi.rs

View workflow job for this annotation

GitHub Actions / Check nightly / x86_64-apple-darwin

type alias `io_name` is never used

Check warning on line 21 in src/apple/macos/ffi.rs

View workflow job for this annotation

GitHub Actions / Check nightly / x86_64-apple-darwin

type alias `io_name` is never used

Check warning on line 21 in src/apple/macos/ffi.rs

View workflow job for this annotation

GitHub Actions / Check stable / x86_64-apple-darwin

type alias `io_name` is never used

Check warning on line 21 in src/apple/macos/ffi.rs

View workflow job for this annotation

GitHub Actions / Check stable / x86_64-apple-darwin

type alias `io_name` is never used

Check warning on line 21 in src/apple/macos/ffi.rs

View workflow job for this annotation

GitHub Actions / Check 1.63.0 / x86_64-apple-darwin

type alias `io_name` is never used

Check warning on line 21 in src/apple/macos/ffi.rs

View workflow job for this annotation

GitHub Actions / Check 1.63.0 / x86_64-apple-darwin

type alias `io_name` is never used
#[allow(non_camel_case_types)]
pub type io_name_t = *const c_char;

pub type IOOptionBits = u32;

#[allow(non_upper_case_globals)]
pub const kIOServicePlane: &str = "IOService\0";
pub const kIOServicePlane: &[u8] = b"IOService\0";
#[allow(non_upper_case_globals)]
pub const kIOPropertyDeviceCharacteristicsKey: &str = "Device Characteristics";
#[allow(non_upper_case_globals)]
Expand All @@ -44,6 +48,8 @@
matching: CFMutableDictionaryRef,
existing: *mut io_iterator_t,
) -> kern_return_t;
#[allow(dead_code)]
pub fn IOServiceMatching(a: *const c_char) -> CFMutableDictionaryRef;

pub fn IOIteratorNext(iterator: io_iterator_t) -> io_object_t;

Expand All @@ -60,22 +66,36 @@
plane: io_name_t,
parent: *mut io_registry_entry_t,
) -> kern_return_t;
#[allow(dead_code)]
pub fn IORegistryEntryGetName(entry: io_registry_entry_t, name: io_name_t) -> kern_return_t;

pub fn IOBSDNameMatching(
mainPort: mach_port_t,
options: u32,
bsdName: *const c_char,
) -> CFMutableDictionaryRef;
}
#[allow(dead_code)]
pub const KIO_RETURN_SUCCESS: i32 = 0;

extern "C" {
// FIXME: to be removed once higher version than core_foundation_sys 0.8.4 is released.
#[allow(dead_code)]
pub fn CFStringCreateWithCStringNoCopy(
alloc: CFAllocatorRef,
cStr: *const c_char,
encoding: core_foundation_sys::string::CFStringEncoding,
contentsDeallocator: CFAllocatorRef,
) -> CFStringRef;
}

#[cfg(all(
not(feature = "apple-sandbox"),
any(target_arch = "x86", target_arch = "x86_64")
))]
mod io_service {
use super::{io_object_t, mach_port_t};
use core_foundation_sys::dictionary::CFMutableDictionaryRef;
use libc::{c_char, kern_return_t, size_t, task_t};
use libc::{kern_return_t, size_t, task_t};

#[allow(non_camel_case_types)]
pub type io_connect_t = io_object_t;
Expand All @@ -87,8 +107,6 @@
pub type task_port_t = task_t;

extern "C" {
pub fn IOServiceMatching(a: *const c_char) -> CFMutableDictionaryRef;

pub fn IOServiceOpen(
device: io_service_t,
owning_task: task_port_t,
Expand Down Expand Up @@ -159,8 +177,6 @@

#[allow(dead_code)]
pub const SMC_CMD_READ_BYTES: u8 = 5;

pub const KIO_RETURN_SUCCESS: i32 = 0;
}

#[cfg(feature = "apple-sandbox")]
Expand All @@ -176,14 +192,15 @@
mod io_service {
use std::ptr::null;

use super::CFStringCreateWithCStringNoCopy;
use core_foundation_sys::array::CFArrayRef;
use core_foundation_sys::base::{CFAllocatorRef, CFRelease};
use core_foundation_sys::dictionary::{
kCFTypeDictionaryKeyCallBacks, kCFTypeDictionaryValueCallBacks, CFDictionaryCreate,
CFDictionaryRef,
};
use core_foundation_sys::number::{kCFNumberSInt32Type, CFNumberCreate};
use core_foundation_sys::string::{CFStringCreateWithCString, CFStringRef};
use core_foundation_sys::string::CFStringRef;

#[repr(C)]
pub struct __IOHIDServiceClient(libc::c_void);
Expand Down Expand Up @@ -250,15 +267,17 @@
pub(crate) fn matching(page: i32, usage: i32) -> CFDictionaryRef {
unsafe {
let keys = [
CFStringCreateWithCString(
CFStringCreateWithCStringNoCopy(
null() as *const _,
HID_DEVICE_PROPERTY_PRIMARY_USAGE_PAGE.as_ptr() as *const _,
0,
core_foundation_sys::string::kCFStringEncodingUTF8,
core_foundation_sys::base::kCFAllocatorNull as *mut _,
),
CFStringCreateWithCString(
CFStringCreateWithCStringNoCopy(
null() as *const _,
HID_DEVICE_PROPERTY_PRIMARY_USAGE.as_ptr() as *const _,
0,
core_foundation_sys::string::kCFStringEncodingUTF8,
core_foundation_sys::base::kCFAllocatorNull as *mut _,
),
];

Expand Down
3 changes: 3 additions & 0 deletions src/apple/macos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ pub mod disk;
pub mod ffi;
pub(crate) mod utils;

#[cfg(not(feature = "apple-sandbox"))]
pub(crate) mod cpu;

#[cfg(not(feature = "apple-sandbox"))]
pub mod system;

Expand Down
2 changes: 1 addition & 1 deletion src/apple/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ impl SystemExt for System {
return;
}
if refresh_kind.frequency() && !self.got_cpu_frequency {
let frequency = get_cpu_frequency();
let frequency = unsafe { get_cpu_frequency() };
for proc_ in cpus.iter_mut() {
proc_.set_frequency(frequency);
}
Expand Down
Loading
Loading