Repository: GuillaumeGomez/sysinfo (language: rust)

Issue:
Extract "standalone" methods from `System`
If they don't need information stored in `System`, they shouldn't be a method of it.


Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 932d07b53..a8f95ae47 100644
--- a/README.md
+++ b/README.md
@@ -54,10 +54,10 @@ println!("total swap  : {} bytes", sys.total_swap());
 println!("used swap   : {} bytes", sys.used_swap());
 
 // Display system information:
-println!("System name:             {:?}", sys.name());
-println!("System kernel version:   {:?}", sys.kernel_version());
-println!("System OS version:       {:?}", sys.os_version());
-println!("System host name:        {:?}", sys.host_name());
+println!("System name:             {:?}", System::name());
+println!("System kernel version:   {:?}", System::kernel_version());
+println!("System OS version:       {:?}", System::os_version());
+println!("System host name:        {:?}", System::host_name());
 
 // Number of CPUs:
 println!("NB CPUs: {}", sys.cpus().len());
diff --git a/examples/simple.rs b/examples/simple.rs
index 7c9bd7584..34634150a 100644
--- a/examples/simple.rs
+++ b/examples/simple.rs
@@ -268,7 +268,7 @@ fn interpret_input(
             writeln!(&mut io::stdout(), "brand: {}", sys.cpus()[0].brand());
         }
         "load_avg" => {
-            let load_avg = sys.load_average();
+            let load_avg = System::load_average();
             writeln!(&mut io::stdout(), "one minute     : {}%", load_avg.one);
             writeln!(&mut io::stdout(), "five minutes   : {}%", load_avg.five);
             writeln!(&mut io::stdout(), "fifteen minutes: {}%", load_avg.fifteen);
@@ -376,11 +376,11 @@ fn interpret_input(
             }
         }
         "boot_time" => {
-            writeln!(&mut io::stdout(), "{} seconds", sys.boot_time());
+            writeln!(&mut io::stdout(), "{} seconds", System::boot_time());
         }
         "uptime" => {
-            let up = sys.uptime();
-            let mut uptime = sys.uptime();
+            let up = System::uptime();
+            let mut uptime = up;
             let days = uptime / 86400;
             uptime -= days * 86400;
             let hours = uptime / 3600;
@@ -435,13 +435,11 @@ fn interpret_input(
                  System OS version:        {}\n\
                  System OS (long) version: {}\n\
                  System host name:         {}",
-                sys.name().unwrap_or_else(|| "<unknown>".to_owned()),
-                sys.kernel_version()
-                    .unwrap_or_else(|| "<unknown>".to_owned()),
-                sys.os_version().unwrap_or_else(|| "<unknown>".to_owned()),
-                sys.long_os_version()
-                    .unwrap_or_else(|| "<unknown>".to_owned()),
-                sys.host_name().unwrap_or_else(|| "<unknown>".to_owned()),
+                System::name().unwrap_or_else(|| "<unknown>".to_owned()),
+                System::kernel_version().unwrap_or_else(|| "<unknown>".to_owned()),
+                System::os_version().unwrap_or_else(|| "<unknown>".to_owned()),
+                System::long_os_version().unwrap_or_else(|| "<unknown>".to_owned()),
+                System::host_name().unwrap_or_else(|| "<unknown>".to_owned()),
             );
         }
         e => {
diff --git a/src/c_interface.rs b/src/c_interface.rs
index 0ca8cea85..33e6649d3 100644
--- a/src/c_interface.rs
+++ b/src/c_interface.rs
@@ -585,82 +585,56 @@ pub extern "C" fn sysinfo_cpu_frequency(system: CSystem) -> u64 {
 
 /// Equivalent of [`System::name()`][crate::System#method.name].
 #[no_mangle]
-pub extern "C" fn sysinfo_system_name(system: CSystem) -> RString {
-    assert!(!system.is_null());
-    unsafe {
-        let system: Box<System> = Box::from_raw(system as *mut System);
-        let c_string = if let Some(c) = system.name().and_then(|p| CString::new(p).ok()) {
-            c.into_raw() as _
-        } else {
-            std::ptr::null()
-        };
-        Box::into_raw(system);
-        c_string
-    }
+pub extern "C" fn sysinfo_system_name() -> RString {
+    let c_string = if let Some(c) = System::name().and_then(|p| CString::new(p).ok()) {
+        c.into_raw() as _
+    } else {
+        std::ptr::null()
+    };
+    c_string
 }
 
 /// Equivalent of [`System::version()`][crate::System#method.version].
 #[no_mangle]
-pub extern "C" fn sysinfo_system_version(system: CSystem) -> RString {
-    assert!(!system.is_null());
-    unsafe {
-        let system: Box<System> = Box::from_raw(system as *mut System);
-        let c_string = if let Some(c) = system.os_version().and_then(|c| CString::new(c).ok()) {
-            c.into_raw() as _
-        } else {
-            std::ptr::null()
-        };
-        Box::into_raw(system);
-        c_string
-    }
+pub extern "C" fn sysinfo_system_version() -> RString {
+    let c_string = if let Some(c) = System::os_version().and_then(|c| CString::new(c).ok()) {
+        c.into_raw() as _
+    } else {
+        std::ptr::null()
+    };
+    c_string
 }
 
 /// Equivalent of [`System::kernel_version()`][crate::System#method.kernel_version].
 #[no_mangle]
-pub extern "C" fn sysinfo_system_kernel_version(system: CSystem) -> RString {
-    assert!(!system.is_null());
-    unsafe {
-        let system: Box<System> = Box::from_raw(system as *mut System);
-        let c_string = if let Some(c) = system.kernel_version().and_then(|c| CString::new(c).ok()) {
-            c.into_raw() as _
-        } else {
-            std::ptr::null()
-        };
+pub extern "C" fn sysinfo_system_kernel_version() -> RString {
+    let c_string = if let Some(c) = System::kernel_version().and_then(|c| CString::new(c).ok()) {
+        c.into_raw() as _
+    } else {
+        std::ptr::null()
+    };
 
-        Box::into_raw(system);
-        c_string
-    }
+    c_string
 }
 
 /// Equivalent of [`System::host_name()`][crate::System#method.host_name].
 #[no_mangle]
-pub extern "C" fn sysinfo_system_host_name(system: CSystem) -> RString {
-    assert!(!system.is_null());
-    unsafe {
-        let system: Box<System> = Box::from_raw(system as *mut System);
-        let c_string = if let Some(c) = system.host_name().and_then(|c| CString::new(c).ok()) {
-            c.into_raw() as _
-        } else {
-            std::ptr::null()
-        };
-        Box::into_raw(system);
-        c_string
-    }
+pub extern "C" fn sysinfo_system_host_name() -> RString {
+    let c_string = if let Some(c) = System::host_name().and_then(|c| CString::new(c).ok()) {
+        c.into_raw() as _
+    } else {
+        std::ptr::null()
+    };
+    c_string
 }
 
 /// Equivalent of [`System::long_os_version()`][crate::System#method.long_os_version].
 #[no_mangle]
-pub extern "C" fn sysinfo_system_long_version(system: CSystem) -> RString {
-    assert!(!system.is_null());
-    unsafe {
-        let system: Box<System> = Box::from_raw(system as *mut System);
-        let c_string = if let Some(c) = system.long_os_version().and_then(|c| CString::new(c).ok())
-        {
-            c.into_raw() as _
-        } else {
-            std::ptr::null()
-        };
-        Box::into_raw(system);
-        c_string
-    }
+pub extern "C" fn sysinfo_system_long_version() -> RString {
+    let c_string = if let Some(c) = System::long_os_version().and_then(|c| CString::new(c).ok()) {
+        c.into_raw() as _
+    } else {
+        std::ptr::null()
+    };
+    c_string
 }
diff --git a/src/common.rs b/src/common.rs
index 73b8cafa5..9a0a5551a 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -655,26 +655,28 @@ impl System {
 
     /// Returns system uptime (in seconds).
     ///
+    /// **Important**: this information is computed every time this function is called.
+    ///
     /// ```no_run
     /// use sysinfo::System;
     ///
-    /// let s = System::new_all();
-    /// println!("System running since {} seconds", s.uptime());
+    /// println!("System running since {} seconds", System::uptime());
     /// ```
-    pub fn uptime(&self) -> u64 {
-        self.inner.uptime()
+    pub fn uptime() -> u64 {
+        SystemInner::uptime()
     }
 
     /// Returns the time (in seconds) when the system booted since UNIX epoch.
     ///
+    /// **Important**: this information is computed every time this function is called.
+    ///
     /// ```no_run
     /// use sysinfo::System;
     ///
-    /// let s = System::new();
-    /// println!("System booted at {} seconds", s.boot_time());
+    /// println!("System booted at {} seconds", System::boot_time());
     /// ```
-    pub fn boot_time(&self) -> u64 {
-        self.inner.boot_time()
+    pub fn boot_time() -> u64 {
+        SystemInner::boot_time()
     }
 
     /// Returns the system load average value.
@@ -686,8 +688,7 @@ impl System {
     /// ```no_run
     /// use sysinfo::System;
     ///
-    /// let s = System::new_all();
-    /// let load_avg = s.load_average();
+    /// let load_avg = System::load_average();
     /// println!(
     ///     "one minute: {}%, five minutes: {}%, fifteen minutes: {}%",
     ///     load_avg.one,
@@ -695,8 +696,8 @@ impl System {
     ///     load_avg.fifteen,
     /// );
     /// ```
-    pub fn load_average(&self) -> LoadAvg {
-        self.inner.load_average()
+    pub fn load_average() -> LoadAvg {
+        SystemInner::load_average()
     }
 
     /// Returns the system name.
@@ -706,11 +707,10 @@ impl System {
     /// ```no_run
     /// use sysinfo::System;
     ///
-    /// let s = System::new();
-    /// println!("OS: {:?}", s.name());
+    /// println!("OS: {:?}", System::name());
     /// ```
-    pub fn name(&self) -> Option<String> {
-        self.inner.name()
+    pub fn name() -> Option<String> {
+        SystemInner::name()
     }
 
     /// Returns the system's kernel version.
@@ -720,25 +720,24 @@ impl System {
     /// ```no_run
     /// use sysinfo::System;
     ///
-    /// let s = System::new();
-    /// println!("kernel version: {:?}", s.kernel_version());
+    /// println!("kernel version: {:?}", System::kernel_version());
     /// ```
-    pub fn kernel_version(&self) -> Option<String> {
-        self.inner.kernel_version()
+    pub fn kernel_version() -> Option<String> {
+        SystemInner::kernel_version()
     }
 
-    /// Returns the system version (e.g. for MacOS this will return 11.1 rather than the kernel version).
+    /// Returns the system version (e.g. for MacOS this will return 11.1 rather than the kernel
+    /// version).
     ///
     /// **Important**: this information is computed every time this function is called.
     ///
     /// ```no_run
     /// use sysinfo::System;
     ///
-    /// let s = System::new();
-    /// println!("OS version: {:?}", s.os_version());
+    /// println!("OS version: {:?}", System::os_version());
     /// ```
-    pub fn os_version(&self) -> Option<String> {
-        self.inner.os_version()
+    pub fn os_version() -> Option<String> {
+        SystemInner::os_version()
     }
 
     /// Returns the system long os version (e.g "MacOS 11.2 BigSur").
@@ -748,11 +747,10 @@ impl System {
     /// ```no_run
     /// use sysinfo::System;
     ///
-    /// let s = System::new();
-    /// println!("Long OS Version: {:?}", s.long_os_version());
+    /// println!("Long OS Version: {:?}", System::long_os_version());
     /// ```
-    pub fn long_os_version(&self) -> Option<String> {
-        self.inner.long_os_version()
+    pub fn long_os_version() -> Option<String> {
+        SystemInner::long_os_version()
     }
 
     /// Returns the distribution id as defined by os-release,
@@ -767,37 +765,36 @@ impl System {
     /// ```no_run
     /// use sysinfo::System;
     ///
-    /// let s = System::new();
-    /// println!("Distribution ID: {:?}", s.distribution_id());
+    /// println!("Distribution ID: {:?}", System::distribution_id());
     /// ```
-    pub fn distribution_id(&self) -> String {
-        self.inner.distribution_id()
+    pub fn distribution_id() -> String {
+        SystemInner::distribution_id()
     }
 
-    /// Returns the system hostname based off DNS
+    /// Returns the system hostname based off DNS.
     ///
     /// **Important**: this information is computed every time this function is called.
     ///
     /// ```no_run
     /// use sysinfo::System;
     ///
-    /// let s = System::new();
-    /// println!("Hostname: {:?}", s.host_name());
+    /// println!("Hostname: {:?}", System::host_name());
     /// ```
-    pub fn host_name(&self) -> Option<String> {
-        self.inner.host_name()
+    pub fn host_name() -> Option<String> {
+        SystemInner::host_name()
     }
 
     /// Returns the CPU architecture (eg. x86, amd64, aarch64, ...).
     ///
+    /// **Important**: this information is computed every time this function is called.
+    ///
     /// ```no_run
     /// use sysinfo::System;
     ///
-    /// let s = System::new();
-    /// println!("CPU Archicture: {:?}", s.cpu_arch());
+    /// println!("CPU Archicture: {:?}", System::cpu_arch());
     /// ```
-    pub fn cpu_arch(&self) -> Option<String> {
-        self.inner.cpu_arch()
+    pub fn cpu_arch() -> Option<String> {
+        SystemInner::cpu_arch()
     }
 }
 
@@ -2797,8 +2794,7 @@ pub struct CGroupLimits {
 /// ```no_run
 /// use sysinfo::System;
 ///
-/// let s = System::new_all();
-/// let load_avg = s.load_average();
+/// let load_avg = System::load_average();
 /// println!(
 ///     "one minute: {}%, five minutes: {}%, fifteen minutes: {}%",
 ///     load_avg.one,
diff --git a/src/debug.rs b/src/debug.rs
index 98976a021..3926fe8dc 100644
--- a/src/debug.rs
+++ b/src/debug.rs
@@ -22,7 +22,7 @@ impl fmt::Debug for System {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("System")
             .field("global CPU usage", &self.global_cpu_info().cpu_usage())
-            .field("load average", &self.load_average())
+            .field("load average", &Self::load_average())
             .field("total memory", &self.total_memory())
             .field("free memory", &self.free_memory())
             .field("total swap", &self.total_swap())
diff --git a/src/lib.rs b/src/lib.rs
index 0ba42187c..faf1cc0fb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -365,34 +365,33 @@ mod test {
 
     #[test]
     fn check_system_info() {
-        let s = System::new();
-
         // We don't want to test on unsupported systems.
         if IS_SUPPORTED {
-            assert!(!s.name().expect("Failed to get system name").is_empty());
+            assert!(!System::name()
+                .expect("Failed to get system name")
+                .is_empty());
 
-            assert!(!s
-                .kernel_version()
+            assert!(!System::kernel_version()
                 .expect("Failed to get kernel version")
                 .is_empty());
 
-            assert!(!s.os_version().expect("Failed to get os version").is_empty());
+            assert!(!System::os_version()
+                .expect("Failed to get os version")
+                .is_empty());
 
-            assert!(!s
-                .long_os_version()
+            assert!(!System::long_os_version()
                 .expect("Failed to get long OS version")
                 .is_empty());
         }
 
-        assert!(!s.distribution_id().is_empty());
+        assert!(!System::distribution_id().is_empty());
     }
 
     #[test]
     fn check_host_name() {
         // We don't want to test on unsupported systems.
         if IS_SUPPORTED {
-            let s = System::new();
-            assert!(s.host_name().is_some());
+            assert!(System::host_name().is_some());
         }
     }
 
@@ -512,7 +511,6 @@ mod test {
 
     #[test]
     fn check_cpu_arch() {
-        let s = System::new();
-        assert_eq!(s.cpu_arch().is_some(), IS_SUPPORTED);
+        assert_eq!(System::cpu_arch().is_some(), IS_SUPPORTED);
     }
 }
diff --git a/src/serde.rs b/src/serde.rs
index cb96580af..5ddc3b302 100644
--- a/src/serde.rs
+++ b/src/serde.rs
@@ -120,15 +120,15 @@ impl serde::Serialize for crate::System {
         state.serialize_field("free_swap", &self.free_swap())?;
         state.serialize_field("used_swap", &self.used_swap())?;
 
-        state.serialize_field("uptime", &self.uptime())?;
-        state.serialize_field("boot_time", &self.boot_time())?;
-        state.serialize_field("load_average", &self.load_average())?;
-        state.serialize_field("name", &self.name())?;
-        state.serialize_field("kernel_version", &self.kernel_version())?;
-        state.serialize_field("os_version", &self.os_version())?;
-        state.serialize_field("long_os_version", &self.long_os_version())?;
-        state.serialize_field("distribution_id", &self.distribution_id())?;
-        state.serialize_field("host_name", &self.host_name())?;
+        state.serialize_field("uptime", &Self::uptime())?;
+        state.serialize_field("boot_time", &Self::boot_time())?;
+        state.serialize_field("load_average", &Self::load_average())?;
+        state.serialize_field("name", &Self::name())?;
+        state.serialize_field("kernel_version", &Self::kernel_version())?;
+        state.serialize_field("os_version", &Self::os_version())?;
+        state.serialize_field("long_os_version", &Self::long_os_version())?;
+        state.serialize_field("distribution_id", &Self::distribution_id())?;
+        state.serialize_field("host_name", &Self::host_name())?;
 
         state.end()
     }
diff --git a/src/sysinfo.h b/src/sysinfo.h
index 279714c50..20a9832e3 100644
--- a/src/sysinfo.h
+++ b/src/sysinfo.h
@@ -67,10 +67,10 @@ RString     sysinfo_cpu_brand(CSystem system);
 uint64_t    sysinfo_cpu_frequency(CSystem system);
 uint32_t    sysinfo_cpu_physical_cores(CSystem system);
 
-RString     sysinfo_system_name(CSystem system);
-RString     sysinfo_system_kernel_version(CSystem system);
-RString     sysinfo_system_version(CSystem system);
-RString     sysinfo_system_host_name(CSystem system);
-RString     sysinfo_system_long_version(CSystem system);
+RString     sysinfo_system_name();
+RString     sysinfo_system_kernel_version();
+RString     sysinfo_system_version();
+RString     sysinfo_system_host_name();
+RString     sysinfo_system_long_version();
 
 void        sysinfo_rstring_free(RString str);
diff --git a/src/system.rs b/src/system.rs
index 3b8eb2ead..2230645f4 100644
--- a/src/system.rs
+++ b/src/system.rs
@@ -98,24 +98,28 @@ mod tests {
 
     #[test]
     fn check_hostname_has_no_nuls() {
-        let sys = System::new();
-
-        if let Some(hostname) = sys.host_name() {
+        if let Some(hostname) = System::host_name() {
             assert!(!hostname.contains('\u{0}'))
         }
     }
 
     #[test]
     fn check_uptime() {
-        let sys = System::new();
-        let uptime = sys.uptime();
+        let uptime = System::uptime();
         if crate::IS_SUPPORTED {
             std::thread::sleep(std::time::Duration::from_millis(1000));
-            let new_uptime = sys.uptime();
+            let new_uptime = System::uptime();
             assert!(uptime < new_uptime);
         }
     }
 
+    #[test]
+    fn check_boot_time() {
+        if crate::IS_SUPPORTED {
+            assert_ne!(System::boot_time(), 0);
+        }
+    }
+
     // This test is used to ensure that the CPU usage computation isn't completely going off
     // when refreshing it too frequently (ie, multiple times in a row in a very small interval).
     #[test]
diff --git a/src/unix/apple/system.rs b/src/unix/apple/system.rs
index b99a4a888..c04dc0752 100644
--- a/src/unix/apple/system.rs
+++ b/src/unix/apple/system.rs
@@ -29,7 +29,6 @@ pub(crate) struct SystemInner {
     swap_free: u64,
     page_size_b: u64,
     port: mach_port_t,
-    boot_time: u64,
     #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
     clock_info: Option<crate::sys::macos::system::SystemTimeInfo>,
     cpus: CpusWrapper,
@@ -88,7 +87,6 @@ impl SystemInner {
                 swap_free: 0,
                 page_size_b: sysconf(_SC_PAGESIZE) as _,
                 port,
-                boot_time: boot_time(),
                 #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
                 clock_info: crate::sys::macos::system::SystemTimeInfo::new(port),
                 cpus: CpusWrapper::new(),
@@ -321,15 +319,15 @@ impl SystemInner {
         self.swap_total - self.swap_free
     }
 
-    pub(crate) fn uptime(&self) -> u64 {
+    pub(crate) fn uptime() -> u64 {
         unsafe {
             let csec = libc::time(::std::ptr::null_mut());
 
-            libc::difftime(csec, self.boot_time as _) as u64
+            libc::difftime(csec, Self::boot_time() as _) as _
         }
     }
 
-    pub(crate) fn load_average(&self) -> LoadAvg {
+    pub(crate) fn load_average() -> LoadAvg {
         let mut loads = vec![0f64; 3];
 
         unsafe {
@@ -342,17 +340,17 @@ impl SystemInner {
         }
     }
 
-    pub(crate) fn boot_time(&self) -> u64 {
-        self.boot_time
+    pub(crate) fn boot_time() -> u64 {
+        boot_time()
     }
 
-    pub(crate) fn name(&self) -> Option<String> {
+    pub(crate) fn name() -> Option<String> {
         get_system_info(libc::KERN_OSTYPE, Some("Darwin"))
     }
 
-    pub(crate) fn long_os_version(&self) -> Option<String> {
+    pub(crate) fn long_os_version() -> Option<String> {
         #[cfg(target_os = "macos")]
-        let friendly_name = match self.os_version().unwrap_or_default() {
+        let friendly_name = match Self::os_version().unwrap_or_default() {
             f_n if f_n.starts_with("14.0") => "Sonoma",
             f_n if f_n.starts_with("10.16")
                 | f_n.starts_with("11.0")
@@ -383,25 +381,25 @@ impl SystemInner {
         #[cfg(target_os = "macos")]
         let long_name = Some(format!(
             "MacOS {} {}",
-            self.os_version().unwrap_or_default(),
+            Self::os_version().unwrap_or_default(),
             friendly_name
         ));
 
         #[cfg(target_os = "ios")]
-        let long_name = Some(format!("iOS {}", self.os_version().unwrap_or_default()));
+        let long_name = Some(format!("iOS {}", Self::os_version().unwrap_or_default()));
 
         long_name
     }
 
-    pub(crate) fn host_name(&self) -> Option<String> {
+    pub(crate) fn host_name() -> Option<String> {
         get_system_info(libc::KERN_HOSTNAME, None)
     }
 
-    pub(crate) fn kernel_version(&self) -> Option<String> {
+    pub(crate) fn kernel_version() -> Option<String> {
         get_system_info(libc::KERN_OSRELEASE, None)
     }
 
-    pub(crate) fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version() -> Option<String> {
         unsafe {
             // get the size for the buffer first
             let mut size = 0;
@@ -433,11 +431,11 @@ impl SystemInner {
         }
     }
 
-    pub(crate) fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id() -> String {
         std::env::consts::OS.to_owned()
     }
 
-    pub(crate) fn cpu_arch(&self) -> Option<String> {
+    pub(crate) fn cpu_arch() -> Option<String> {
         let mut arch_str: [u8; 32] = [0; 32];
         let mut mib = [libc::CTL_HW as _, libc::HW_MACHINE as _];
 
diff --git a/src/unix/freebsd/cpu.rs b/src/unix/freebsd/cpu.rs
index f2c784784..16e3fb75c 100644
--- a/src/unix/freebsd/cpu.rs
+++ b/src/unix/freebsd/cpu.rs
@@ -187,7 +187,7 @@ pub(crate) fn physical_core_count() -> Option<usize> {
 }
 
 unsafe fn get_frequency_for_cpu(cpu_nb: usize) -> u64 {
-    let mut frequency = 0;
+    let mut frequency: c_int = 0;
 
     // The information can be missing if it's running inside a VM.
     if !get_sys_value_by_name(
diff --git a/src/unix/freebsd/system.rs b/src/unix/freebsd/system.rs
index 776c2902e..d8fc23329 100644
--- a/src/unix/freebsd/system.rs
+++ b/src/unix/freebsd/system.rs
@@ -25,7 +25,6 @@ pub(crate) struct SystemInner {
     mem_used: u64,
     swap_total: u64,
     swap_used: u64,
-    boot_time: u64,
     system_info: SystemInfo,
     cpus: CpusWrapper,
 }
@@ -39,7 +38,6 @@ impl SystemInner {
             mem_used: 0,
             swap_total: 0,
             swap_used: 0,
-            boot_time: boot_time(),
             system_info: SystemInfo::new(),
             cpus: CpusWrapper::new(),
         }
@@ -186,19 +184,19 @@ impl SystemInner {
         self.swap_used
     }
 
-    pub(crate) fn uptime(&self) -> u64 {
+    pub(crate) fn uptime() -> u64 {
         unsafe {
             let csec = libc::time(std::ptr::null_mut());
 
-            libc::difftime(csec, self.boot_time as _) as u64
+            libc::difftime(csec, Self::boot_time() as _) as u64
         }
     }
 
-    pub(crate) fn boot_time(&self) -> u64 {
-        self.boot_time
+    pub(crate) fn boot_time() -> u64 {
+        boot_time()
     }
 
-    pub(crate) fn load_average(&self) -> LoadAvg {
+    pub(crate) fn load_average() -> LoadAvg {
         let mut loads = vec![0f64; 3];
         unsafe {
             libc::getloadavg(loads.as_mut_ptr(), 3);
@@ -210,31 +208,53 @@ impl SystemInner {
         }
     }
 
-    pub(crate) fn name(&self) -> Option<String> {
-        self.system_info.get_os_name()
+    pub(crate) fn name() -> Option<String> {
+        let mut os_type: [c_int; 2] = [0; 2];
+        unsafe {
+            init_mib(b"kern.ostype\0", &mut os_type);
+            get_system_info(&os_type, Some("FreeBSD"))
+        }
     }
 
-    pub(crate) fn long_os_version(&self) -> Option<String> {
-        self.system_info.get_os_release_long()
+    pub(crate) fn os_version() -> Option<String> {
+        let mut os_release: [c_int; 2] = [0; 2];
+        unsafe {
+            init_mib(b"kern.osrelease\0", &mut os_release);
+            // It returns something like "13.0-RELEASE". We want to keep everything until the "-".
+            get_system_info(&os_release, None)
+                .and_then(|s| s.split('-').next().map(|s| s.to_owned()))
+        }
     }
 
-    pub(crate) fn host_name(&self) -> Option<String> {
-        self.system_info.get_hostname()
+    pub(crate) fn long_os_version() -> Option<String> {
+        let mut os_release: [c_int; 2] = [0; 2];
+        unsafe {
+            init_mib(b"kern.osrelease\0", &mut os_release);
+            get_system_info(&os_release, None)
+        }
     }
 
-    pub(crate) fn kernel_version(&self) -> Option<String> {
-        self.system_info.get_kernel_version()
+    pub(crate) fn host_name() -> Option<String> {
+        let mut hostname: [c_int; 2] = [0; 2];
+        unsafe {
+            init_mib(b"kern.hostname\0", &mut hostname);
+            get_system_info(&hostname, None)
+        }
     }
 
-    pub(crate) fn os_version(&self) -> Option<String> {
-        self.system_info.get_os_release()
+    pub(crate) fn kernel_version() -> Option<String> {
+        let mut kern_version: [c_int; 2] = [0; 2];
+        unsafe {
+            init_mib(b"kern.version\0", &mut kern_version);
+            get_system_info(&kern_version, None)
+        }
     }
 
-    pub(crate) fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id() -> String {
         std::env::consts::OS.to_owned()
     }
 
-    pub(crate) fn cpu_arch(&self) -> Option<String> {
+    pub(crate) fn cpu_arch() -> Option<String> {
         let mut arch_str: [u8; 32] = [0; 32];
         let mib = [libc::CTL_HW as _, libc::HW_MACHINE as _];
 
@@ -429,10 +449,6 @@ struct SystemInfo {
     virtual_cache_count: [c_int; 4],
     virtual_inactive_count: [c_int; 4],
     virtual_free_count: [c_int; 4],
-    os_type: [c_int; 2],
-    os_release: [c_int; 2],
-    kern_version: [c_int; 2],
-    hostname: [c_int; 2],
     buf_space: [c_int; 2],
     kd: NonNull<libc::kvm_t>,
     /// From FreeBSD manual: "The kernel fixed-point scale factor". It's used when computing
@@ -470,10 +486,6 @@ impl SystemInfo {
                 virtual_inactive_count: Default::default(),
                 virtual_free_count: Default::default(),
                 buf_space: Default::default(),
-                os_type: Default::default(),
-                os_release: Default::default(),
-                kern_version: Default::default(),
-                hostname: Default::default(),
                 kd,
                 fscale: 0.,
                 procstat: std::ptr::null_mut(),
@@ -505,37 +517,10 @@ impl SystemInfo {
             init_mib(b"vm.stats.vm.v_free_count\0", &mut si.virtual_free_count);
             init_mib(b"vfs.bufspace\0", &mut si.buf_space);
 
-            init_mib(b"kern.ostype\0", &mut si.os_type);
-            init_mib(b"kern.osrelease\0", &mut si.os_release);
-            init_mib(b"kern.version\0", &mut si.kern_version);
-            init_mib(b"kern.hostname\0", &mut si.hostname);
-
             si
         }
     }
 
-    fn get_os_name(&self) -> Option<String> {
-        get_system_info(&[self.os_type[0], self.os_type[1]], Some("FreeBSD"))
-    }
-
-    fn get_kernel_version(&self) -> Option<String> {
-        get_system_info(&[self.kern_version[0], self.kern_version[1]], None)
-    }
-
-    fn get_os_release_long(&self) -> Option<String> {
-        get_system_info(&[self.os_release[0], self.os_release[1]], None)
-    }
-
-    fn get_os_release(&self) -> Option<String> {
-        // It returns something like "13.0-RELEASE". We want to keep everything until the "-".
-        get_system_info(&[self.os_release[0], self.os_release[1]], None)
-            .and_then(|s| s.split('-').next().map(|s| s.to_owned()))
-    }
-
-    fn get_hostname(&self) -> Option<String> {
-        get_system_info(&[self.hostname[0], self.hostname[1]], Some(""))
-    }
-
     /// Returns (used, total).
     fn get_swap_info(&self) -> (u64, u64) {
         // Magic number used in htop. Cannot find how they got it when reading `kvm_getswapinfo`
diff --git a/src/unix/linux/system.rs b/src/unix/linux/system.rs
index 92bfd57f3..16e3e630f 100644
--- a/src/unix/linux/system.rs
+++ b/src/unix/linux/system.rs
@@ -10,7 +10,7 @@ use std::cmp::min;
 use std::collections::HashMap;
 use std::ffi::CStr;
 use std::fs::File;
-use std::io::{BufRead, BufReader, Read};
+use std::io::Read;
 use std::path::Path;
 use std::str::FromStr;
 use std::sync::atomic::AtomicIsize;
@@ -59,12 +59,12 @@ pub(crate) fn get_max_nb_fds() -> isize {
 }
 
 fn boot_time() -> u64 {
-    if let Ok(f) = File::open("/proc/stat") {
-        let buf = BufReader::new(f);
-        let line = buf
-            .split(b'\n')
-            .filter_map(|r| r.ok())
-            .find(|l| l.starts_with(b"btime"));
+    if let Ok(buf) = File::open("/proc/stat").and_then(|mut f| {
+        let mut buf = Vec::new();
+        f.read_to_end(&mut buf)?;
+        Ok(buf)
+    }) {
+        let line = buf.split(|c| *c == b'\n').find(|l| l.starts_with(b"btime"));
 
         if let Some(line) = line {
             return line
@@ -235,7 +235,7 @@ impl SystemInner {
         filter: Option<&[Pid]>,
         refresh_kind: ProcessRefreshKind,
     ) {
-        let uptime = self.uptime();
+        let uptime = Self::uptime();
         refresh_procs(
             &mut self.process_list,
             Path::new("/proc"),
@@ -253,7 +253,7 @@ impl SystemInner {
         pid: Pid,
         refresh_kind: ProcessRefreshKind,
     ) -> bool {
-        let uptime = self.uptime();
+        let uptime = Self::uptime();
         match _get_process_data(
             &Path::new("/proc/").join(pid.to_string()),
             &mut self.process_list,
@@ -348,7 +348,7 @@ impl SystemInner {
         self.swap_total - self.swap_free
     }
 
-    pub(crate) fn uptime(&self) -> u64 {
+    pub(crate) fn uptime() -> u64 {
         let content = get_all_data("/proc/uptime", 50).unwrap_or_default();
         content
             .split('.')
@@ -357,11 +357,11 @@ impl SystemInner {
             .unwrap_or_default()
     }
 
-    pub(crate) fn boot_time(&self) -> u64 {
-        self.info.boot_time
+    pub(crate) fn boot_time() -> u64 {
+        boot_time()
     }
 
-    pub(crate) fn load_average(&self) -> LoadAvg {
+    pub(crate) fn load_average() -> LoadAvg {
         let mut s = String::new();
         if File::open("/proc/loadavg")
             .and_then(|mut f| f.read_to_string(&mut s))
@@ -383,7 +383,7 @@ impl SystemInner {
     }
 
     #[cfg(not(target_os = "android"))]
-    pub(crate) fn name(&self) -> Option<String> {
+    pub(crate) fn name() -> Option<String> {
         get_system_info_linux(
             InfoType::Name,
             Path::new("/etc/os-release"),
@@ -392,11 +392,11 @@ impl SystemInner {
     }
 
     #[cfg(target_os = "android")]
-    pub(crate) fn name(&self) -> Option<String> {
+    pub(crate) fn name() -> Option<String> {
         get_system_info_android(InfoType::Name)
     }
 
-    pub(crate) fn long_os_version(&self) -> Option<String> {
+    pub(crate) fn long_os_version() -> Option<String> {
         #[cfg(target_os = "android")]
         let system_name = "Android";
 
@@ -406,12 +406,12 @@ impl SystemInner {
         Some(format!(
             "{} {} {}",
             system_name,
-            self.os_version().unwrap_or_default(),
-            self.name().unwrap_or_default()
+            Self::os_version().unwrap_or_default(),
+            Self::name().unwrap_or_default()
         ))
     }
 
-    pub(crate) fn host_name(&self) -> Option<String> {
+    pub(crate) fn host_name() -> Option<String> {
         unsafe {
             let hostname_max = sysconf(_SC_HOST_NAME_MAX);
             let mut buffer = vec![0_u8; hostname_max as usize];
@@ -428,7 +428,7 @@ impl SystemInner {
         }
     }
 
-    pub(crate) fn kernel_version(&self) -> Option<String> {
+    pub(crate) fn kernel_version() -> Option<String> {
         let mut raw = std::mem::MaybeUninit::<libc::utsname>::zeroed();
 
         unsafe {
@@ -450,7 +450,7 @@ impl SystemInner {
     }
 
     #[cfg(not(target_os = "android"))]
-    pub(crate) fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version() -> Option<String> {
         get_system_info_linux(
             InfoType::OsVersion,
             Path::new("/etc/os-release"),
@@ -459,12 +459,12 @@ impl SystemInner {
     }
 
     #[cfg(target_os = "android")]
-    pub(crate) fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version() -> Option<String> {
         get_system_info_android(InfoType::OsVersion)
     }
 
     #[cfg(not(target_os = "android"))]
-    pub(crate) fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id() -> String {
         get_system_info_linux(
             InfoType::DistributionID,
             Path::new("/etc/os-release"),
@@ -474,7 +474,7 @@ impl SystemInner {
     }
 
     #[cfg(target_os = "android")]
-    pub(crate) fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id() -> String {
         // Currently get_system_info_android doesn't support InfoType::DistributionID and always
         // returns None. This call is done anyway for consistency with non-Android implementation
         // and to suppress dead-code warning for DistributionID on Android.
@@ -482,7 +482,7 @@ impl SystemInner {
             .unwrap_or_else(|| std::env::consts::OS.to_owned())
     }
 
-    pub(crate) fn cpu_arch(&self) -> Option<String> {
+    pub(crate) fn cpu_arch() -> Option<String> {
         let mut raw = std::mem::MaybeUninit::<libc::utsname>::uninit();
 
         unsafe {
@@ -594,16 +594,18 @@ enum InfoType {
 
 #[cfg(not(target_os = "android"))]
 fn get_system_info_linux(info: InfoType, path: &Path, fallback_path: &Path) -> Option<String> {
-    if let Ok(f) = File::open(path) {
-        let reader = BufReader::new(f);
-
+    if let Ok(buf) = File::open(path).and_then(|mut f| {
+        let mut buf = String::new();
+        f.read_to_string(&mut buf)?;
+        Ok(buf)
+    }) {
         let info_str = match info {
             InfoType::Name => "NAME=",
             InfoType::OsVersion => "VERSION_ID=",
             InfoType::DistributionID => "ID=",
         };
 
-        for line in reader.lines().map_while(Result::ok) {
+        for line in buf.lines() {
             if let Some(stripped) = line.strip_prefix(info_str) {
                 return Some(stripped.replace('"', ""));
             }
@@ -614,7 +616,13 @@ fn get_system_info_linux(info: InfoType, path: &Path, fallback_path: &Path) -> O
     // VERSION_ID is not required in the `/etc/os-release` file
     // per https://www.linux.org/docs/man5/os-release.html
     // If this fails for some reason, fallback to None
-    let reader = BufReader::new(File::open(fallback_path).ok()?);
+    let buf = File::open(fallback_path)
+        .and_then(|mut f| {
+            let mut buf = String::new();
+            f.read_to_string(&mut buf)?;
+            Ok(buf)
+        })
+        .ok()?;
 
     let info_str = match info {
         InfoType::OsVersion => "DISTRIB_RELEASE=",
@@ -624,7 +632,7 @@ fn get_system_info_linux(info: InfoType, path: &Path, fallback_path: &Path) -> O
             return None;
         }
     };
-    for line in reader.lines().map_while(Result::ok) {
+    for line in buf.lines() {
         if let Some(stripped) = line.strip_prefix(info_str) {
             return Some(stripped.replace('"', ""));
         }
diff --git a/src/unknown/system.rs b/src/unknown/system.rs
index 75aa7104f..766038fb6 100644
--- a/src/unknown/system.rs
+++ b/src/unknown/system.rs
@@ -94,15 +94,15 @@ impl SystemInner {
         0
     }
 
-    pub(crate) fn uptime(&self) -> u64 {
+    pub(crate) fn uptime() -> u64 {
         0
     }
 
-    pub(crate) fn boot_time(&self) -> u64 {
+    pub(crate) fn boot_time() -> u64 {
         0
     }
 
-    pub(crate) fn load_average(&self) -> LoadAvg {
+    pub(crate) fn load_average() -> LoadAvg {
         LoadAvg {
             one: 0.,
             five: 0.,
@@ -110,30 +110,30 @@ impl SystemInner {
         }
     }
 
-    pub(crate) fn name(&self) -> Option<String> {
+    pub(crate) fn name() -> Option<String> {
         None
     }
 
-    pub(crate) fn long_os_version(&self) -> Option<String> {
+    pub(crate) fn long_os_version() -> Option<String> {
         None
     }
 
-    pub(crate) fn kernel_version(&self) -> Option<String> {
+    pub(crate) fn kernel_version() -> Option<String> {
         None
     }
 
-    pub(crate) fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version() -> Option<String> {
         None
     }
 
-    pub(crate) fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id() -> String {
         std::env::consts::OS.to_owned()
     }
 
-    pub(crate) fn host_name(&self) -> Option<String> {
+    pub(crate) fn host_name() -> Option<String> {
         None
     }
-    pub(crate) fn cpu_arch(&self) -> Option<String> {
+    pub(crate) fn cpu_arch() -> Option<String> {
         None
     }
 }
diff --git a/src/windows/system.rs b/src/windows/system.rs
index bb9f86800..50f3fd144 100644
--- a/src/windows/system.rs
+++ b/src/windows/system.rs
@@ -32,10 +32,9 @@ use windows::Win32::System::Threading::GetExitCodeProcess;
 const WINDOWS_ELEVEN_BUILD_NUMBER: u32 = 22000;
 
 impl SystemInner {
-    fn is_windows_eleven(&self) -> bool {
+    fn is_windows_eleven() -> bool {
         WINDOWS_ELEVEN_BUILD_NUMBER
-            <= self
-                .kernel_version()
+            <= Self::kernel_version()
                 .unwrap_or_default()
                 .parse()
                 .unwrap_or(0)
@@ -67,7 +66,6 @@ pub(crate) struct SystemInner {
     swap_used: u64,
     cpus: CpusWrapper,
     query: Option<Query>,
-    boot_time: u64,
 }
 
 impl SystemInner {
@@ -80,7 +78,6 @@ impl SystemInner {
             swap_used: 0,
             cpus: CpusWrapper::new(),
             query: None,
-            boot_time: unsafe { boot_time() },
         }
     }
 
@@ -410,24 +407,24 @@ impl SystemInner {
         self.swap_used
     }
 
-    pub(crate) fn uptime(&self) -> u64 {
+    pub(crate) fn uptime() -> u64 {
         unsafe { GetTickCount64() / 1_000 }
     }
 
-    pub(crate) fn boot_time(&self) -> u64 {
-        self.boot_time
+    pub(crate) fn boot_time() -> u64 {
+        unsafe { boot_time() }
     }
 
-    pub(crate) fn load_average(&self) -> LoadAvg {
+    pub(crate) fn load_average() -> LoadAvg {
         get_load_average()
     }
 
-    pub(crate) fn name(&self) -> Option<String> {
+    pub(crate) fn name() -> Option<String> {
         Some("Windows".to_owned())
     }
 
-    pub(crate) fn long_os_version(&self) -> Option<String> {
-        if self.is_windows_eleven() {
+    pub(crate) fn long_os_version() -> Option<String> {
+        if Self::is_windows_eleven() {
             return get_reg_string_value(
                 HKEY_LOCAL_MACHINE,
                 "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
@@ -442,11 +439,11 @@ impl SystemInner {
         )
     }
 
-    pub(crate) fn host_name(&self) -> Option<String> {
+    pub(crate) fn host_name() -> Option<String> {
         get_dns_hostname()
     }
 
-    pub(crate) fn kernel_version(&self) -> Option<String> {
+    pub(crate) fn kernel_version() -> Option<String> {
         get_reg_string_value(
             HKEY_LOCAL_MACHINE,
             "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
@@ -454,14 +451,14 @@ impl SystemInner {
         )
     }
 
-    pub(crate) fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version() -> Option<String> {
         let build_number = get_reg_string_value(
             HKEY_LOCAL_MACHINE,
             "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
             "CurrentBuildNumber",
         )
         .unwrap_or_default();
-        let major = if self.is_windows_eleven() {
+        let major = if Self::is_windows_eleven() {
             11u32
         } else {
             u32::from_le_bytes(
@@ -476,10 +473,10 @@ impl SystemInner {
         Some(format!("{major} ({build_number})"))
     }
 
-    pub(crate) fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id() -> String {
         std::env::consts::OS.to_owned()
     }
-    pub(crate) fn cpu_arch(&self) -> Option<String> {
+    pub(crate) fn cpu_arch() -> Option<String> {
         unsafe {
             // https://docs.microsoft.com/fr-fr/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info
             let info = SYSTEM_INFO::default();


Test patch:
diff --git a/tests/process.rs b/tests/process.rs
index 9c67fa1b3..582cfa335 100644
--- a/tests/process.rs
+++ b/tests/process.rs
@@ -272,6 +272,8 @@ fn test_process_times() {
     if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
+    let boot_time = System::boot_time();
+    assert!(boot_time > 0);
     let mut p = if cfg!(target_os = "windows") {
         std::process::Command::new("waitfor")
             .arg("/t")
@@ -300,15 +302,15 @@ fn test_process_times() {
         assert!(p.run_time() <= 2);
         assert!(p.start_time() > p.run_time());
         // On linux, for whatever reason, the uptime seems to be older than the boot time, leading
-        // to this weird `+ 3` to ensure the test is passing as it should...
+        // to this weird `+ 5` to ensure the test is passing as it should...
         assert!(
-            p.start_time() + 3
+            p.start_time() + 5
                 > SystemTime::now()
                     .duration_since(UNIX_EPOCH)
                     .unwrap()
                     .as_secs(),
         );
-        assert!(p.start_time() >= s.boot_time());
+        assert!(p.start_time() >= boot_time);
     } else {
         panic!("Process not found!");
     }
diff --git a/tests/uptime.rs b/tests/uptime.rs
deleted file mode 100644
index 388feca69..000000000
--- a/tests/uptime.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Take a look at the license at the top of the repository in the LICENSE file.
-
-#[test]
-fn test_uptime() {
-    if sysinfo::IS_SUPPORTED {
-        let mut s = sysinfo::System::new();
-        s.refresh_all();
-        assert!(s.uptime() != 0);
-    }
-}