Repository: GuillaumeGomez/sysinfo
Pull request #1092 (2023-10-08 20:56:49)

Remove `SystemExt` trait
Part of https://github.com/GuillaumeGomez/sysinfo/issues/1088.


Patch:
diff --git a/README.md b/README.md
index 74f17c4..0f87c74 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ It currently supports the following OSes (alphabetically sorted):
 
 You can still use `sysinfo` on non-supported OSes, it'll simply do nothing and always return
 empty values. You can check in your program directly if an OS is supported by checking the
-[`SystemExt::IS_SUPPORTED`] constant.
+[`IS_SUPPORTED`] constant.
 
 The minimum-supported version of `rustc` is **1.63**.
 
@@ -36,7 +36,7 @@ Otherwise, here is a little code sample:
 ```rust
 use sysinfo::{
     Components, ComponentsExt, Disks, NetworkExt, Networks,
-    NetworksExt, ProcessExt, System, SystemExt,
+    NetworksExt, ProcessExt, System,
 };
 
 // Please note that we use "new_all" to ensure that all list of
@@ -100,7 +100,7 @@ Please remember that to have some up-to-date information, you need to call the e
 `refresh` method. For example, for the CPU usage:
 
 ```rust,no_run
-use sysinfo::{CpuExt, System, SystemExt};
+use sysinfo::{CpuExt, System};
 
 let mut sys = System::new();
 
@@ -111,7 +111,7 @@ loop {
     }
     // Sleeping to let time for the system to run for long
     // enough to have useful information.
-    std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL);
+    std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
 }
 ```
 
diff --git a/benches/basic.rs b/benches/basic.rs
index ef28e36..d44d710 100644
--- a/benches/basic.rs
+++ b/benches/basic.rs
@@ -3,7 +3,7 @@
 extern crate test;
 
 use sysinfo::get_current_pid;
-use sysinfo::{ComponentsExt, NetworksExt, SystemExt, UsersExt};
+use sysinfo::{ComponentsExt, NetworksExt, UsersExt};
 
 #[bench]
 fn bench_new(b: &mut test::Bencher) {
diff --git a/examples/simple.rs b/examples/simple.rs
index eb64cee..c088407 100644
--- a/examples/simple.rs
+++ b/examples/simple.rs
@@ -9,7 +9,7 @@ use std::str::FromStr;
 use sysinfo::Signal::*;
 use sysinfo::{
     Components, ComponentsExt, CpuExt, Disks, NetworkExt, Networks, NetworksExt, Pid, ProcessExt,
-    Signal, System, SystemExt, UserExt, Users, UsersExt,
+    Signal, System, UserExt, Users, UsersExt,
 };
 
 const signals: &[Signal] = &[
diff --git a/md_doc/is_supported.md b/md_doc/is_supported.md
new file mode 100644
index 0000000..672674e
--- /dev/null
+++ b/md_doc/is_supported.md
@@ -0,0 +1,10 @@
+Returns `true` if this OS is supported. Please refer to the
+[crate-level documentation](index.html) to get the list of supported OSes.
+
+```
+if sysinfo::IS_SUPPORTED {
+    println!("This OS is supported!");
+} else {
+    println!("This OS isn't supported (yet?).");
+}
+```
diff --git a/md_doc/minimum_cpu_update_interval.md b/md_doc/minimum_cpu_update_interval.md
new file mode 100644
index 0000000..9c7921f
--- /dev/null
+++ b/md_doc/minimum_cpu_update_interval.md
@@ -0,0 +1,8 @@
+This is the minimum interval time used internally by `sysinfo` to refresh the CPU time.
+
+⚠️ This value differs from one OS to another.
+
+Why is this constant even needed?
+
+If refreshed too often, the CPU usage of processes will be `0` whereas on Linux it'll
+always be the maximum value (`number of CPUs * 100`).
diff --git a/md_doc/serde.md b/md_doc/serde.md
index 35562fc..31b79b5 100644
--- a/md_doc/serde.md
+++ b/md_doc/serde.md
@@ -2,7 +2,7 @@
 With the `serde` feature enabled, you can then serialize `sysinfo` types. Let's see an example with `serde_json`:
 
 ```
-use sysinfo::{System, SystemExt};
+use sysinfo::System;
 
 let mut sys = System::new_all();
 // First we update all information of our `System` struct.
diff --git a/md_doc/supported_signals.md b/md_doc/supported_signals.md
new file mode 100644
index 0000000..ded9479
--- /dev/null
+++ b/md_doc/supported_signals.md
@@ -0,0 +1,8 @@
+Returns the list of the supported signals on this system (used by
+[`ProcessExt::kill_with`][crate::ProcessExt::kill_with]).
+
+```
+use sysinfo::{System, SUPPORTED_SIGNALS};
+
+println!("supported signals: {:?}", SUPPORTED_SIGNALS);
+```
diff --git a/md_doc/system.md b/md_doc/system.md
deleted file mode 100644
index faf50b9..0000000
--- a/md_doc/system.md
+++ /dev/null
@@ -1,1 +0,0 @@
-Structs containing system's information.
diff --git a/src/c_interface.rs b/src/c_interface.rs
index b7cbff3..e066534 100644
--- a/src/c_interface.rs
+++ b/src/c_interface.rs
@@ -1,8 +1,6 @@
 // Take a look at the license at the top of the repository in the LICENSE file.
 
-use crate::{
-    CpuExt, Disks, NetworkExt, Networks, NetworksExt, Pid, Process, ProcessExt, System, SystemExt,
-};
+use crate::{CpuExt, Disks, NetworkExt, Networks, NetworksExt, Pid, Process, ProcessExt, System};
 use libc::{self, c_char, c_float, c_uint, c_void, size_t};
 use std::borrow::BorrowMut;
 use std::ffi::CString;
diff --git a/src/common.rs b/src/common.rs
index 62a89b8..9b42beb 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -1,8 +1,8 @@
 // Take a look at the license at the top of the repository in the LICENSE file.
 
 use crate::{
-    Component, Components, ComponentsExt, GroupExt, NetworkData, NetworksExt, User, UserExt,
-    UsersExt,
+    Component, Components, ComponentsExt, Cpu, GroupExt, NetworkData, NetworksExt, Process,
+    ProcessExt, SystemInner, User, UserExt, UsersExt,
 };
 
 use std::cmp::Ordering;
@@ -13,6 +13,671 @@ use std::fmt;
 use std::path::Path;
 use std::str::FromStr;
 
+/// Structs containing system's information such as processes, memory and CPU.
+///
+/// ```
+/// use sysinfo::System;
+///
+/// if sysinfo::IS_SUPPORTED {
+///     println!("System: {:?}", System::new_all());
+/// } else {
+///     println!("This OS isn't supported (yet?).");
+/// }
+/// ```
+pub struct System {
+    pub(crate) inner: SystemInner,
+}
+
+impl Default for System {
+    fn default() -> System {
+        System::new()
+    }
+}
+
+impl System {
+    /// Creates a new [`System`] instance with nothing loaded.
+    ///
+    /// Use the [`refresh_all`] method to update its internal information (or any of the `refresh_`
+    /// method).
+    ///
+    /// [`System`]: crate::System
+    /// [`refresh_all`]: #method.refresh_all
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new();
+    /// ```
+    pub fn new() -> Self {
+        Self::new_with_specifics(RefreshKind::new())
+    }
+
+    /// Creates a new [`System`] instance with everything loaded.
+    ///
+    /// It is an equivalent of [`System::new_with_specifics`]`(`[`RefreshKind::everything`]`())`.
+    ///
+    /// [`System`]: crate::System
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new_all();
+    /// ```
+    pub fn new_all() -> Self {
+        Self::new_with_specifics(RefreshKind::everything())
+    }
+
+    /// Creates a new [`System`] instance and refresh the data corresponding to the
+    /// given [`RefreshKind`].
+    ///
+    /// [`System`]: crate::System
+    ///
+    /// ```
+    /// use sysinfo::{ProcessRefreshKind, RefreshKind, System};
+    ///
+    /// // We want to only refresh processes.
+    /// let mut system = System::new_with_specifics(
+    ///      RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
+    /// );
+    ///
+    /// # if sysinfo::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") {
+    /// assert!(!system.processes().is_empty());
+    /// # }
+    /// ```
+    pub fn new_with_specifics(refreshes: RefreshKind) -> Self {
+        let mut s = Self {
+            inner: SystemInner::new(),
+        };
+        s.refresh_specifics(refreshes);
+        s
+    }
+
+    /// Refreshes according to the given [`RefreshKind`]. It calls the corresponding
+    /// "refresh_" methods.
+    ///
+    /// ```
+    /// use sysinfo::{ProcessRefreshKind, RefreshKind, System};
+    ///
+    /// let mut s = System::new_all();
+    ///
+    /// // Let's just update processes:
+    /// s.refresh_specifics(
+    ///     RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
+    /// );
+    /// ```
+    pub fn refresh_specifics(&mut self, refreshes: RefreshKind) {
+        if refreshes.memory() {
+            self.refresh_memory();
+        }
+        if let Some(kind) = refreshes.cpu() {
+            self.refresh_cpu_specifics(kind);
+        }
+        if let Some(kind) = refreshes.processes() {
+            self.refresh_processes_specifics(kind);
+        }
+    }
+
+    /// Refreshes all system and processes information.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_all();
+    /// ```
+    pub fn refresh_all(&mut self) {
+        self.refresh_system();
+        self.refresh_processes();
+    }
+
+    /// Refreshes system information (RAM, swap, CPU usage and components' temperature).
+    ///
+    /// If you want some more specific refreshes, you might be interested into looking at
+    /// [`refresh_memory`] and [`refresh_cpu`].
+    ///
+    /// [`refresh_memory`]: System::refresh_memory
+    /// [`refresh_cpu`]: System::refresh_memory
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_system();
+    /// ```
+    pub fn refresh_system(&mut self) {
+        self.refresh_memory();
+        self.refresh_cpu_usage();
+    }
+
+    /// Refreshes RAM and SWAP usage.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_memory();
+    /// ```
+    pub fn refresh_memory(&mut self) {
+        self.inner.refresh_memory()
+    }
+
+    /// Refreshes CPUs usage.
+    ///
+    /// ⚠️ Please note that the result will very likely be inaccurate at the first call.
+    /// You need to call this method at least twice (with a bit of time between each call, like
+    /// 200 ms, take a look at [`MINIMUM_CPU_UPDATE_INTERVAL`] for more information)
+    /// to get accurate value as it uses previous results to compute the next value.
+    ///
+    /// Calling this method is the same as calling
+    /// `refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage())`.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_cpu_usage();
+    /// ```
+    ///
+    /// [`MINIMUM_CPU_UPDATE_INTERVAL`]: crate::MINIMUM_CPU_UPDATE_INTERVAL
+    pub fn refresh_cpu_usage(&mut self) {
+        self.refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage())
+    }
+
+    /// Refreshes CPUs frequency information.
+    ///
+    /// Calling this method is the same as calling
+    /// `refresh_cpu_specifics(CpuRefreshKind::new().with_frequency())`.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_cpu_frequency();
+    /// ```
+    pub fn refresh_cpu_frequency(&mut self) {
+        self.refresh_cpu_specifics(CpuRefreshKind::new().with_frequency())
+    }
+
+    /// Refreshes all information related to CPUs information.
+    ///
+    /// ⚠️ Please note that the result will very likely be inaccurate at the first call.
+    /// You need to call this method at least twice (with a bit of time between each call, like
+    /// 200 ms, take a look at [`MINIMUM_CPU_UPDATE_INTERVAL`] for more information)
+    /// to get accurate value as it uses previous results to compute the next value.
+    ///
+    /// Calling this method is the same as calling
+    /// `refresh_cpu_specifics(CpuRefreshKind::everything())`.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_cpu();
+    /// ```
+    ///
+    /// [`MINIMUM_CPU_UPDATE_INTERVAL`]: crate::MINIMUM_CPU_UPDATE_INTERVAL
+    pub fn refresh_cpu(&mut self) {
+        self.refresh_cpu_specifics(CpuRefreshKind::everything())
+    }
+
+    /// Refreshes CPUs specific information.
+    ///
+    /// ```no_run
+    /// use sysinfo::{System, CpuRefreshKind};
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_cpu_specifics(CpuRefreshKind::everything());
+    /// ```
+    pub fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) {
+        self.inner.refresh_cpu_specifics(refresh_kind)
+    }
+
+    /// Gets all processes and updates their information.
+    ///
+    /// It does the same as `system.refresh_processes_specifics(ProcessRefreshKind::everything())`.
+    ///
+    /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour
+    /// by using [`set_open_files_limit`][crate::set_open_files_limit].
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_processes();
+    /// ```
+    pub fn refresh_processes(&mut self) {
+        self.refresh_processes_specifics(ProcessRefreshKind::everything());
+    }
+
+    /// Gets all processes and updates the specified information.
+    ///
+    /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour
+    /// by using [`set_open_files_limit`][crate::set_open_files_limit].
+    ///
+    /// ```no_run
+    /// use sysinfo::{ProcessRefreshKind, System};
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_processes_specifics(ProcessRefreshKind::new());
+    /// ```
+    pub fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) {
+        self.inner.refresh_processes_specifics(refresh_kind)
+    }
+
+    /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't
+    /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it
+    /// isn't listed yet, it'll be added.
+    ///
+    /// It is the same as calling
+    /// `sys.refresh_process_specifics(pid, ProcessRefreshKind::everything())`.
+    ///
+    /// ```no_run
+    /// use sysinfo::{Pid, System};
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_process(Pid::from(1337));
+    /// ```
+    pub fn refresh_process(&mut self, pid: Pid) -> bool {
+        self.refresh_process_specifics(pid, ProcessRefreshKind::everything())
+    }
+
+    /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't
+    /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it
+    /// isn't listed yet, it'll be added.
+    ///
+    /// ```no_run
+    /// use sysinfo::{Pid, ProcessRefreshKind, System};
+    ///
+    /// let mut s = System::new_all();
+    /// s.refresh_process_specifics(Pid::from(1337), ProcessRefreshKind::new());
+    /// ```
+    pub fn refresh_process_specifics(
+        &mut self,
+        pid: Pid,
+        refresh_kind: ProcessRefreshKind,
+    ) -> bool {
+        self.inner.refresh_process_specifics(pid, refresh_kind)
+    }
+
+    /// Returns the process list.
+    ///
+    /// ```no_run
+    /// use sysinfo::{ProcessExt, System};
+    ///
+    /// let s = System::new_all();
+    /// for (pid, process) in s.processes() {
+    ///     println!("{} {}", pid, process.name());
+    /// }
+    /// ```
+    pub fn processes(&self) -> &HashMap<Pid, Process> {
+        self.inner.processes()
+    }
+
+    /// Returns the process corresponding to the given `pid` or `None` if no such process exists.
+    ///
+    /// ```no_run
+    /// use sysinfo::{Pid, ProcessExt, System};
+    ///
+    /// let s = System::new_all();
+    /// if let Some(process) = s.process(Pid::from(1337)) {
+    ///     println!("{}", process.name());
+    /// }
+    /// ```
+    pub fn process(&self, pid: Pid) -> Option<&Process> {
+        self.inner.process(pid)
+    }
+
+    /// Returns an iterator of process containing the given `name`.
+    ///
+    /// If you want only the processes with exactly the given `name`, take a look at
+    /// [`System::processes_by_exact_name`].
+    ///
+    /// **⚠️ Important ⚠️**
+    ///
+    /// On **Linux**, there are two things to know about processes' name:
+    ///  1. It is limited to 15 characters.
+    ///  2. It is not always the exe name.
+    ///
+    /// ```no_run
+    /// use sysinfo::{ProcessExt, System};
+    ///
+    /// let s = System::new_all();
+    /// for process in s.processes_by_name("htop") {
+    ///     println!("{} {}", process.pid(), process.name());
+    /// }
+    /// ```
+    // FIXME: replace the returned type with `impl Iterator<Item = &Process>` when it's supported!
+    pub fn processes_by_name<'a: 'b, 'b>(
+        &'a self,
+        name: &'b str,
+    ) -> Box<dyn Iterator<Item = &'a Process> + 'b> {
+        Box::new(
+            self.processes()
+                .values()
+                .filter(move |val: &&Process| val.name().contains(name)),
+        )
+    }
+
+    /// Returns an iterator of processes with exactly the given `name`.
+    ///
+    /// If you instead want the processes containing `name`, take a look at
+    /// [`System::processes_by_name`].
+    ///
+    /// **⚠️ Important ⚠️**
+    ///
+    /// On **Linux**, there are two things to know about processes' name:
+    ///  1. It is limited to 15 characters.
+    ///  2. It is not always the exe name.
+    ///
+    /// ```no_run
+    /// use sysinfo::{ProcessExt, System};
+    ///
+    /// let s = System::new_all();
+    /// for process in s.processes_by_exact_name("htop") {
+    ///     println!("{} {}", process.pid(), process.name());
+    /// }
+    /// ```
+    // FIXME: replace the returned type with `impl Iterator<Item = &Process>` when it's supported!
+    pub fn processes_by_exact_name<'a: 'b, 'b>(
+        &'a self,
+        name: &'b str,
+    ) -> Box<dyn Iterator<Item = &'a Process> + 'b> {
+        Box::new(
+            self.processes()
+                .values()
+                .filter(move |val: &&Process| val.name() == name),
+        )
+    }
+
+    /// Returns "global" CPUs information (aka the addition of all the CPUs).
+    ///
+    /// To have up-to-date information, you need to call [`System::refresh_cpu`] or
+    /// [`System::refresh_specifics`] with `cpu` enabled.
+    ///
+    /// **⚠️ Important ⚠️**
+    ///
+    /// Information like [`CpuExt::brand`], [`CpuExt::vendor_id`] or [`CpuExt::frequency`]
+    /// are not set on the "global" CPU.
+    ///
+    /// ```no_run
+    /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System};
+    ///
+    /// let s = System::new_with_specifics(
+    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
+    /// );
+    /// println!("{}%", s.global_cpu_info().cpu_usage());
+    /// ```
+    ///
+    /// [`CpuExt::brand`]: crate::CpuExt::brand
+    /// [`CpuExt::vendor_id`]: crate::CpuExt::vendor_id
+    /// [`CpuExt::frequency`]: crate::CpuExt::frequency
+    pub fn global_cpu_info(&self) -> &Cpu {
+        self.inner.global_cpu_info()
+    }
+
+    /// Returns the list of the CPUs.
+    ///
+    /// By default, the list of CPUs is empty until you call [`System::refresh_cpu`] or
+    /// [`System::refresh_specifics`] with `cpu` enabled.
+    ///
+    /// ```no_run
+    /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System};
+    ///
+    /// let s = System::new_with_specifics(
+    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
+    /// );
+    /// for cpu in s.cpus() {
+    ///     println!("{}%", cpu.cpu_usage());
+    /// }
+    /// ```
+    pub fn cpus(&self) -> &[Cpu] {
+        self.inner.cpus()
+    }
+
+    /// Returns the number of physical cores on the CPU or `None` if it couldn't get it.
+    ///
+    /// In case there are multiple CPUs, it will combine the physical core count of all the CPUs.
+    ///
+    /// **Important**: this information is computed every time this function is called.
+    ///
+    /// ```no_run
+    /// use sysinfo::{CpuExt, System};
+    ///
+    /// let s = System::new();
+    /// println!("{:?}", s.physical_core_count());
+    /// ```
+    pub fn physical_core_count(&self) -> Option<usize> {
+        self.inner.physical_core_count()
+    }
+
+    /// Returns the RAM size in bytes.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new_all();
+    /// println!("{} bytes", s.total_memory());
+    /// ```
+    pub fn total_memory(&self) -> u64 {
+        self.inner.total_memory()
+    }
+
+    /// Returns the amount of free RAM in bytes.
+    ///
+    /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to
+    /// memory that is available for (re)use.
+    ///
+    /// Side note: Windows doesn't report "free" memory so this method returns the same value
+    /// as [`available_memory`](System::available_memory).
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new_all();
+    /// println!("{} bytes", s.free_memory());
+    /// ```
+    pub fn free_memory(&self) -> u64 {
+        self.inner.free_memory()
+    }
+
+    /// Returns the amount of available RAM in bytes.
+    ///
+    /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to
+    /// memory that is available for (re)use.
+    ///
+    /// ⚠️ Windows and FreeBSD don't report "available" memory so [`System::free_memory`]
+    /// returns the same value as this method.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new_all();
+    /// println!("{} bytes", s.available_memory());
+    /// ```
+    pub fn available_memory(&self) -> u64 {
+        self.inner.available_memory()
+    }
+
+    /// Returns the amount of used RAM in bytes.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new_all();
+    /// println!("{} bytes", s.used_memory());
+    /// ```
+    pub fn used_memory(&self) -> u64 {
+        self.inner.used_memory()
+    }
+
+    /// Returns the SWAP size in bytes.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new_all();
+    /// println!("{} bytes", s.total_swap());
+    /// ```
+    pub fn total_swap(&self) -> u64 {
+        self.inner.total_swap()
+    }
+
+    /// Returns the amount of free SWAP in bytes.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new_all();
+    /// println!("{} bytes", s.free_swap());
+    /// ```
+    pub fn free_swap(&self) -> u64 {
+        self.inner.free_swap()
+    }
+
+    /// Returns the amount of used SWAP in bytes.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new_all();
+    /// println!("{} bytes", s.used_swap());
+    /// ```
+    pub fn used_swap(&self) -> u64 {
+        self.inner.used_swap()
+    }
+
+    /// Returns system uptime (in seconds).
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new_all();
+    /// println!("System running since {} seconds", s.uptime());
+    /// ```
+    pub fn uptime(&self) -> u64 {
+        self.inner.uptime()
+    }
+
+    /// Returns the time (in seconds) when the system booted since UNIX epoch.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new();
+    /// println!("System booted at {} seconds", s.boot_time());
+    /// ```
+    pub fn boot_time(&self) -> u64 {
+        self.inner.boot_time()
+    }
+
+    /// Returns the system load average value.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new_all();
+    /// let load_avg = s.load_average();
+    /// println!(
+    ///     "one minute: {}%, five minutes: {}%, fifteen minutes: {}%",
+    ///     load_avg.one,
+    ///     load_avg.five,
+    ///     load_avg.fifteen,
+    /// );
+    /// ```
+    pub fn load_average(&self) -> LoadAvg {
+        self.inner.load_average()
+    }
+
+    /// Returns the system name.
+    ///
+    /// **Important**: this information is computed every time this function is called.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new();
+    /// println!("OS: {:?}", s.name());
+    /// ```
+    pub fn name(&self) -> Option<String> {
+        self.inner.name()
+    }
+
+    /// Returns the system's kernel version.
+    ///
+    /// **Important**: this information is computed every time this function is called.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new();
+    /// println!("kernel version: {:?}", s.kernel_version());
+    /// ```
+    pub fn kernel_version(&self) -> Option<String> {
+        self.inner.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());
+    /// ```
+    pub fn os_version(&self) -> Option<String> {
+        self.inner.os_version()
+    }
+
+    /// Returns the system long os version (e.g "MacOS 11.2 BigSur").
+    ///
+    /// **Important**: this information is computed every time this function is called.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new();
+    /// println!("Long OS Version: {:?}", s.long_os_version());
+    /// ```
+    pub fn long_os_version(&self) -> Option<String> {
+        self.inner.long_os_version()
+    }
+
+    /// Returns the distribution id as defined by os-release,
+    /// or [`std::env::consts::OS`].
+    ///
+    /// See also
+    /// - <https://www.freedesktop.org/software/systemd/man/os-release.html#ID=>
+    /// - <https://doc.rust-lang.org/std/env/consts/constant.OS.html>
+    ///
+    /// **Important**: this information is computed every time this function is called.
+    ///
+    /// ```no_run
+    /// use sysinfo::System;
+    ///
+    /// let s = System::new();
+    /// println!("Distribution ID: {:?}", s.distribution_id());
+    /// ```
+    pub fn distribution_id(&self) -> String {
+        self.inner.distribution_id()
+    }
+
+    /// 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());
+    /// ```
+    pub fn host_name(&self) -> Option<String> {
+        self.inner.host_name()
+    }
+}
+
 /// Trait to have a common conversions for the [`Pid`][crate::Pid] type.
 ///
 /// ```
@@ -219,7 +884,7 @@ assert_eq!(r.", stringify!($name), "().is_some(), false);
 /// extra computation.
 ///
 /// ```
-/// use sysinfo::{ProcessExt, ProcessRefreshKind, System, SystemExt};
+/// use sysinfo::{ProcessExt, ProcessRefreshKind, System};
 ///
 /// let mut system = System::new();
 ///
@@ -297,7 +962,7 @@ on Windows as other platforms get this information alongside the Process informa
 /// extra computation.
 ///
 /// ```
-/// use sysinfo::{CpuExt, CpuRefreshKind, System, SystemExt};
+/// use sysinfo::{CpuExt, CpuRefreshKind, System};
 ///
 /// let mut system = System::new();
 ///
@@ -357,13 +1022,13 @@ impl CpuRefreshKind {
 /// extra computation.
 ///
 /// ```
-/// use sysinfo::{RefreshKind, System, SystemExt};
+/// use sysinfo::{RefreshKind, System};
 ///
 /// // We want everything except memory.
 /// let mut system = System::new_with_specifics(RefreshKind::everything().without_memory());
 ///
 /// assert_eq!(system.total_memory(), 0);
-/// # if System::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") {
+/// # if sysinfo::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") {
 /// assert!(system.processes().len() > 0);
 /// # }
 /// ```
@@ -857,7 +1522,7 @@ impl std::ops::DerefMut for Users {
 /// the different OSes.
 ///
 /// If you want the list of the supported signals on the current system, use
-/// [`SystemExt::SUPPORTED_SIGNALS`][crate::SystemExt::SUPPORTED_SIGNALS].
+/// [`SUPPORTED_SIGNALS`][crate::SUPPORTED_SIGNALS].
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
 pub enum Signal {
     /// Hangup detected on controlling terminal or death of controlling process.
@@ -970,10 +1635,10 @@ impl std::fmt::Display for Signal {
 
 /// A struct representing system load average value.
 ///
-/// It is returned by [`SystemExt::load_average`][crate::SystemExt::load_average].
+/// It is returned by [`System::load_average`][crate::System::load_average].
 ///
 /// ```no_run
-/// use sysinfo::{System, SystemExt};
+/// use sysinfo::System;
 ///
 /// let s = System::new_all();
 /// let load_avg = s.load_average();
@@ -1147,7 +1812,7 @@ impl GroupExt for Group {
 /// It is returned by [`ProcessExt::disk_usage`][crate::ProcessExt::disk_usage].
 ///
 /// ```no_run
-/// use sysinfo::{ProcessExt, System, SystemExt};
+/// use sysinfo::{ProcessExt, System};
 ///
 /// let s = System::new_all();
 /// for (pid, process) in s.processes() {
diff --git a/src/debug.rs b/src/debug.rs
index e710147..e3a29c2 100644
--- a/src/debug.rs
+++ b/src/debug.rs
@@ -2,7 +2,7 @@
 
 use crate::{
     Component, ComponentExt, Components, Cpu, CpuExt, Disk, Disks, NetworkData, NetworkExt,
-    Networks, NetworksExt, Process, ProcessExt, System, SystemExt, User, UserExt, Users,
+    Networks, NetworksExt, Process, ProcessExt, System, User, UserExt, Users,
 };
 
 use std::fmt;
diff --git a/src/lib.rs b/src/lib.rs
index e4de7d3..708e43a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -54,13 +54,17 @@ cfg_if::cfg_if! {
 pub use crate::common::{
     get_current_pid, CpuRefreshKind, Disk, DiskKind, DiskUsage, Disks, Gid, Group, LoadAvg,
     MacAddr, Networks, NetworksIter, Pid, PidExt, ProcessRefreshKind, ProcessStatus, RefreshKind,
-    Signal, Uid, Users,
+    Signal, System, Uid, Users,
 };
-pub use crate::sys::{Component, Components, Cpu, NetworkData, Process, System, User};
-pub(crate) use crate::sys::{DiskInner, DisksInner};
+
+pub use crate::sys::{
+    Component, Components, Cpu, NetworkData, Process, User, IS_SUPPORTED,
+    MINIMUM_CPU_UPDATE_INTERVAL, SUPPORTED_SIGNALS,
+};
+pub(crate) use crate::sys::{DiskInner, DisksInner, SystemInner};
 pub use crate::traits::{
-    ComponentExt, ComponentsExt, CpuExt, GroupExt, NetworkExt, NetworksExt, ProcessExt, SystemExt,
-    UserExt, UsersExt,
+    ComponentExt, ComponentsExt, CpuExt, GroupExt, NetworkExt, NetworksExt, ProcessExt, UserExt,
+    UsersExt,
 };
 
 #[cfg(feature = "c-interface")]
@@ -90,7 +94,7 @@ mod utils;
 /// Returns `true` if the new value has been set.
 ///
 /// ```no_run
-/// use sysinfo::{System, SystemExt, set_open_files_limit};
+/// use sysinfo::{System, set_open_files_limit};
 ///
 /// // We call the function before any call to the processes update.
 /// if !set_open_files_limit(10) {
@@ -136,7 +140,7 @@ mod doctest {
     /// First we check that the "basic" code works:
     ///
     /// ```no_run
-    /// use sysinfo::{Process, System, SystemExt};
+    /// use sysinfo::{Process, System};
     ///
     /// let mut s = System::new_all();
     /// let p: &Process = s.processes().values().next().unwrap();
@@ -145,7 +149,7 @@ mod doctest {
     /// And now we check if it fails when we try to clone it:
     ///
     /// ```compile_fail
-    /// use sysinfo::{Process, System, SystemExt};
+    /// use sysinfo::{Process, System};
     ///
     /// let mut s = System::new_all();
     /// let p: &Process = s.processes().values().next().unwrap();
@@ -158,7 +162,7 @@ mod doctest {
     /// First we check that the "basic" code works:
     ///
     /// ```no_run
-    /// use sysinfo::{Process, System, SystemExt};
+    /// use sysinfo::{Process, System};
     ///
     /// let s = System::new();
     /// ```
@@ -166,7 +170,7 @@ mod doctest {
     /// And now we check if it fails when we try to clone it:
     ///
     /// ```compile_fail
-    /// use sysinfo::{Process, System, SystemExt};
+    /// use sysinfo::{Process, System};
     ///
     /// let s = System::new();
     /// let s = s.clone();
@@ -181,7 +185,19 @@ mod test {
     #[cfg(feature = "unknown-ci")]
     #[test]
     fn check_unknown_ci_feature() {
-        assert!(!System::IS_SUPPORTED);
+        assert!(!IS_SUPPORTED);
+    }
+
+    // If this test doesn't compile, it means the current OS doesn't implement them correctly.
+    #[test]
+    fn check_macro_types() {
+        fn check_is_supported(_: bool) {}
+        fn check_supported_signals(_: &'static [Signal]) {}
+        fn check_minimum_cpu_update_interval(_: std::time::Duration) {}
+
+        check_is_supported(IS_SUPPORTED);
+        check_supported_signals(SUPPORTED_SIGNALS);
+        check_minimum_cpu_update_interval(MINIMUM_CPU_UPDATE_INTERVAL);
     }
 
     #[test]
@@ -189,7 +205,7 @@ mod test {
         let mut s = System::new();
         s.refresh_all();
 
-        if System::IS_SUPPORTED {
+        if IS_SUPPORTED {
             // No process should have 0 as memory usage.
             #[cfg(not(feature = "apple-sandbox"))]
             assert!(!s.processes().iter().all(|(_, proc_)| proc_.memory() == 0));
@@ -199,6 +215,13 @@ mod test {
         }
     }
 
+    #[test]
+    fn check_system_implemented_traits() {
+        fn check<T: Sized + std::fmt::Debug + Default + Send + Sync>(_: T) {}
+
+        check(System::new());
+    }
+
     #[test]
     fn check_memory_usage() {
         let mut s = System::new();
@@ -212,7 +235,7 @@ mod test {
         assert_eq!(s.used_swap(), 0);
 
         s.refresh_memory();
-        if System::IS_SUPPORTED {
+        if IS_SUPPORTED {
             assert!(s.total_memory() > 0);
             assert!(s.used_memory() > 0);
             if s.total_swap() > 0 {
@@ -230,7 +253,7 @@ mod test {
     #[cfg(target_os = "linux")]
     #[test]
     fn check_processes_cpu_usage() {
-        if !System::IS_SUPPORTED {
+        if !IS_SUPPORTED {
             return;
         }
         let mut s = System::new();
@@ -243,7 +266,7 @@ mod test {
             .all(|(_, proc_)| proc_.cpu_usage() == 0.0));
 
         // Wait a bit to update CPU usage values
-        std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL);
+        std::thread::sleep(MINIMUM_CPU_UPDATE_INTERVAL);
         s.refresh_processes();
         assert!(s
             .processes()
@@ -258,14 +281,14 @@ mod test {
 
     #[test]
     fn check_cpu_usage() {
-        if !System::IS_SUPPORTED {
+        if !IS_SUPPORTED {
             return;
         }
         let mut s = System::new();
         for _ in 0..10 {
             s.refresh_cpu_usage();
             // Wait a bit to update CPU usage values
-            std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL);
+            std::thread::sleep(MINIMUM_CPU_UPDATE_INTERVAL);
             if s.cpus().iter().any(|c| c.cpu_usage() > 0.0) {
                 // All good!
                 return;
@@ -290,7 +313,7 @@ mod test {
         let user_list = users.users();
         assert!(user_list.len() >= MIN_USERS);
 
-        if System::IS_SUPPORTED {
+        if IS_SUPPORTED {
             #[cfg(not(target_os = "windows"))]
             {
                 let user = user_list
@@ -322,7 +345,7 @@ mod test {
     fn check_all_process_uids_resolvable() {
         // On linux, some user IDs don't have an associated user (no idea why though).
         // If `getent` doesn't find them, we can assume it's a dark secret from the linux land.
-        if System::IS_SUPPORTED && cfg!(not(target_os = "linux")) {
+        if IS_SUPPORTED && cfg!(not(target_os = "linux")) {
             let s = System::new_with_specifics(
                 RefreshKind::new().with_processes(ProcessRefreshKind::new().with_user()),
             );
@@ -348,7 +371,7 @@ mod test {
         let s = System::new();
 
         // We don't want to test on unsupported systems.
-        if System::IS_SUPPORTED {
+        if IS_SUPPORTED {
             assert!(!s.name().expect("Failed to get system name").is_empty());
 
             assert!(!s
@@ -370,7 +393,7 @@ mod test {
     #[test]
     fn check_host_name() {
         // We don't want to test on unsupported systems.
-        if System::IS_SUPPORTED {
+        if IS_SUPPORTED {
             let s = System::new();
             assert!(s.host_name().is_some());
         }
@@ -379,7 +402,7 @@ mod test {
     #[test]
     fn check_refresh_process_return_value() {
         // We don't want to test on unsupported systems.
-        if System::IS_SUPPORTED {
+        if IS_SUPPORTED {
             let _pid = get_current_pid().expect("Failed to get current PID");
 
             #[cfg(not(feature = "apple-sandbox"))]
@@ -396,9 +419,9 @@ mod test {
     #[test]
     fn ensure_is_supported_is_set_correctly() {
         if MIN_USERS > 0 {
-            assert!(System::IS_SUPPORTED);
+            assert!(IS_SUPPORTED);
         } else {
-            assert!(!System::IS_SUPPORTED);
+            assert!(!IS_SUPPORTED);
         }
     }
 
@@ -408,7 +431,7 @@ mod test {
 
         // This information isn't retrieved by default.
         assert!(s.cpus().is_empty());
-        if System::IS_SUPPORTED {
+        if IS_SUPPORTED {
             // The physical cores count is recomputed every time the function is called, so the
             // information must be relevant even with nothing initialized.
             let physical_cores_count = s
@@ -434,14 +457,14 @@ mod test {
 
     #[test]
     fn check_nb_supported_signals() {
-        if System::IS_SUPPORTED {
+        if IS_SUPPORTED {
             assert!(
-                !System::SUPPORTED_SIGNALS.is_empty(),
+                !SUPPORTED_SIGNALS.is_empty(),
                 "SUPPORTED_SIGNALS shoudn't be empty on supported systems!"
             );
         } else {
             assert!(
-                System::SUPPORTED_SIGNALS.is_empty(),
+                SUPPORTED_SIGNALS.is_empty(),
                 "SUPPORTED_SIGNALS should be empty on not support systems!"
             );
         }
@@ -450,7 +473,7 @@ mod test {
     // Ensure that the CPUs frequency isn't retrieved until we ask for it.
     #[test]
     fn check_cpu_frequency() {
-        if !System::IS_SUPPORTED {
+        if !IS_SUPPORTED {
             return;
         }
         let mut s = System::new();
@@ -475,7 +498,7 @@ mod test {
     // so this test ensures that it doesn't happen.
     #[test]
     fn check_refresh_process_update() {
-        if !System::IS_SUPPORTED {
+        if !IS_SUPPORTED {
             return;
         }
         let mut s = System::new_all();
@@ -493,7 +516,7 @@ mod test {
     // We ensure that the `Process` cmd information is retrieved as expected.
     #[test]
     fn check_cmd_line() {
-        if !System::IS_SUPPORTED {
+        if !IS_SUPPORTED {
             return;
         }
         let mut sys = System::new();
diff --git a/src/serde.rs b/src/serde.rs
index 3ef6b8a..481a04f 100644
--- a/src/serde.rs
+++ b/src/serde.rs
@@ -3,7 +3,7 @@
 use crate::common::PidExt;
 use crate::{
     ComponentExt, CpuExt, DiskKind, DiskUsage, GroupExt, MacAddr, NetworkExt, NetworksExt,
-    ProcessExt, ProcessStatus, Signal, SystemExt, UserExt,
+    ProcessExt, ProcessStatus, Signal, UserExt,
 };
 use serde::{ser::SerializeStruct, Serialize, Serializer};
 use std::ops::Deref;
@@ -93,15 +93,8 @@ impl serde::Serialize for crate::System {
     where
         S: serde::Serializer,
     {
-        // `23` corresponds to the number of fields.
-        let mut state = serializer.serialize_struct("System", 22)?;
-
-        state.serialize_field("IS_SUPPORTED", &<Self as SystemExt>::IS_SUPPORTED)?;
-        state.serialize_field("SUPPORTED_SIGNALS", <Self as SystemExt>::SUPPORTED_SIGNALS)?;
-        state.serialize_field(
-            "MINIMUM_CPU_UPDATE_INTERVAL",
-            &<Self as SystemExt>::MINIMUM_CPU_UPDATE_INTERVAL,
-        )?;
+        // `19` corresponds to the number of fields.
+        let mut state = serializer.serialize_struct("System", 19)?;
 
         state.serialize_field("global_cpu_info", &self.global_cpu_info())?;
         state.serialize_field("cpus", &self.cpus())?;
diff --git a/src/system.rs b/src/system.rs
index 1c4254e..5983b7f 100644
--- a/src/system.rs
+++ b/src/system.rs
@@ -5,14 +5,14 @@
 
 #[cfg(test)]
 mod tests {
-    use crate::{ProcessExt, System, SystemExt};
+    use crate::{ProcessExt, System};
 
     #[test]
     fn test_refresh_system() {
         let mut sys = System::new();
         sys.refresh_system();
         // We don't want to test on unsupported systems.
-        if System::IS_SUPPORTED {
+        if crate::IS_SUPPORTED {
             assert!(sys.total_memory() != 0);
             assert!(sys.free_memory() != 0);
         }
@@ -27,7 +27,7 @@ mod tests {
         // We don't want to test on unsupported systems.
 
         #[cfg(not(feature = "apple-sandbox"))]
-        if System::IS_SUPPORTED {
+        if crate::IS_SUPPORTED {
             assert!(
                 sys.refresh_process(crate::get_current_pid().expect("failed to get current pid")),
                 "process not listed",
@@ -46,7 +46,7 @@ mod tests {
         let current_pid = match crate::get_current_pid() {
             Ok(pid) => pid,
             _ => {
-                if !System::IS_SUPPORTED {
+                if !crate::IS_SUPPORTED {
                     return;
                 }
                 panic!("get_current_pid should work!");
@@ -56,7 +56,7 @@ mod tests {
             assert!(p.memory() > 0);
         } else {
             #[cfg(not(feature = "apple-sandbox"))]
-            assert!(!System::IS_SUPPORTED);
+            assert!(!crate::IS_SUPPORTED);
         }
     }
 
@@ -78,7 +78,7 @@ mod tests {
         let current_pid = match crate::get_current_pid() {
             Ok(pid) => pid,
             _ => {
-                if !System::IS_SUPPORTED {
+                if !crate::IS_SUPPORTED {
                     return;
                 }
                 panic!("get_current_pid should work!");
@@ -91,7 +91,7 @@ mod tests {
                      // doesn't implement the Sync trait.
         } else {
             #[cfg(not(feature = "apple-sandbox"))]
-            assert!(!System::IS_SUPPORTED);
+            assert!(!crate::IS_SUPPORTED);
         }
     }
 
@@ -108,7 +108,7 @@ mod tests {
     fn check_uptime() {
         let sys = System::new();
         let uptime = sys.uptime();
-        if System::IS_SUPPORTED {
+        if crate::IS_SUPPORTED {
             std::thread::sleep(std::time::Duration::from_millis(1000));
             let new_uptime = sys.uptime();
             assert!(uptime < new_uptime);
@@ -120,12 +120,12 @@ mod tests {
     #[test]
     #[ignore] // This test MUST be run on its own to prevent wrong CPU usage measurements.
     fn test_consecutive_cpu_usage_update() {
-        use crate::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt};
+        use crate::{PidExt, ProcessExt, ProcessRefreshKind, System};
         use std::sync::atomic::{AtomicBool, Ordering};
         use std::sync::Arc;
         use std::time::Duration;
 
-        if !System::IS_SUPPORTED {
+        if !crate::IS_SUPPORTED {
             return;
         }
 
@@ -158,9 +158,7 @@ mod tests {
         assert_eq!(pids.len(), 3);
 
         for it in 0..3 {
-            std::thread::sleep(
-                crate::System::MINIMUM_CPU_UPDATE_INTERVAL + Duration::from_millis(1),
-            );
+            std::thread::sleep(crate::MINIMUM_CPU_UPDATE_INTERVAL + Duration::from_millis(1));
             for pid in &pids {
                 sys.refresh_process_specifics(*pid, ProcessRefreshKind::new().with_cpu());
             }
diff --git a/src/traits.rs b/src/traits.rs
index f00696c..1d139b7 100644
--- a/src/traits.rs
+++ b/src/traits.rs
@@ -2,22 +2,17 @@
 
 use crate::{
     common::{Gid, MacAddr, Uid},
-    sys::{Component, Cpu, Process},
-};
-use crate::{
-    CpuRefreshKind, DiskUsage, Group, LoadAvg, NetworksIter, Pid, ProcessRefreshKind,
-    ProcessStatus, RefreshKind, Signal, User,
+    sys::Component,
 };
+use crate::{DiskUsage, Group, NetworksIter, Pid, ProcessStatus, Signal, User};
 
-use std::collections::HashMap;
 use std::fmt::Debug;
 use std::path::Path;
-use std::time::Duration;
 
 /// Contains all the methods of the [`Process`][crate::Process] struct.
 ///
 /// ```no_run
-/// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+/// use sysinfo::{Pid, ProcessExt, System};
 ///
 /// let s = System::new_all();
 /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -31,10 +26,10 @@ pub trait ProcessExt: Debug {
     /// If you want to send another signal, take a look at [`ProcessExt::kill_with`].
     ///
     /// To get the list of the supported signals on this system, use
-    /// [`SystemExt::SUPPORTED_SIGNALS`].
+    /// [`SUPPORTED_SIGNALS`][crate::SUPPORTED_SIGNALS].
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -52,10 +47,10 @@ pub trait ProcessExt: Debug {
     /// If you just want to kill the process, use [`ProcessExt::kill`] directly.
     ///
     /// To get the list of the supported signals on this system, use
-    /// [`SystemExt::SUPPORTED_SIGNALS`].
+    /// [`SUPPORTED_SIGNALS`][crate::SUPPORTED_SIGNALS].
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, Signal, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, Signal, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -78,7 +73,7 @@ pub trait ProcessExt: Debug {
     /// cases it's better to use [`ProcessExt::exe`] instead (which can be empty sometimes!).
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -90,7 +85,7 @@ pub trait ProcessExt: Debug {
     /// Returns the command line.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -102,7 +97,7 @@ pub trait ProcessExt: Debug {
     /// Returns the path to the process.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -126,7 +121,7 @@ pub trait ProcessExt: Debug {
     /// Returns the PID of the process.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -138,7 +133,7 @@ pub trait ProcessExt: Debug {
     /// Returns the environment variables of the process.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -150,7 +145,7 @@ pub trait ProcessExt: Debug {
     /// Returns the current working directory.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -162,7 +157,7 @@ pub trait ProcessExt: Debug {
     /// Returns the path of the root directory.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -174,7 +169,7 @@ pub trait ProcessExt: Debug {
     /// Returns the memory usage (in bytes).
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -186,7 +181,7 @@ pub trait ProcessExt: Debug {
     /// Returns the virtual memory usage (in bytes).
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -198,7 +193,7 @@ pub trait ProcessExt: Debug {
     /// Returns the parent PID.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -210,7 +205,7 @@ pub trait ProcessExt: Debug {
     /// Returns the status of the process.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -222,7 +217,7 @@ pub trait ProcessExt: Debug {
     /// Returns the time where the process was started (in seconds) from epoch.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -234,7 +229,7 @@ pub trait ProcessExt: Debug {
     /// Returns for how much time the process has been running (in seconds).
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -254,10 +249,10 @@ pub trait ProcessExt: Debug {
     ///
     /// ⚠️ If you want accurate CPU usage number, better leave a bit of time
     /// between two calls of this method (take a look at
-    /// [`SystemExt::MINIMUM_CPU_UPDATE_INTERVAL`] for more information).
+    /// [`MINIMUM_CPU_UPDATE_INTERVAL`][crate::MINIMUM_CPU_UPDATE_INTERVAL] for more information).
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -271,7 +266,7 @@ pub trait ProcessExt: Debug {
     /// ⚠️ On Windows and FreeBSD, this method actually returns **ALL** I/O read and written bytes.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let s = System::new_all();
     /// if let Some(process) = s.process(Pid::from(1337)) {
@@ -293,7 +288,7 @@ pub trait ProcessExt: Debug {
     /// [`UsersExt::get_user_by_id`].
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let mut s = System::new_all();
     ///
@@ -313,7 +308,7 @@ pub trait ProcessExt: Debug {
     /// ⚠️ It always returns `None` on Windows.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let mut s = System::new_all();
     ///
@@ -328,7 +323,7 @@ pub trait ProcessExt: Debug {
     /// ⚠️ It always returns `None` on Windows.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let mut s = System::new_all();
     ///
@@ -346,7 +341,7 @@ pub trait ProcessExt: Debug {
     /// ⚠️ It always returns `None` on Windows.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let mut s = System::new_all();
     ///
@@ -359,7 +354,7 @@ pub trait ProcessExt: Debug {
     /// Wait for process termination.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let mut s = System::new_all();
     ///
@@ -376,7 +371,7 @@ pub trait ProcessExt: Debug {
     /// ⚠️ This information is computed every time this method is called.
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
+    /// use sysinfo::{Pid, ProcessExt, System};
     ///
     /// let mut s = System::new_all();
     ///
@@ -390,14 +385,14 @@ pub trait ProcessExt: Debug {
 /// Contains all the methods of the [`Cpu`][crate::Cpu] struct.
 ///
 /// ```no_run
-/// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
+/// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind};
 ///
 /// let mut s = System::new_with_specifics(
 ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
 /// );
 ///
 /// // Wait a bit because CPU usage is based on diff.
-/// std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL);
+/// std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
 /// // Refresh CPUs again.
 /// s.refresh_cpu();
 ///
@@ -412,14 +407,14 @@ pub trait CpuExt: Debug {
     /// how CPU usage is computed) at first if you want to have a non-zero value.
     ///
     /// ```no_run
-    /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
+    /// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind};
     ///
     /// let mut s = System::new_with_specifics(
     ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
     /// );
     ///
     /// // Wait a bit because CPU usage is based on diff.
-    /// std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL);
+    /// std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
     /// // Refresh CPUs again.
     /// s.refresh_cpu();
     ///
@@ -432,7 +427,7 @@ pub trait CpuExt: Debug {
     /// Returns this CPU's name.
     ///
     /// ```no_run
-    /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
+    /// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind};
     ///
     /// let s = System::new_with_specifics(
     ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
@@ -446,7 +441,7 @@ pub trait CpuExt: Debug {
     /// Returns the CPU's vendor id.
     ///
     /// ```no_run
-    /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
+    /// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind};
     ///
     /// let s = System::new_with_specifics(
     ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
@@ -460,7 +455,7 @@ pub trait CpuExt: Debug {
     /// Returns the CPU's brand.
     ///
     /// ```no_run
-    /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
+    /// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind};
     ///
     /// let s = System::new_with_specifics(
     ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
@@ -474,7 +469,7 @@ pub trait CpuExt: Debug {
     /// Returns the CPU's frequency.
     ///
     /// ```no_run
-    /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
+    /// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind};
     ///
     /// let s = System::new_with_specifics(
     ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
@@ -486,627 +481,6 @@ pub trait CpuExt: Debug {
     fn frequency(&self) -> u64;
 }
 
-/// Contains all the methods of the [`System`][crate::System] type.
-///
-/// ```
-/// use sysinfo::{System, SystemExt};
-///
-/// if System::IS_SUPPORTED {
-///     println!("System: {:?}", System::new_all());
-/// } else {
-///     println!("This OS isn't supported (yet?).");
-/// }
-/// ```
-pub trait SystemExt: Sized + Debug + Default + Send + Sync {
-    /// Returns `true` if this OS is supported. Please refer to the
-    /// [crate-level documentation](index.html) to get the list of supported OSes.
-    ///
-    /// ```
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// if System::IS_SUPPORTED {
-    ///     println!("This OS is supported!");
-    /// } else {
-    ///     println!("This OS isn't supported (yet?).");
-    /// }
-    /// ```
-    const IS_SUPPORTED: bool;
-
-    /// Returns the list of the supported signals on this system (used by
-    /// [`ProcessExt::kill_with`]).
-    ///
-    /// ```
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// println!("supported signals: {:?}", System::SUPPORTED_SIGNALS);
-    /// ```
-    const SUPPORTED_SIGNALS: &'static [Signal];
-
-    /// This is the minimum interval time used internally by `sysinfo` to refresh the CPU time.
-    ///
-    /// ⚠️ This value differs from one OS to another.
-    ///
-    /// Why is this constant even needed?
-    ///
-    /// If refreshed too often, the CPU usage of processes will be `0` whereas on Linux it'll
-    /// always be the maximum value (`number of CPUs * 100`).
-    const MINIMUM_CPU_UPDATE_INTERVAL: Duration;
-
-    /// Creates a new [`System`] instance with nothing loaded.
-    ///
-    /// Use the [`refresh_all`] method to update its internal information (or any of the `refresh_`
-    /// method).
-    ///
-    /// [`System`]: crate::System
-    /// [`refresh_all`]: #method.refresh_all
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new();
-    /// ```
-    fn new() -> Self {
-        Self::new_with_specifics(RefreshKind::new())
-    }
-
-    /// Creates a new [`System`] instance with everything loaded.
-    ///
-    /// It is an equivalent of [`SystemExt::new_with_specifics`]`(`[`RefreshKind::everything`]`())`.
-    ///
-    /// [`System`]: crate::System
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// ```
-    fn new_all() -> Self {
-        Self::new_with_specifics(RefreshKind::everything())
-    }
-
-    /// Creates a new [`System`] instance and refresh the data corresponding to the
-    /// given [`RefreshKind`].
-    ///
-    /// [`System`]: crate::System
-    ///
-    /// ```
-    /// use sysinfo::{ProcessRefreshKind, RefreshKind, System, SystemExt};
-    ///
-    /// // We want to only refresh processes.
-    /// let mut system = System::new_with_specifics(
-    ///      RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
-    /// );
-    ///
-    /// # if System::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") {
-    /// assert!(!system.processes().is_empty());
-    /// # }
-    /// ```
-    fn new_with_specifics(refreshes: RefreshKind) -> Self;
-
-    /// Refreshes according to the given [`RefreshKind`]. It calls the corresponding
-    /// "refresh_" methods.
-    ///
-    /// ```
-    /// use sysinfo::{ProcessRefreshKind, RefreshKind, System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    ///
-    /// // Let's just update processes:
-    /// s.refresh_specifics(
-    ///     RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
-    /// );
-    /// ```
-    fn refresh_specifics(&mut self, refreshes: RefreshKind) {
-        if refreshes.memory() {
-            self.refresh_memory();
-        }
-        if let Some(kind) = refreshes.cpu() {
-            self.refresh_cpu_specifics(kind);
-        }
-        if let Some(kind) = refreshes.processes() {
-            self.refresh_processes_specifics(kind);
-        }
-    }
-
-    /// Refreshes all system and processes information.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_all();
-    /// ```
-    fn refresh_all(&mut self) {
-        self.refresh_system();
-        self.refresh_processes();
-    }
-
-    /// Refreshes system information (RAM, swap, CPU usage and components' temperature).
-    ///
-    /// If you want some more specific refreshes, you might be interested into looking at
-    /// [`refresh_memory`] and [`refresh_cpu`].
-    ///
-    /// [`refresh_memory`]: SystemExt::refresh_memory
-    /// [`refresh_cpu`]: SystemExt::refresh_memory
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_system();
-    /// ```
-    fn refresh_system(&mut self) {
-        self.refresh_memory();
-        self.refresh_cpu_usage();
-    }
-
-    /// Refreshes RAM and SWAP usage.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_memory();
-    /// ```
-    fn refresh_memory(&mut self);
-
-    /// Refreshes CPUs usage.
-    ///
-    /// ⚠️ Please note that the result will very likely be inaccurate at the first call.
-    /// You need to call this method at least twice (with a bit of time between each call, like
-    /// 200 ms, take a look at [`SystemExt::MINIMUM_CPU_UPDATE_INTERVAL`] for more information)
-    /// to get accurate value as it uses previous results to compute the next value.
-    ///
-    /// Calling this method is the same as calling
-    /// `refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage())`.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_cpu_usage();
-    /// ```
-    fn refresh_cpu_usage(&mut self) {
-        self.refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage())
-    }
-
-    /// Refreshes CPUs frequency information.
-    ///
-    /// Calling this method is the same as calling
-    /// `refresh_cpu_specifics(CpuRefreshKind::new().with_frequency())`.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_cpu_frequency();
-    /// ```
-    fn refresh_cpu_frequency(&mut self) {
-        self.refresh_cpu_specifics(CpuRefreshKind::new().with_frequency())
-    }
-
-    /// Refreshes all information related to CPUs information.
-    ///
-    /// ⚠️ Please note that the result will very likely be inaccurate at the first call.
-    /// You need to call this method at least twice (with a bit of time between each call, like
-    /// 200 ms, take a look at [`SystemExt::MINIMUM_CPU_UPDATE_INTERVAL`] for more information)
-    /// to get accurate value as it uses previous results to compute the next value.
-    ///
-    /// Calling this method is the same as calling
-    /// `refresh_cpu_specifics(CpuRefreshKind::everything())`.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_cpu();
-    /// ```
-    fn refresh_cpu(&mut self) {
-        self.refresh_cpu_specifics(CpuRefreshKind::everything())
-    }
-
-    /// Refreshes CPUs specific information.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt, CpuRefreshKind};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_cpu_specifics(CpuRefreshKind::everything());
-    /// ```
-    fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind);
-
-    /// Gets all processes and updates their information.
-    ///
-    /// It does the same as `system.refresh_processes_specifics(ProcessRefreshKind::everything())`.
-    ///
-    /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour
-    /// by using [`set_open_files_limit`][crate::set_open_files_limit].
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_processes();
-    /// ```
-    fn refresh_processes(&mut self) {
-        self.refresh_processes_specifics(ProcessRefreshKind::everything());
-    }
-
-    /// Gets all processes and updates the specified information.
-    ///
-    /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour
-    /// by using [`set_open_files_limit`][crate::set_open_files_limit].
-    ///
-    /// ```no_run
-    /// use sysinfo::{ProcessRefreshKind, System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_processes_specifics(ProcessRefreshKind::new());
-    /// ```
-    fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind);
-
-    /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't
-    /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it
-    /// isn't listed yet, it'll be added.
-    ///
-    /// It is the same as calling
-    /// `sys.refresh_process_specifics(pid, ProcessRefreshKind::everything())`.
-    ///
-    /// ```no_run
-    /// use sysinfo::{Pid, System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_process(Pid::from(1337));
-    /// ```
-    fn refresh_process(&mut self, pid: Pid) -> bool {
-        self.refresh_process_specifics(pid, ProcessRefreshKind::everything())
-    }
-
-    /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't
-    /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it
-    /// isn't listed yet, it'll be added.
-    ///
-    /// ```no_run
-    /// use sysinfo::{Pid, ProcessRefreshKind, System, SystemExt};
-    ///
-    /// let mut s = System::new_all();
-    /// s.refresh_process_specifics(Pid::from(1337), ProcessRefreshKind::new());
-    /// ```
-    fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool;
-
-    /// Returns the process list.
-    ///
-    /// ```no_run
-    /// use sysinfo::{ProcessExt, System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// for (pid, process) in s.processes() {
-    ///     println!("{} {}", pid, process.name());
-    /// }
-    /// ```
-    fn processes(&self) -> &HashMap<Pid, Process>;
-
-    /// Returns the process corresponding to the given `pid` or `None` if no such process exists.
-    ///
-    /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// if let Some(process) = s.process(Pid::from(1337)) {
-    ///     println!("{}", process.name());
-    /// }
-    /// ```
-    fn process(&self, pid: Pid) -> Option<&Process>;
-
-    /// Returns an iterator of process containing the given `name`.
-    ///
-    /// If you want only the processes with exactly the given `name`, take a look at
-    /// [`SystemExt::processes_by_exact_name`].
-    ///
-    /// **⚠️ Important ⚠️**
-    ///
-    /// On **Linux**, there are two things to know about processes' name:
-    ///  1. It is limited to 15 characters.
-    ///  2. It is not always the exe name.
-    ///
-    /// ```no_run
-    /// use sysinfo::{ProcessExt, System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// for process in s.processes_by_name("htop") {
-    ///     println!("{} {}", process.pid(), process.name());
-    /// }
-    /// ```
-    // FIXME: replace the returned type with `impl Iterator<Item = &Process>` when it's supported!
-    fn processes_by_name<'a: 'b, 'b>(
-        &'a self,
-        name: &'b str,
-    ) -> Box<dyn Iterator<Item = &'a Process> + 'b> {
-        Box::new(
-            self.processes()
-                .values()
-                .filter(move |val: &&Process| val.name().contains(name)),
-        )
-    }
-
-    /// Returns an iterator of processes with exactly the given `name`.
-    ///
-    /// If you instead want the processes containing `name`, take a look at
-    /// [`SystemExt::processes_by_name`].
-    ///
-    /// **⚠️ Important ⚠️**
-    ///
-    /// On **Linux**, there are two things to know about processes' name:
-    ///  1. It is limited to 15 characters.
-    ///  2. It is not always the exe name.
-    ///
-    /// ```no_run
-    /// use sysinfo::{ProcessExt, System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// for process in s.processes_by_exact_name("htop") {
-    ///     println!("{} {}", process.pid(), process.name());
-    /// }
-    /// ```
-    // FIXME: replace the returned type with `impl Iterator<Item = &Process>` when it's supported!
-    fn processes_by_exact_name<'a: 'b, 'b>(
-        &'a self,
-        name: &'b str,
-    ) -> Box<dyn Iterator<Item = &'a Process> + 'b> {
-        Box::new(
-            self.processes()
-                .values()
-                .filter(move |val: &&Process| val.name() == name),
-        )
-    }
-
-    /// Returns "global" CPUs information (aka the addition of all the CPUs).
-    ///
-    /// To have up-to-date information, you need to call [`SystemExt::refresh_cpu`] or
-    /// [`SystemExt::refresh_specifics`] with `cpu` enabled.
-    ///
-    /// **⚠️ Important ⚠️**
-    ///
-    /// Information like [`CpuExt::brand`], [`CpuExt::vendor_id`] or [`CpuExt::frequency`]
-    /// are not set on the "global" CPU.
-    ///
-    /// ```no_run
-    /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System, SystemExt};
-    ///
-    /// let s = System::new_with_specifics(
-    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
-    /// );
-    /// println!("{}%", s.global_cpu_info().cpu_usage());
-    /// ```
-    fn global_cpu_info(&self) -> &Cpu;
-
-    /// Returns the list of the CPUs.
-    ///
-    /// By default, the list of CPUs is empty until you call [`SystemExt::refresh_cpu`] or
-    /// [`SystemExt::refresh_specifics`] with `cpu` enabled.
-    ///
-    /// ```no_run
-    /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System, SystemExt};
-    ///
-    /// let s = System::new_with_specifics(
-    ///     RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
-    /// );
-    /// for cpu in s.cpus() {
-    ///     println!("{}%", cpu.cpu_usage());
-    /// }
-    /// ```
-    fn cpus(&self) -> &[Cpu];
-
-    /// Returns the number of physical cores on the CPU or `None` if it couldn't get it.
-    ///
-    /// In case there are multiple CPUs, it will combine the physical core count of all the CPUs.
-    ///
-    /// **Important**: this information is computed every time this function is called.
-    ///
-    /// ```no_run
-    /// use sysinfo::{CpuExt, System, SystemExt};
-    ///
-    /// let s = System::new();
-    /// println!("{:?}", s.physical_core_count());
-    /// ```
-    fn physical_core_count(&self) -> Option<usize>;
-
-    /// Returns the RAM size in bytes.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// println!("{} bytes", s.total_memory());
-    /// ```
-    fn total_memory(&self) -> u64;
-
-    /// Returns the amount of free RAM in bytes.
-    ///
-    /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to
-    /// memory that is available for (re)use.
-    ///
-    /// Side note: Windows doesn't report "free" memory so this method returns the same value
-    /// as [`get_available_memory`](#tymethod.available_memory).
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// println!("{} bytes", s.free_memory());
-    /// ```
-    fn free_memory(&self) -> u64;
-
-    /// Returns the amount of available RAM in bytes.
-    ///
-    /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to
-    /// memory that is available for (re)use.
-    ///
-    /// ⚠️ Windows and FreeBSD don't report "available" memory so [`SystemExt::free_memory`]
-    /// returns the same value as this method.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// println!("{} bytes", s.available_memory());
-    /// ```
-    fn available_memory(&self) -> u64;
-
-    /// Returns the amount of used RAM in bytes.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// println!("{} bytes", s.used_memory());
-    /// ```
-    fn used_memory(&self) -> u64;
-
-    /// Returns the SWAP size in bytes.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// println!("{} bytes", s.total_swap());
-    /// ```
-    fn total_swap(&self) -> u64;
-
-    /// Returns the amount of free SWAP in bytes.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// println!("{} bytes", s.free_swap());
-    /// ```
-    fn free_swap(&self) -> u64;
-
-    /// Returns the amount of used SWAP in bytes.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// println!("{} bytes", s.used_swap());
-    /// ```
-    fn used_swap(&self) -> u64;
-
-    /// Returns system uptime (in seconds).
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// println!("System running since {} seconds", s.uptime());
-    /// ```
-    fn uptime(&self) -> u64;
-
-    /// Returns the time (in seconds) when the system booted since UNIX epoch.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new();
-    /// println!("System booted at {} seconds", s.boot_time());
-    /// ```
-    fn boot_time(&self) -> u64;
-
-    /// Returns the system load average value.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new_all();
-    /// let load_avg = s.load_average();
-    /// println!(
-    ///     "one minute: {}%, five minutes: {}%, fifteen minutes: {}%",
-    ///     load_avg.one,
-    ///     load_avg.five,
-    ///     load_avg.fifteen,
-    /// );
-    /// ```
-    fn load_average(&self) -> LoadAvg;
-
-    /// Returns the system name.
-    ///
-    /// **Important**: this information is computed every time this function is called.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new();
-    /// println!("OS: {:?}", s.name());
-    /// ```
-    fn name(&self) -> Option<String>;
-
-    /// Returns the system's kernel version.
-    ///
-    /// **Important**: this information is computed every time this function is called.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new();
-    /// println!("kernel version: {:?}", s.kernel_version());
-    /// ```
-    fn kernel_version(&self) -> Option<String>;
-
-    /// 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, SystemExt};
-    ///
-    /// let s = System::new();
-    /// println!("OS version: {:?}", s.os_version());
-    /// ```
-    fn os_version(&self) -> Option<String>;
-
-    /// Returns the system long os version (e.g "MacOS 11.2 BigSur").
-    ///
-    /// **Important**: this information is computed every time this function is called.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new();
-    /// println!("Long OS Version: {:?}", s.long_os_version());
-    /// ```
-    fn long_os_version(&self) -> Option<String>;
-
-    /// Returns the distribution id as defined by os-release,
-    /// or [`std::env::consts::OS`].
-    ///
-    /// See also
-    /// - <https://www.freedesktop.org/software/systemd/man/os-release.html#ID=>
-    /// - <https://doc.rust-lang.org/std/env/consts/constant.OS.html>
-    ///
-    /// **Important**: this information is computed every time this function is called.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new();
-    /// println!("Distribution ID: {:?}", s.distribution_id());
-    /// ```
-    fn distribution_id(&self) -> String;
-
-    /// Returns the system hostname based off DNS
-    ///
-    /// **Important**: this information is computed every time this function is called.
-    ///
-    /// ```no_run
-    /// use sysinfo::{System, SystemExt};
-    ///
-    /// let s = System::new();
-    /// println!("Hostname: {:?}", s.host_name());
-    /// ```
-    fn host_name(&self) -> Option<String>;
-}
-
 /// Getting volume of received and transmitted data.
 ///
 /// ```no_run
@@ -1317,7 +691,7 @@ pub trait NetworksExt: Debug {
     /// Returns an iterator over the network interfaces.
     ///
     /// ```no_run
-    /// use sysinfo::{Networks, NetworkExt, NetworksExt, System, SystemExt};
+    /// use sysinfo::{Networks, NetworkExt, NetworksExt, System};
     ///
     /// let mut networks = Networks::new();
     /// networks.refresh_list();
@@ -1334,7 +708,7 @@ pub trait NetworksExt: Debug {
     /// Refreshes the network interfaces list.
     ///
     /// ```no_run
-    /// use sysinfo::{Networks, NetworksExt, System, SystemExt};
+    /// use sysinfo::{Networks, NetworksExt, System};
     ///
     /// let mut networks = Networks::new();
     /// networks.refresh_list();
@@ -1351,7 +725,7 @@ pub trait NetworksExt: Debug {
     /// as the network list will be empty.
     ///
     /// ```no_run
-    /// use sysinfo::{Networks, NetworksExt, System, SystemExt};
+    /// use sysinfo::{Networks, NetworksExt, System};
     ///
     /// let mut networks = Networks::new();
     /// // Refreshes the network interfaces list.
@@ -1761,7 +1135,7 @@ pub trait UsersExt: Debug {
     /// Full example:
     ///
     /// ```no_run
-    /// use sysinfo::{Pid, ProcessExt, System, SystemExt, Users, UsersExt};
+    /// use sysinfo::{Pid, ProcessExt, System, Users, UsersExt};
     ///
     /// let mut s = System::new_all();
     /// let mut users = Users::new();
diff --git a/src/unix/apple/macos/process.rs b/src/unix/apple/macos/process.rs
index e6fa4f5..259af97 100644
--- a/src/unix/apple/macos/process.rs
+++ b/src/unix/apple/macos/process.rs
@@ -114,7 +114,7 @@ impl Process {
 
 impl ProcessExt for Process {
     fn kill_with(&self, signal: Signal) -> Option<bool> {
-        let c_signal = crate::sys::system::convert_signal(signal)?;
+        let c_signal = crate::sys::convert_signal(signal)?;
         unsafe { Some(kill(self.pid.0, c_signal) == 0) }
     }
 
diff --git a/src/unix/apple/macos/system.rs b/src/unix/apple/macos/system.rs
index 6c5a790..5a44ab6 100644
--- a/src/unix/apple/macos/system.rs
+++ b/src/unix/apple/macos/system.rs
@@ -1,7 +1,5 @@
 // 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};
 
@@ -127,8 +125,7 @@ impl SystemTimeInfo {
             // 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;
+            let smallest = crate::MINIMUM_CPU_UPDATE_INTERVAL.as_secs_f64() * 1_000_000_000.0;
             if base_interval < smallest {
                 smallest
             } else {
@@ -146,7 +143,7 @@ mod test {
     /// 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") {
+        if !crate::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
             return;
         }
 
@@ -154,12 +151,12 @@ mod test {
         let mut info = SystemTimeInfo::new(port).unwrap();
         info.get_time_interval(port);
 
-        std::thread::sleep(crate::System::MINIMUM_CPU_UPDATE_INTERVAL.saturating_mul(5));
+        std::thread::sleep(crate::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
+            crate::MINIMUM_CPU_UPDATE_INTERVAL.as_secs_f64() * 1_000_000_000.0
         );
     }
 }
diff --git a/src/unix/apple/mod.rs b/src/unix/apple/mod.rs
index 9263006..f908782 100644
--- a/src/unix/apple/mod.rs
+++ b/src/unix/apple/mod.rs
@@ -29,7 +29,60 @@ pub use self::cpu::Cpu;
 pub(crate) use self::disk::DiskInner;
 pub use self::network::NetworkData;
 pub use self::process::Process;
-pub use self::system::System;
+pub(crate) use self::system::SystemInner;
 pub(crate) use crate::unix::users::get_users;
 pub use crate::unix::users::User;
 pub(crate) use crate::unix::DisksInner;
+
+use std::time::Duration;
+
+#[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
+declare_signals! {
+    libc::c_int,
+    Signal::Hangup => libc::SIGHUP,
+    Signal::Interrupt => libc::SIGINT,
+    Signal::Quit => libc::SIGQUIT,
+    Signal::Illegal => libc::SIGILL,
+    Signal::Trap => libc::SIGTRAP,
+    Signal::Abort => libc::SIGABRT,
+    Signal::IOT => libc::SIGIOT,
+    Signal::Bus => libc::SIGBUS,
+    Signal::FloatingPointException => libc::SIGFPE,
+    Signal::Kill => libc::SIGKILL,
+    Signal::User1 => libc::SIGUSR1,
+    Signal::Segv => libc::SIGSEGV,
+    Signal::User2 => libc::SIGUSR2,
+    Signal::Pipe => libc::SIGPIPE,
+    Signal::Alarm => libc::SIGALRM,
+    Signal::Term => libc::SIGTERM,
+    Signal::Child => libc::SIGCHLD,
+    Signal::Continue => libc::SIGCONT,
+    Signal::Stop => libc::SIGSTOP,
+    Signal::TSTP => libc::SIGTSTP,
+    Signal::TTIN => libc::SIGTTIN,
+    Signal::TTOU => libc::SIGTTOU,
+    Signal::Urgent => libc::SIGURG,
+    Signal::XCPU => libc::SIGXCPU,
+    Signal::XFSZ => libc::SIGXFSZ,
+    Signal::VirtualAlarm => libc::SIGVTALRM,
+    Signal::Profiling => libc::SIGPROF,
+    Signal::Winch => libc::SIGWINCH,
+    Signal::IO => libc::SIGIO,
+    // SIGPOLL doesn't exist on apple targets but since it's an equivalent of SIGIO on unix,
+    // we simply use the SIGIO constant.
+    Signal::Poll => libc::SIGIO,
+    Signal::Sys => libc::SIGSYS,
+    _ => None,
+}
+#[cfg(any(target_os = "ios", feature = "apple-sandbox"))]
+declare_signals! {
+    libc::c_int,
+    _ => None,
+}
+
+#[doc = include_str!("../../../md_doc/is_supported.md")]
+pub const IS_SUPPORTED: bool = true;
+#[doc = include_str!("../../../md_doc/supported_signals.md")]
+pub const SUPPORTED_SIGNALS: &[crate::Signal] = supported_signals();
+#[doc = include_str!("../../../md_doc/minimum_cpu_update_interval.md")]
+pub const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200);
diff --git a/src/unix/apple/system.rs b/src/unix/apple/system.rs
index 455a6cb..e775424 100644
--- a/src/unix/apple/system.rs
+++ b/src/unix/apple/system.rs
@@ -4,7 +4,7 @@ use crate::sys::cpu::*;
 use crate::sys::process::*;
 use crate::sys::utils::{get_sys_value, get_sys_value_by_name};
 
-use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt};
+use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind};
 
 #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
 use crate::ProcessExt;
@@ -12,7 +12,6 @@ use crate::ProcessExt;
 use std::cell::UnsafeCell;
 use std::collections::HashMap;
 use std::mem;
-use std::time::Duration;
 #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
 use std::time::SystemTime;
 
@@ -24,52 +23,7 @@ use libc::{
     _SC_PAGESIZE,
 };
 
-#[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
-declare_signals! {
-    c_int,
-    Signal::Hangup => libc::SIGHUP,
-    Signal::Interrupt => libc::SIGINT,
-    Signal::Quit => libc::SIGQUIT,
-    Signal::Illegal => libc::SIGILL,
-    Signal::Trap => libc::SIGTRAP,
-    Signal::Abort => libc::SIGABRT,
-    Signal::IOT => libc::SIGIOT,
-    Signal::Bus => libc::SIGBUS,
-    Signal::FloatingPointException => libc::SIGFPE,
-    Signal::Kill => libc::SIGKILL,
-    Signal::User1 => libc::SIGUSR1,
-    Signal::Segv => libc::SIGSEGV,
-    Signal::User2 => libc::SIGUSR2,
-    Signal::Pipe => libc::SIGPIPE,
-    Signal::Alarm => libc::SIGALRM,
-    Signal::Term => libc::SIGTERM,
-    Signal::Child => libc::SIGCHLD,
-    Signal::Continue => libc::SIGCONT,
-    Signal::Stop => libc::SIGSTOP,
-    Signal::TSTP => libc::SIGTSTP,
-    Signal::TTIN => libc::SIGTTIN,
-    Signal::TTOU => libc::SIGTTOU,
-    Signal::Urgent => libc::SIGURG,
-    Signal::XCPU => libc::SIGXCPU,
-    Signal::XFSZ => libc::SIGXFSZ,
-    Signal::VirtualAlarm => libc::SIGVTALRM,
-    Signal::Profiling => libc::SIGPROF,
-    Signal::Winch => libc::SIGWINCH,
-    Signal::IO => libc::SIGIO,
-    // SIGPOLL doesn't exist on apple targets but since it's an equivalent of SIGIO on unix,
-    // we simply use the SIGIO constant.
-    Signal::Poll => libc::SIGIO,
-    Signal::Sys => libc::SIGSYS,
-    _ => None,
-}
-#[cfg(any(target_os = "ios", feature = "apple-sandbox"))]
-declare_signals! {
-    c_int,
-    _ => None,
-}
-
-#[doc = include_str!("../../../md_doc/system.md")]
-pub struct System {
+pub(crate) struct SystemInner {
     process_list: HashMap<Pid, Process>,
     mem_total: u64,
     mem_free: u64,
@@ -123,16 +77,12 @@ fn get_now() -> u64 {
         .unwrap_or(0)
 }
 
-impl SystemExt for System {
-    const IS_SUPPORTED: bool = true;
-    const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals();
-    const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200);
-
-    fn new_with_specifics(refreshes: RefreshKind) -> System {
+impl SystemInner {
+    pub(crate) fn new() -> Self {
         unsafe {
             let port = libc::mach_host_self();
 
-            let mut s = System {
+            Self {
                 process_list: HashMap::with_capacity(200),
                 mem_total: 0,
                 mem_free: 0,
@@ -146,13 +96,11 @@ impl SystemExt for System {
                 #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
                 clock_info: crate::sys::macos::system::SystemTimeInfo::new(port),
                 cpus: CpusWrapper::new(),
-            };
-            s.refresh_specifics(refreshes);
-            s
+            }
         }
     }
 
-    fn refresh_memory(&mut self) {
+    pub(crate) fn refresh_memory(&mut self) {
         let mut mib = [0, 0];
 
         unsafe {
@@ -213,15 +161,15 @@ impl SystemExt for System {
         }
     }
 
-    fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) {
+    pub(crate) fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) {
         self.cpus.refresh(refresh_kind, self.port);
     }
 
     #[cfg(any(target_os = "ios", feature = "apple-sandbox"))]
-    fn refresh_processes_specifics(&mut self, _refresh_kind: ProcessRefreshKind) {}
+    pub(crate) fn refresh_processes_specifics(&mut self, _refresh_kind: ProcessRefreshKind) {}
 
     #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
-    fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) {
+    pub(crate) fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) {
         use crate::utils::into_iter;
 
         unsafe {
@@ -267,12 +215,20 @@ impl SystemExt for System {
     }
 
     #[cfg(any(target_os = "ios", feature = "apple-sandbox"))]
-    fn refresh_process_specifics(&mut self, _pid: Pid, _refresh_kind: ProcessRefreshKind) -> bool {
+    pub(crate) fn refresh_process_specifics(
+        &mut self,
+        _pid: Pid,
+        _refresh_kind: ProcessRefreshKind,
+    ) -> bool {
         false
     }
 
     #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
-    fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool {
+    pub(crate) fn refresh_process_specifics(
+        &mut self,
+        pid: Pid,
+        refresh_kind: ProcessRefreshKind,
+    ) -> bool {
         let mut time_interval = None;
         let arg_max = get_arg_max();
         let now = get_now();
@@ -306,56 +262,56 @@ impl SystemExt for System {
     //
     // Need to be moved into a "common" file to avoid duplication.
 
-    fn processes(&self) -> &HashMap<Pid, Process> {
+    pub(crate) fn processes(&self) -> &HashMap<Pid, Process> {
         &self.process_list
     }
 
-    fn process(&self, pid: Pid) -> Option<&Process> {
+    pub(crate) fn process(&self, pid: Pid) -> Option<&Process> {
         self.process_list.get(&pid)
     }
 
-    fn global_cpu_info(&self) -> &Cpu {
+    pub(crate) fn global_cpu_info(&self) -> &Cpu {
         &self.cpus.global_cpu
     }
 
-    fn cpus(&self) -> &[Cpu] {
+    pub(crate) fn cpus(&self) -> &[Cpu] {
         &self.cpus.cpus
     }
 
-    fn physical_core_count(&self) -> Option<usize> {
+    pub(crate) fn physical_core_count(&self) -> Option<usize> {
         physical_core_count()
     }
 
-    fn total_memory(&self) -> u64 {
+    pub(crate) fn total_memory(&self) -> u64 {
         self.mem_total
     }
 
-    fn free_memory(&self) -> u64 {
+    pub(crate) fn free_memory(&self) -> u64 {
         self.mem_free
     }
 
-    fn available_memory(&self) -> u64 {
+    pub(crate) fn available_memory(&self) -> u64 {
         self.mem_available
     }
 
-    fn used_memory(&self) -> u64 {
+    pub(crate) fn used_memory(&self) -> u64 {
         self.mem_used
     }
 
-    fn total_swap(&self) -> u64 {
+    pub(crate) fn total_swap(&self) -> u64 {
         self.swap_total
     }
 
-    fn free_swap(&self) -> u64 {
+    pub(crate) fn free_swap(&self) -> u64 {
         self.swap_free
     }
 
     // TODO: need to be checked
-    fn used_swap(&self) -> u64 {
+    pub(crate) fn used_swap(&self) -> u64 {
         self.swap_total - self.swap_free
     }
 
-    fn uptime(&self) -> u64 {
+    pub(crate) fn uptime(&self) -> u64 {
         unsafe {
             let csec = libc::time(::std::ptr::null_mut());
 
@@ -363,7 +319,7 @@ impl SystemExt for System {
         }
     }
 
-    fn load_average(&self) -> LoadAvg {
+    pub(crate) fn load_average(&self) -> LoadAvg {
         let mut loads = vec![0f64; 3];
 
         unsafe {
@@ -376,15 +332,15 @@ impl SystemExt for System {
         }
     }
 
-    fn boot_time(&self) -> u64 {
+    pub(crate) fn boot_time(&self) -> u64 {
         self.boot_time
     }
 
-    fn name(&self) -> Option<String> {
+    pub(crate) fn name(&self) -> Option<String> {
         get_system_info(libc::KERN_OSTYPE, Some("Darwin"))
     }
 
-    fn long_os_version(&self) -> Option<String> {
+    pub(crate) fn long_os_version(&self) -> Option<String> {
         #[cfg(target_os = "macos")]
         let friendly_name = match self.os_version().unwrap_or_default() {
             f_n if f_n.starts_with("10.16")
@@ -426,15 +382,15 @@ impl SystemExt for System {
         long_name
     }
 
-    fn host_name(&self) -> Option<String> {
+    pub(crate) fn host_name(&self) -> Option<String> {
         get_system_info(libc::KERN_HOSTNAME, None)
     }
 
-    fn kernel_version(&self) -> Option<String> {
+    pub(crate) fn kernel_version(&self) -> Option<String> {
         get_system_info(libc::KERN_OSRELEASE, None)
     }
 
-    fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version(&self) -> Option<String> {
         unsafe {
             // get the size for the buffer first
             let mut size = 0;
@@ -466,17 +422,11 @@ impl SystemExt for System {
         }
     }
 
-    fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id(&self) -> String {
         std::env::consts::OS.to_owned()
     }
 }
 
-impl Default for System {
-    fn default() -> System {
-        System::new()
-    }
-}
-
 #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))]
 fn get_arg_max() -> usize {
     let mut mib = [libc::CTL_KERN, libc::KERN_ARGMAX];
diff --git a/src/unix/freebsd/mod.rs b/src/unix/freebsd/mod.rs
index d6f61d0..71fc247 100644
--- a/src/unix/freebsd/mod.rs
+++ b/src/unix/freebsd/mod.rs
@@ -13,7 +13,52 @@ pub use self::cpu::Cpu;
 pub(crate) use self::disk::DiskInner;
 pub use self::network::NetworkData;
 pub use self::process::Process;
-pub use self::system::System;
+pub(crate) use self::system::SystemInner;
 pub(crate) use crate::unix::users::get_users;
 pub use crate::unix::users::User;
 pub(crate) use crate::unix::DisksInner;
+
+use libc::c_int;
+use std::time::Duration;
+
+declare_signals! {
+    c_int,
+    Signal::Hangup => libc::SIGHUP,
+    Signal::Interrupt => libc::SIGINT,
+    Signal::Quit => libc::SIGQUIT,
+    Signal::Illegal => libc::SIGILL,
+    Signal::Trap => libc::SIGTRAP,
+    Signal::Abort => libc::SIGABRT,
+    Signal::IOT => libc::SIGIOT,
+    Signal::Bus => libc::SIGBUS,
+    Signal::FloatingPointException => libc::SIGFPE,
+    Signal::Kill => libc::SIGKILL,
+    Signal::User1 => libc::SIGUSR1,
+    Signal::Segv => libc::SIGSEGV,
+    Signal::User2 => libc::SIGUSR2,
+    Signal::Pipe => libc::SIGPIPE,
+    Signal::Alarm => libc::SIGALRM,
+    Signal::Term => libc::SIGTERM,
+    Signal::Child => libc::SIGCHLD,
+    Signal::Continue => libc::SIGCONT,
+    Signal::Stop => libc::SIGSTOP,
+    Signal::TSTP => libc::SIGTSTP,
+    Signal::TTIN => libc::SIGTTIN,
+    Signal::TTOU => libc::SIGTTOU,
+    Signal::Urgent => libc::SIGURG,
+    Signal::XCPU => libc::SIGXCPU,
+    Signal::XFSZ => libc::SIGXFSZ,
+    Signal::VirtualAlarm => libc::SIGVTALRM,
+    Signal::Profiling => libc::SIGPROF,
+    Signal::Winch => libc::SIGWINCH,
+    Signal::IO => libc::SIGIO,
+    Signal::Sys => libc::SIGSYS,
+    _ => None,
+}
+
+#[doc = include_str!("../../../md_doc/is_supported.md")]
+pub const IS_SUPPORTED: bool = true;
+#[doc = include_str!("../../../md_doc/supported_signals.md")]
+pub const SUPPORTED_SIGNALS: &[crate::Signal] = supported_signals();
+#[doc = include_str!("../../../md_doc/minimum_cpu_update_interval.md")]
+pub const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(100);
diff --git a/src/unix/freebsd/process.rs b/src/unix/freebsd/process.rs
index 40c5fce..394ebf4 100644
--- a/src/unix/freebsd/process.rs
+++ b/src/unix/freebsd/process.rs
@@ -69,7 +69,7 @@ pub struct Process {
 
 impl ProcessExt for Process {
     fn kill_with(&self, signal: Signal) -> Option<bool> {
-        let c_signal = super::system::convert_signal(signal)?;
+        let c_signal = crate::sys::convert_signal(signal)?;
         unsafe { Some(libc::kill(self.pid.0, c_signal) == 0) }
     }
 
diff --git a/src/unix/freebsd/system.rs b/src/unix/freebsd/system.rs
index fcfdc61..23dd13e 100644
--- a/src/unix/freebsd/system.rs
+++ b/src/unix/freebsd/system.rs
@@ -2,7 +2,7 @@
 
 use crate::{
     sys::{Cpu, Process},
-    CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt,
+    CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind,
 };
 
 use std::cell::UnsafeCell;
@@ -11,7 +11,6 @@ use std::ffi::CStr;
 use std::mem::MaybeUninit;
 use std::path::{Path, PathBuf};
 use std::ptr::NonNull;
-use std::time::Duration;
 
 use crate::sys::cpu::{physical_core_count, CpusWrapper};
 use crate::sys::utils::{
@@ -21,43 +20,7 @@ use crate::sys::utils::{
 
 use libc::c_int;
 
-declare_signals! {
-    c_int,
-    Signal::Hangup => libc::SIGHUP,
-    Signal::Interrupt => libc::SIGINT,
-    Signal::Quit => libc::SIGQUIT,
-    Signal::Illegal => libc::SIGILL,
-    Signal::Trap => libc::SIGTRAP,
-    Signal::Abort => libc::SIGABRT,
-    Signal::IOT => libc::SIGIOT,
-    Signal::Bus => libc::SIGBUS,
-    Signal::FloatingPointException => libc::SIGFPE,
-    Signal::Kill => libc::SIGKILL,
-    Signal::User1 => libc::SIGUSR1,
-    Signal::Segv => libc::SIGSEGV,
-    Signal::User2 => libc::SIGUSR2,
-    Signal::Pipe => libc::SIGPIPE,
-    Signal::Alarm => libc::SIGALRM,
-    Signal::Term => libc::SIGTERM,
-    Signal::Child => libc::SIGCHLD,
-    Signal::Continue => libc::SIGCONT,
-    Signal::Stop => libc::SIGSTOP,
-    Signal::TSTP => libc::SIGTSTP,
-    Signal::TTIN => libc::SIGTTIN,
-    Signal::TTOU => libc::SIGTTOU,
-    Signal::Urgent => libc::SIGURG,
-    Signal::XCPU => libc::SIGXCPU,
-    Signal::XFSZ => libc::SIGXFSZ,
-    Signal::VirtualAlarm => libc::SIGVTALRM,
-    Signal::Profiling => libc::SIGPROF,
-    Signal::Winch => libc::SIGWINCH,
-    Signal::IO => libc::SIGIO,
-    Signal::Sys => libc::SIGSYS,
-    _ => None,
-}
-
-#[doc = include_str!("../../../md_doc/system.md")]
-pub struct System {
+pub(crate) struct SystemInner {
     process_list: HashMap<Pid, Process>,
     mem_total: u64,
     mem_free: u64,
@@ -69,15 +32,9 @@ pub struct System {
     cpus: CpusWrapper,
 }
 
-impl SystemExt for System {
-    const IS_SUPPORTED: bool = true;
-    const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals();
-    const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(100);
-
-    fn new_with_specifics(refreshes: RefreshKind) -> System {
-        let system_info = SystemInfo::new();
-
-        let mut s = System {
+impl SystemInner {
+    pub(crate) fn new() -> Self {
+        Self {
             process_list: HashMap::with_capacity(200),
             mem_total: 0,
             mem_free: 0,
@@ -85,14 +42,12 @@ impl SystemExt for System {
             swap_total: 0,
             swap_used: 0,
             boot_time: boot_time(),
-            system_info,
+            system_info: SystemInfo::new(),
             cpus: CpusWrapper::new(),
-        };
-        s.refresh_specifics(refreshes);
-        s
+        }
     }
 
-    fn refresh_memory(&mut self) {
+    pub(crate) fn refresh_memory(&mut self) {
         if self.mem_total == 0 {
             self.mem_total = self.system_info.get_total_memory();
         }
@@ -103,15 +58,19 @@ impl SystemExt for System {
         self.swap_used = swap_used;
     }
 
-    fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) {
+    pub(crate) fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) {
         self.cpus.refresh(refresh_kind)
     }
 
-    fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) {
+    pub(crate) fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) {
         unsafe { self.refresh_procs(refresh_kind) }
     }
 
-    fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool {
+    pub(crate) fn refresh_process_specifics(
+        &mut self,
+        pid: Pid,
+        refresh_kind: ProcessRefreshKind,
+    ) -> bool {
         unsafe {
             let kd = self.system_info.kd.as_ptr();
             let mut count = 0;
@@ -170,68 +129,68 @@ impl SystemExt for System {
     //
     // Need to be moved into a "common" file to avoid duplication.
 
-    fn processes(&self) -> &HashMap<Pid, Process> {
+    pub(crate) fn processes(&self) -> &HashMap<Pid, Process> {
         &self.process_list
     }
 
-    fn process(&self, pid: Pid) -> Option<&Process> {
+    pub(crate) fn process(&self, pid: Pid) -> Option<&Process> {
         self.process_list.get(&pid)
     }
 
-    fn global_cpu_info(&self) -> &Cpu {
+    pub(crate) fn global_cpu_info(&self) -> &Cpu {
         &self.cpus.global_cpu
     }
 
-    fn cpus(&self) -> &[Cpu] {
+    pub(crate) fn cpus(&self) -> &[Cpu] {
         &self.cpus.cpus
     }
 
-    fn physical_core_count(&self) -> Option<usize> {
+    pub(crate) fn physical_core_count(&self) -> Option<usize> {
         physical_core_count()
     }
 
-    fn total_memory(&self) -> u64 {
+    pub(crate) fn total_memory(&self) -> u64 {
         self.mem_total
     }
 
-    fn free_memory(&self) -> u64 {
+    pub(crate) fn free_memory(&self) -> u64 {
         self.mem_free
     }
 
-    fn available_memory(&self) -> u64 {
+    pub(crate) fn available_memory(&self) -> u64 {
         self.mem_free
     }
 
-    fn used_memory(&self) -> u64 {
+    pub(crate) fn used_memory(&self) -> u64 {
         self.mem_used
     }
 
-    fn total_swap(&self) -> u64 {
+    pub(crate) fn total_swap(&self) -> u64 {
         self.swap_total
     }
 
-    fn free_swap(&self) -> u64 {
+    pub(crate) fn free_swap(&self) -> u64 {
         self.swap_total - self.swap_used
     }
 
     // TODO: need to be checked
-    fn used_swap(&self) -> u64 {
+    pub(crate) fn used_swap(&self) -> u64 {
         self.swap_used
     }
 
-    fn uptime(&self) -> u64 {
+    pub(crate) fn uptime(&self) -> u64 {
         unsafe {
-            let csec = libc::time(::std::ptr::null_mut());
+            let csec = libc::time(std::ptr::null_mut());
 
             libc::difftime(csec, self.boot_time as _) as u64
         }
     }
 
-    fn boot_time(&self) -> u64 {
+    pub(crate) fn boot_time(&self) -> u64 {
         self.boot_time
     }
 
-    fn load_average(&self) -> LoadAvg {
+    pub(crate) fn load_average(&self) -> LoadAvg {
         let mut loads = vec![0f64; 3];
         unsafe {
             libc::getloadavg(loads.as_mut_ptr(), 3);
@@ -243,38 +202,32 @@ impl SystemExt for System {
         }
     }
 
-    fn name(&self) -> Option<String> {
+    pub(crate) fn name(&self) -> Option<String> {
         self.system_info.get_os_name()
     }
 
-    fn long_os_version(&self) -> Option<String> {
+    pub(crate) fn long_os_version(&self) -> Option<String> {
         self.system_info.get_os_release_long()
     }
 
-    fn host_name(&self) -> Option<String> {
+    pub(crate) fn host_name(&self) -> Option<String> {
         self.system_info.get_hostname()
     }
 
-    fn kernel_version(&self) -> Option<String> {
+    pub(crate) fn kernel_version(&self) -> Option<String> {
         self.system_info.get_kernel_version()
     }
 
-    fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version(&self) -> Option<String> {
         self.system_info.get_os_release()
     }
 
-    fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id(&self) -> String {
         std::env::consts::OS.to_owned()
     }
 }
 
-impl Default for System {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
-impl System {
+impl SystemInner {
     unsafe fn refresh_procs(&mut self, refresh_kind: ProcessRefreshKind) {
         let kd = self.system_info.kd.as_ptr();
         let procs = {
diff --git a/src/unix/linux/cpu.rs b/src/unix/linux/cpu.rs
index 455d3f4..60b652d 100644
--- a/src/unix/linux/cpu.rs
+++ b/src/unix/linux/cpu.rs
@@ -8,7 +8,7 @@ use std::io::{BufRead, BufReader, Read};
 use std::time::Instant;
 
 use crate::sys::utils::to_u64;
-use crate::{CpuExt, CpuRefreshKind, SystemExt};
+use crate::{CpuExt, CpuRefreshKind};
 
 macro_rules! to_str {
     ($e:expr) => {
@@ -68,7 +68,7 @@ impl CpusWrapper {
     pub(crate) fn refresh(&mut self, only_update_global_cpu: bool, refresh_kind: CpuRefreshKind) {
         let need_cpu_usage_update = self
             .last_update
-            .map(|last_update| last_update.elapsed() > crate::System::MINIMUM_CPU_UPDATE_INTERVAL)
+            .map(|last_update| last_update.elapsed() > crate::MINIMUM_CPU_UPDATE_INTERVAL)
             .unwrap_or(true);
 
         let first = self.cpus.is_empty();
diff --git a/src/unix/linux/mod.rs b/src/unix/linux/mod.rs
index abefdfd..4c63193 100644
--- a/src/unix/linux/mod.rs
+++ b/src/unix/linux/mod.rs
@@ -13,7 +13,52 @@ pub use self::cpu::Cpu;
 pub(crate) use self::disk::DiskInner;
 pub use self::network::NetworkData;
 pub use self::process::Process;
-pub use self::system::System;
+pub(crate) use self::system::SystemInner;
 pub(crate) use crate::unix::users::get_users;
 pub use crate::unix::users::User;
 pub(crate) use crate::unix::DisksInner;
+
+use std::time::Duration;
+
+declare_signals! {
+    libc::c_int,
+    Signal::Hangup => libc::SIGHUP,
+    Signal::Interrupt => libc::SIGINT,
+    Signal::Quit => libc::SIGQUIT,
+    Signal::Illegal => libc::SIGILL,
+    Signal::Trap => libc::SIGTRAP,
+    Signal::Abort => libc::SIGABRT,
+    Signal::IOT => libc::SIGIOT,
+    Signal::Bus => libc::SIGBUS,
+    Signal::FloatingPointException => libc::SIGFPE,
+    Signal::Kill => libc::SIGKILL,
+    Signal::User1 => libc::SIGUSR1,
+    Signal::Segv => libc::SIGSEGV,
+    Signal::User2 => libc::SIGUSR2,
+    Signal::Pipe => libc::SIGPIPE,
+    Signal::Alarm => libc::SIGALRM,
+    Signal::Term => libc::SIGTERM,
+    Signal::Child => libc::SIGCHLD,
+    Signal::Continue => libc::SIGCONT,
+    Signal::Stop => libc::SIGSTOP,
+    Signal::TSTP => libc::SIGTSTP,
+    Signal::TTIN => libc::SIGTTIN,
+    Signal::TTOU => libc::SIGTTOU,
+    Signal::Urgent => libc::SIGURG,
+    Signal::XCPU => libc::SIGXCPU,
+    Signal::XFSZ => libc::SIGXFSZ,
+    Signal::VirtualAlarm => libc::SIGVTALRM,
+    Signal::Profiling => libc::SIGPROF,
+    Signal::Winch => libc::SIGWINCH,
+    Signal::IO => libc::SIGIO,
+    Signal::Poll => libc::SIGPOLL,
+    Signal::Power => libc::SIGPWR,
+    Signal::Sys => libc::SIGSYS,
+}
+
+#[doc = include_str!("../../../md_doc/is_supported.md")]
+pub const IS_SUPPORTED: bool = true;
+#[doc = include_str!("../../../md_doc/supported_signals.md")]
+pub const SUPPORTED_SIGNALS: &[crate::Signal] = supported_signals();
+#[doc = include_str!("../../../md_doc/minimum_cpu_update_interval.md")]
+pub const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200);
diff --git a/src/unix/linux/process.rs b/src/unix/linux/process.rs
index 9fc8e55..3ca7873 100644
--- a/src/unix/linux/process.rs
+++ b/src/unix/linux/process.rs
@@ -134,7 +134,7 @@ impl Process {
 
 impl ProcessExt for Process {
     fn kill_with(&self, signal: Signal) -> Option<bool> {
-        let c_signal = super::system::convert_signal(signal)?;
+        let c_signal = crate::sys::convert_signal(signal)?;
         unsafe { Some(kill(self.pid.0, c_signal) == 0) }
     }
 
diff --git a/src/unix/linux/system.rs b/src/unix/linux/system.rs
index bb8970a..8794608 100644
--- a/src/unix/linux/system.rs
+++ b/src/unix/linux/system.rs
@@ -3,9 +3,9 @@
 use crate::sys::cpu::*;
 use crate::sys::process::*;
 use crate::sys::utils::{get_all_data, to_u64};
-use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt};
+use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind};
 
-use libc::{self, c_char, c_int, sysconf, _SC_CLK_TCK, _SC_HOST_NAME_MAX, _SC_PAGESIZE};
+use libc::{self, c_char, sysconf, _SC_CLK_TCK, _SC_HOST_NAME_MAX, _SC_PAGESIZE};
 use std::cmp::min;
 use std::collections::HashMap;
 use std::fs::File;
@@ -13,7 +13,6 @@ use std::io::{BufRead, BufReader, Read};
 use std::path::Path;
 use std::str::FromStr;
 use std::sync::{Arc, Mutex};
-use std::time::Duration;
 
 // This whole thing is to prevent having too many files open at once. It could be problematic
 // for processes using a lot of files and using sysinfo at the same time.
@@ -108,44 +107,7 @@ impl SystemInfo {
     }
 }
 
-declare_signals! {
-    c_int,
-    Signal::Hangup => libc::SIGHUP,
-    Signal::Interrupt => libc::SIGINT,
-    Signal::Quit => libc::SIGQUIT,
-    Signal::Illegal => libc::SIGILL,
-    Signal::Trap => libc::SIGTRAP,
-    Signal::Abort => libc::SIGABRT,
-    Signal::IOT => libc::SIGIOT,
-    Signal::Bus => libc::SIGBUS,
-    Signal::FloatingPointException => libc::SIGFPE,
-    Signal::Kill => libc::SIGKILL,
-    Signal::User1 => libc::SIGUSR1,
-    Signal::Segv => libc::SIGSEGV,
-    Signal::User2 => libc::SIGUSR2,
-    Signal::Pipe => libc::SIGPIPE,
-    Signal::Alarm => libc::SIGALRM,
-    Signal::Term => libc::SIGTERM,
-    Signal::Child => libc::SIGCHLD,
-    Signal::Continue => libc::SIGCONT,
-    Signal::Stop => libc::SIGSTOP,
-    Signal::TSTP => libc::SIGTSTP,
-    Signal::TTIN => libc::SIGTTIN,
-    Signal::TTOU => libc::SIGTTOU,
-    Signal::Urgent => libc::SIGURG,
-    Signal::XCPU => libc::SIGXCPU,
-    Signal::XFSZ => libc::SIGXFSZ,
-    Signal::VirtualAlarm => libc::SIGVTALRM,
-    Signal::Profiling => libc::SIGPROF,
-    Signal::Winch => libc::SIGWINCH,
-    Signal::IO => libc::SIGIO,
-    Signal::Poll => libc::SIGPOLL,
-    Signal::Power => libc::SIGPWR,
-    Signal::Sys => libc::SIGSYS,
-}
-
-#[doc = include_str!("../../../md_doc/system.md")]
-pub struct System {
+pub(crate) struct SystemInner {
     process_list: Process,
     mem_total: u64,
     mem_free: u64,
@@ -160,7 +122,7 @@ pub struct System {
     cpus: CpusWrapper,
 }
 
-impl System {
+impl SystemInner {
     /// It is sometime possible that a CPU usage computation is bigger than
     /// `"number of CPUs" * 100`.
     ///
@@ -208,15 +170,10 @@ impl System {
     }
 }
 
-impl SystemExt for System {
-    const IS_SUPPORTED: bool = true;
-    const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals();
-    const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200);
-
-    fn new_with_specifics(refreshes: RefreshKind) -> System {
-        let process_list = Process::new(Pid(0));
-        let mut s = System {
-            process_list,
+impl SystemInner {
+    pub(crate) fn new() -> Self {
+        Self {
+            process_list: Process::new(Pid(0)),
             mem_total: 0,
             mem_free: 0,
             mem_available: 0,
@@ -228,12 +185,10 @@ impl SystemExt for System {
             swap_free: 0,
             cpus: CpusWrapper::new(),
             info: SystemInfo::new(),
-        };
-        s.refresh_specifics(refreshes);
-        s
+        }
     }
 
-    fn refresh_memory(&mut self) {
+    pub(crate) fn refresh_memory(&mut self) {
         let mut mem_available_found = false;
         read_table("/proc/meminfo", ':', |key, value_kib| {
             let field = match key {
@@ -301,11 +256,11 @@ impl SystemExt for System {
         }
     }
 
-    fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) {
+    pub(crate) fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) {
         self.refresh_cpus(false, refresh_kind);
     }
 
-    fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) {
+    pub(crate) fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) {
         let uptime = self.uptime();
         refresh_procs(
             &mut self.process_list,
@@ -319,7 +274,11 @@ impl SystemExt for System {
         self.cpus.set_need_cpus_update();
     }
 
-    fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool {
+    pub(crate) fn refresh_process_specifics(
+        &mut self,
+        pid: Pid,
+        refresh_kind: ProcessRefreshKind,
+    ) -> bool {
         let uptime = self.uptime();
         match _get_process_data(
             &Path::new("/proc/").join(pid.to_string()),
@@ -364,56 +323,56 @@ impl SystemExt for System {
     //
     // Need to be moved into a "common" file to avoid duplication.
 
-    fn processes(&self) -> &HashMap<Pid, Process> {
+    pub(crate) fn processes(&self) -> &HashMap<Pid, Process> {
         &self.process_list.tasks
     }
 
-    fn process(&self, pid: Pid) -> Option<&Process> {
+    pub(crate) fn process(&self, pid: Pid) -> Option<&Process> {
         self.process_list.tasks.get(&pid)
     }
 
-    fn global_cpu_info(&self) -> &Cpu {
+    pub(crate) fn global_cpu_info(&self) -> &Cpu {
         &self.cpus.global_cpu
     }
 
-    fn cpus(&self) -> &[Cpu] {
+    pub(crate) fn cpus(&self) -> &[Cpu] {
         &self.cpus.cpus
     }
 
-    fn physical_core_count(&self) -> Option<usize> {
+    pub(crate) fn physical_core_count(&self) -> Option<usize> {
         get_physical_core_count()
     }
 
-    fn total_memory(&self) -> u64 {
+    pub(crate) fn total_memory(&self) -> u64 {
         self.mem_total
     }
 
-    fn free_memory(&self) -> u64 {
+    pub(crate) fn free_memory(&self) -> u64 {
         self.mem_free
     }
 
-    fn available_memory(&self) -> u64 {
+    pub(crate) fn available_memory(&self) -> u64 {
         self.mem_available
     }
 
-    fn used_memory(&self) -> u64 {
+    pub(crate) fn used_memory(&self) -> u64 {
         self.mem_total - self.mem_available
     }
 
-    fn total_swap(&self) -> u64 {
+    pub(crate) fn total_swap(&self) -> u64 {
         self.swap_total
     }
 
-    fn free_swap(&self) -> u64 {
+    pub(crate) fn free_swap(&self) -> u64 {
         self.swap_free
     }
 
     // need to be checked
-    fn used_swap(&self) -> u64 {
+    pub(crate) fn used_swap(&self) -> u64 {
         self.swap_total - self.swap_free
     }
 
-    fn uptime(&self) -> u64 {
+    pub(crate) fn uptime(&self) -> u64 {
         let content = get_all_data("/proc/uptime", 50).unwrap_or_default();
         content
             .split('.')
@@ -422,11 +381,11 @@ impl SystemExt for System {
             .unwrap_or_default()
     }
 
-    fn boot_time(&self) -> u64 {
+    pub(crate) fn boot_time(&self) -> u64 {
         self.info.boot_time
     }
 
-    fn load_average(&self) -> LoadAvg {
+    pub(crate) fn load_average(&self) -> LoadAvg {
         let mut s = String::new();
         if File::open("/proc/loadavg")
             .and_then(|mut f| f.read_to_string(&mut s))
@@ -448,7 +407,7 @@ impl SystemExt for System {
     }
 
     #[cfg(not(target_os = "android"))]
-    fn name(&self) -> Option<String> {
+    pub(crate) fn name(&self) -> Option<String> {
         get_system_info_linux(
             InfoType::Name,
             Path::new("/etc/os-release"),
@@ -457,11 +416,11 @@ impl SystemExt for System {
     }
 
     #[cfg(target_os = "android")]
-    fn name(&self) -> Option<String> {
+    pub(crate) fn name(&self) -> Option<String> {
         get_system_info_android(InfoType::Name)
     }
 
-    fn long_os_version(&self) -> Option<String> {
+    pub(crate) fn long_os_version(&self) -> Option<String> {
         #[cfg(target_os = "android")]
         let system_name = "Android";
 
@@ -476,7 +435,7 @@ impl SystemExt for System {
         ))
     }
 
-    fn host_name(&self) -> Option<String> {
+    pub(crate) fn host_name(&self) -> Option<String> {
         unsafe {
             let hostname_max = sysconf(_SC_HOST_NAME_MAX);
             let mut buffer = vec![0_u8; hostname_max as usize];
@@ -493,7 +452,7 @@ impl SystemExt for System {
         }
     }
 
-    fn kernel_version(&self) -> Option<String> {
+    pub(crate) fn kernel_version(&self) -> Option<String> {
         let mut raw = std::mem::MaybeUninit::<libc::utsname>::zeroed();
 
         unsafe {
@@ -515,7 +474,7 @@ impl SystemExt for System {
     }
 
     #[cfg(not(target_os = "android"))]
-    fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version(&self) -> Option<String> {
         get_system_info_linux(
             InfoType::OsVersion,
             Path::new("/etc/os-release"),
@@ -524,12 +483,12 @@ impl SystemExt for System {
     }
 
     #[cfg(target_os = "android")]
-    fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version(&self) -> Option<String> {
         get_system_info_android(InfoType::OsVersion)
     }
 
     #[cfg(not(target_os = "android"))]
-    fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id(&self) -> String {
         get_system_info_linux(
             InfoType::DistributionID,
             Path::new("/etc/os-release"),
@@ -539,7 +498,7 @@ impl SystemExt for System {
     }
 
     #[cfg(target_os = "android")]
-    fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id(&self) -> 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.
@@ -573,12 +532,6 @@ where
     }
 }
 
-impl Default for System {
-    fn default() -> System {
-        System::new()
-    }
-}
-
 #[derive(PartialEq, Eq)]
 enum InfoType {
     /// The end-user friendly name of:
diff --git a/src/unknown/mod.rs b/src/unknown/mod.rs
index ccbad44..f607033 100644
--- a/src/unknown/mod.rs
+++ b/src/unknown/mod.rs
@@ -13,6 +13,20 @@ pub use self::cpu::Cpu;
 pub(crate) use self::disk::{DiskInner, DisksInner};
 pub use self::network::NetworkData;
 pub use self::process::Process;
-pub use self::system::System;
+pub(crate) use self::system::SystemInner;
 pub(crate) use self::users::get_users;
 pub use self::users::User;
+
+use std::time::Duration;
+
+declare_signals! {
+    (),
+    _ => None,
+}
+
+#[doc = include_str!("../../md_doc/is_supported.md")]
+pub const IS_SUPPORTED: bool = false;
+#[doc = include_str!("../../md_doc/supported_signals.md")]
+pub const SUPPORTED_SIGNALS: &[crate::Signal] = supported_signals();
+#[doc = include_str!("../../md_doc/minimum_cpu_update_interval.md")]
+pub const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(0);
diff --git a/src/unknown/system.rs b/src/unknown/system.rs
index 76b31a8..06c1983 100644
--- a/src/unknown/system.rs
+++ b/src/unknown/system.rs
@@ -2,42 +2,35 @@
 
 use crate::{
     sys::{Cpu, Process},
-    CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt,
+    CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind,
 };
 
 use std::collections::HashMap;
-use std::time::Duration;
 
-declare_signals! {
-    (),
-    _ => None,
-}
-
-#[doc = include_str!("../../md_doc/system.md")]
-pub struct System {
+pub(crate) struct SystemInner {
     processes_list: HashMap<Pid, Process>,
     global_cpu: Cpu,
 }
 
-impl SystemExt for System {
-    const IS_SUPPORTED: bool = false;
-    const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals();
-    const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(0);
-
-    fn new_with_specifics(_: RefreshKind) -> System {
-        System {
+impl SystemInner {
+    pub(crate) fn new() -> Self {
+        Self {
             processes_list: Default::default(),
             global_cpu: Cpu::new(),
         }
     }
 
-    fn refresh_memory(&mut self) {}
+    pub(crate) fn refresh_memory(&mut self) {}
 
-    fn refresh_cpu_specifics(&mut self, _refresh_kind: CpuRefreshKind) {}
+    pub(crate) fn refresh_cpu_specifics(&mut self, _refresh_kind: CpuRefreshKind) {}
 
-    fn refresh_processes_specifics(&mut self, _refresh_kind: ProcessRefreshKind) {}
+    pub(crate) fn refresh_processes_specifics(&mut self, _refresh_kind: ProcessRefreshKind) {}
 
-    fn refresh_process_specifics(&mut self, _pid: Pid, _refresh_kind: ProcessRefreshKind) -> bool {
+    pub(crate) fn refresh_process_specifics(
+        &mut self,
+        _pid: Pid,
+        _refresh_kind: ProcessRefreshKind,
+    ) -> bool {
         false
     }
 
@@ -45,63 +38,63 @@ impl SystemExt for System {
     //
     // Need to be moved into a "common" file to avoid duplication.
 
-    fn processes(&self) -> &HashMap<Pid, Process> {
+    pub(crate) fn processes(&self) -> &HashMap<Pid, Process> {
         &self.processes_list
     }
 
-    fn process(&self, _pid: Pid) -> Option<&Process> {
+    pub(crate) fn process(&self, _pid: Pid) -> Option<&Process> {
         None
     }
 
-    fn global_cpu_info(&self) -> &Cpu {
+    pub(crate) fn global_cpu_info(&self) -> &Cpu {
         &self.global_cpu
     }
 
-    fn cpus(&self) -> &[Cpu] {
+    pub(crate) fn cpus(&self) -> &[Cpu] {
         &[]
     }
 
-    fn physical_core_count(&self) -> Option<usize> {
+    pub(crate) fn physical_core_count(&self) -> Option<usize> {
         None
     }
 
-    fn total_memory(&self) -> u64 {
+    pub(crate) fn total_memory(&self) -> u64 {
         0
     }
 
-    fn free_memory(&self) -> u64 {
+    pub(crate) fn free_memory(&self) -> u64 {
         0
     }
 
-    fn available_memory(&self) -> u64 {
+    pub(crate) fn available_memory(&self) -> u64 {
         0
     }
 
-    fn used_memory(&self) -> u64 {
+    pub(crate) fn used_memory(&self) -> u64 {
         0
     }
 
-    fn total_swap(&self) -> u64 {
+    pub(crate) fn total_swap(&self) -> u64 {
         0
     }
 
-    fn free_swap(&self) -> u64 {
+    pub(crate) fn free_swap(&self) -> u64 {
         0
     }
 
-    fn used_swap(&self) -> u64 {
+    pub(crate) fn used_swap(&self) -> u64 {
         0
     }
 
-    fn uptime(&self) -> u64 {
+    pub(crate) fn uptime(&self) -> u64 {
         0
     }
 
-    fn boot_time(&self) -> u64 {
+    pub(crate) fn boot_time(&self) -> u64 {
         0
     }
 
-    fn load_average(&self) -> LoadAvg {
+    pub(crate) fn load_average(&self) -> LoadAvg {
         LoadAvg {
             one: 0.,
             five: 0.,
@@ -109,33 +102,27 @@ impl SystemExt for System {
         }
     }
 
-    fn name(&self) -> Option<String> {
+    pub(crate) fn name(&self) -> Option<String> {
         None
     }
 
-    fn long_os_version(&self) -> Option<String> {
+    pub(crate) fn long_os_version(&self) -> Option<String> {
         None
     }
 
-    fn kernel_version(&self) -> Option<String> {
+    pub(crate) fn kernel_version(&self) -> Option<String> {
         None
     }
 
-    fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version(&self) -> Option<String> {
         None
     }
 
-    fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id(&self) -> String {
         std::env::consts::OS.to_owned()
     }
 
-    fn host_name(&self) -> Option<String> {
+    pub(crate) fn host_name(&self) -> Option<String> {
         None
     }
 }
-
-impl Default for System {
-    fn default() -> System {
-        System::new()
-    }
-}
diff --git a/src/windows/mod.rs b/src/windows/mod.rs
index a7445a3..8927b96 100644
--- a/src/windows/mod.rs
+++ b/src/windows/mod.rs
@@ -18,6 +18,21 @@ pub(crate) use self::disk::{DiskInner, DisksInner};
 pub use self::network::NetworkData;
 pub use self::process::Process;
 pub use self::sid::Sid;
-pub use self::system::System;
+pub(crate) use self::system::SystemInner;
 pub(crate) use self::users::get_users;
 pub use self::users::User;
+
+use std::time::Duration;
+
+declare_signals! {
+    (),
+    Signal::Kill => (),
+    _ => None,
+}
+
+#[doc = include_str!("../../md_doc/is_supported.md")]
+pub const IS_SUPPORTED: bool = true;
+#[doc = include_str!("../../md_doc/supported_signals.md")]
+pub const SUPPORTED_SIGNALS: &[crate::Signal] = supported_signals();
+#[doc = include_str!("../../md_doc/minimum_cpu_update_interval.md")]
+pub const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200);
diff --git a/src/windows/process.rs b/src/windows/process.rs
index 110dd31..e2cdaa2 100644
--- a/src/windows/process.rs
+++ b/src/windows/process.rs
@@ -507,7 +507,7 @@ impl Process {
 
 impl ProcessExt for Process {
     fn kill_with(&self, signal: Signal) -> Option<bool> {
-        super::system::convert_signal(signal)?;
+        crate::sys::convert_signal(signal)?;
         let mut kill = process::Command::new("taskkill.exe");
         kill.arg("/PID").arg(self.pid.to_string()).arg("/F");
         kill.creation_flags(CREATE_NO_WINDOW.0);
diff --git a/src/windows/system.rs b/src/windows/system.rs
index 4608b63..3bd2c35 100644
--- a/src/windows/system.rs
+++ b/src/windows/system.rs
@@ -1,6 +1,6 @@
 // Take a look at the license at the top of the repository in the LICENSE file.
 
-use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessExt, ProcessRefreshKind, RefreshKind, SystemExt};
+use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessExt, ProcessRefreshKind};
 
 use crate::sys::cpu::*;
 use crate::sys::process::{get_start_time, update_memory, Process};
@@ -13,7 +13,7 @@ use std::cell::UnsafeCell;
 use std::collections::HashMap;
 use std::mem::{size_of, zeroed};
 use std::ptr;
-use std::time::{Duration, SystemTime};
+use std::time::SystemTime;
 
 use ntapi::ntexapi::SYSTEM_PROCESS_INFORMATION;
 use windows::core::PWSTR;
@@ -27,27 +27,9 @@ use windows::Win32::System::SystemInformation::{
 };
 use windows::Win32::System::Threading::GetExitCodeProcess;
 
-declare_signals! {
-    (),
-    Signal::Kill => (),
-    _ => None,
-}
+const WINDOWS_ELEVEN_BUILD_NUMBER: u32 = 22000;
 
-#[doc = include_str!("../../md_doc/system.md")]
-pub struct System {
-    process_list: HashMap<Pid, Process>,
-    mem_total: u64,
-    mem_available: u64,
-    swap_total: u64,
-    swap_used: u64,
-    cpus: CpusWrapper,
-    query: Option<Query>,
-    boot_time: u64,
-}
-
-static WINDOWS_ELEVEN_BUILD_NUMBER: u32 = 22000;
-
-impl System {
+impl SystemInner {
     fn is_windows_eleven(&self) -> bool {
         WINDOWS_ELEVEN_BUILD_NUMBER
             <= self
@@ -75,14 +57,20 @@ unsafe fn boot_time() -> u64 {
     }
 }
 
-impl SystemExt for System {
-    const IS_SUPPORTED: bool = true;
-    const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals();
-    const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200);
+pub(crate) struct SystemInner {
+    process_list: HashMap<Pid, Process>,
+    mem_total: u64,
+    mem_available: u64,
+    swap_total: u64,
+    swap_used: u64,
+    cpus: CpusWrapper,
+    query: Option<Query>,
+    boot_time: u64,
+}
 
-    #[allow(non_snake_case)]
-    fn new_with_specifics(refreshes: RefreshKind) -> System {
-        let mut s = System {
+impl SystemInner {
+    pub(crate) fn new() -> Self {
+        Self {
             process_list: HashMap::with_capacity(500),
             mem_total: 0,
             mem_available: 0,
@@ -91,12 +79,10 @@ impl SystemExt for System {
             cpus: CpusWrapper::new(),
             query: None,
             boot_time: unsafe { boot_time() },
-        };
-        s.refresh_specifics(refreshes);
-        s
+        }
     }
 
-    fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) {
+    pub(crate) fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) {
         if self.query.is_none() {
             self.query = Query::new();
             if let Some(ref mut query) = self.query {
@@ -150,7 +136,7 @@ impl SystemExt for System {
         }
     }
 
-    fn refresh_memory(&mut self) {
+    pub(crate) fn refresh_memory(&mut self) {
         unsafe {
             let mut mem_info: MEMORYSTATUSEX = zeroed();
             mem_info.dwLength = size_of::<MEMORYSTATUSEX>() as u32;
@@ -178,7 +164,11 @@ impl SystemExt for System {
     }
 
     #[allow(clippy::map_entry)]
-    fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool {
+    pub(crate) fn refresh_process_specifics(
+        &mut self,
+        pid: Pid,
+        refresh_kind: ProcessRefreshKind,
+    ) -> bool {
         let now = get_now();
         let nb_cpus = self.cpus.len() as u64;
 
@@ -199,7 +189,7 @@ impl SystemExt for System {
     }
 
     #[allow(clippy::cast_ptr_alignment)]
-    fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) {
+    pub(crate) fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) {
         // Windows 10 notebook requires at least 512KiB of memory to make it in one go
         let mut buffer_size = 512 * 1024;
         let mut process_information: Vec<u8> = Vec::with_capacity(buffer_size);
@@ -334,72 +324,72 @@ impl SystemExt for System {
         });
     }
 
-    fn processes(&self) -> &HashMap<Pid, Process> {
+    pub(crate) fn processes(&self) -> &HashMap<Pid, Process> {
         &self.process_list
     }
 
-    fn process(&self, pid: Pid) -> Option<&Process> {
+    pub(crate) fn process(&self, pid: Pid) -> Option<&Process> {
         self.process_list.get(&pid)
     }
 
-    fn global_cpu_info(&self) -> &Cpu {
+    pub(crate) fn global_cpu_info(&self) -> &Cpu {
         self.cpus.global_cpu()
     }
 
-    fn cpus(&self) -> &[Cpu] {
+    pub(crate) fn cpus(&self) -> &[Cpu] {
         self.cpus.cpus()
     }
 
-    fn physical_core_count(&self) -> Option<usize> {
+    pub(crate) fn physical_core_count(&self) -> Option<usize> {
         get_physical_core_count()
     }
 
-    fn total_memory(&self) -> u64 {
+    pub(crate) fn total_memory(&self) -> u64 {
         self.mem_total
     }
 
-    fn free_memory(&self) -> u64 {
+    pub(crate) fn free_memory(&self) -> u64 {
         // MEMORYSTATUSEX doesn't report free memory
         self.mem_available
     }
 
-    fn available_memory(&self) -> u64 {
+    pub(crate) fn available_memory(&self) -> u64 {
         self.mem_available
     }
 
-    fn used_memory(&self) -> u64 {
+    pub(crate) fn used_memory(&self) -> u64 {
         self.mem_total - self.mem_available
     }
 
-    fn total_swap(&self) -> u64 {
+    pub(crate) fn total_swap(&self) -> u64 {
         self.swap_total
     }
 
-    fn free_swap(&self) -> u64 {
+    pub(crate) fn free_swap(&self) -> u64 {
         self.swap_total - self.swap_used
     }
 
-    fn used_swap(&self) -> u64 {
+    pub(crate) fn used_swap(&self) -> u64 {
         self.swap_used
     }
 
-    fn uptime(&self) -> u64 {
+    pub(crate) fn uptime(&self) -> u64 {
         unsafe { GetTickCount64() / 1_000 }
     }
 
-    fn boot_time(&self) -> u64 {
+    pub(crate) fn boot_time(&self) -> u64 {
         self.boot_time
     }
 
-    fn load_average(&self) -> LoadAvg {
+    pub(crate) fn load_average(&self) -> LoadAvg {
         get_load_average()
     }
 
-    fn name(&self) -> Option<String> {
+    pub(crate) fn name(&self) -> Option<String> {
         Some("Windows".to_owned())
     }
 
-    fn long_os_version(&self) -> Option<String> {
+    pub(crate) fn long_os_version(&self) -> Option<String> {
         if self.is_windows_eleven() {
             return get_reg_string_value(
                 HKEY_LOCAL_MACHINE,
@@ -415,11 +405,11 @@ impl SystemExt for System {
         )
     }
 
-    fn host_name(&self) -> Option<String> {
+    pub(crate) fn host_name(&self) -> Option<String> {
         get_dns_hostname()
     }
 
-    fn kernel_version(&self) -> Option<String> {
+    pub(crate) fn kernel_version(&self) -> Option<String> {
         get_reg_string_value(
             HKEY_LOCAL_MACHINE,
             "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
@@ -427,7 +417,7 @@ impl SystemExt for System {
         )
     }
 
-    fn os_version(&self) -> Option<String> {
+    pub(crate) fn os_version(&self) -> Option<String> {
         let build_number = get_reg_string_value(
             HKEY_LOCAL_MACHINE,
             "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
@@ -449,17 +439,11 @@ impl SystemExt for System {
         Some(format!("{major} ({build_number})"))
     }
 
-    fn distribution_id(&self) -> String {
+    pub(crate) fn distribution_id(&self) -> String {
         std::env::consts::OS.to_owned()
     }
 }
 
-impl Default for System {
-    fn default() -> System {
-        System::new()
-    }
-}
-
 pub(crate) fn is_proc_running(handle: HANDLE) -> bool {
     let mut exit_code = 0;
     unsafe { GetExitCodeProcess(handle, &mut exit_code) }.is_ok()


Test patch:
diff --git a/test-unknown/src/lib.rs b/test-unknown/src/lib.rs
index b4fa566..42269fb 100644
--- a/test-unknown/src/lib.rs
+++ b/test-unknown/src/lib.rs
@@ -1,4 +1,4 @@
-use sysinfo::{System, SystemExt};
+use sysinfo::System;
 use wasm_bindgen::prelude::*;
 
 #[wasm_bindgen]
diff --git a/tests/code_checkers/signals.rs b/tests/code_checkers/signals.rs
index 68e47f7..e97b402 100644
--- a/tests/code_checkers/signals.rs
+++ b/tests/code_checkers/signals.rs
@@ -7,10 +7,10 @@ fn check_supported_signals_decl<'a>(lines: &mut impl Iterator<Item = &'a str>, p
     for line in lines {
         let trimmed = line.trim();
         if trimmed.starts_with("const SUPPORTED_SIGNALS: &'static [Signal]") {
-            if trimmed != "const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals();" {
+            if trimmed != "const SUPPORTED_SIGNALS: &[Signal] = supported_signals();" {
                 show_error(
                     p,
-                    "SystemExt::SUPPORTED_SIGNALS should be declared using `supported_signals()`",
+                    "SUPPORTED_SIGNALS should be declared using `supported_signals()`",
                 );
                 return 1;
             }
@@ -31,7 +31,7 @@ fn check_kill_decl<'a>(lines: &mut impl Iterator<Item = &'a str>, p: &Path) -> u
         } else if trimmed.starts_with("fn kill_with(") {
             if let Some(line) = lines.next() {
                 let trimmed = line.trim();
-                if trimmed.ends_with("::system::convert_signal(signal)?;") || trimmed == "None" {
+                if trimmed.ends_with("crate::sys::convert_signal(signal)?;") || trimmed == "None" {
                     continue;
                 } else {
                     show_error(p, "`ProcessExt::kill_with` should use `convert_signal`");
diff --git a/tests/cpu.rs b/tests/cpu.rs
index f931ceb..f803737 100644
--- a/tests/cpu.rs
+++ b/tests/cpu.rs
@@ -4,12 +4,12 @@
 
 #[test]
 fn test_cpu() {
-    use sysinfo::{CpuExt, SystemExt};
+    use sysinfo::CpuExt;
 
     let mut s = sysinfo::System::new();
     assert!(s.cpus().is_empty());
 
-    if !sysinfo::System::IS_SUPPORTED {
+    if !sysinfo::IS_SUPPORTED {
         return;
     }
 
@@ -30,9 +30,7 @@ fn test_cpu() {
 
 #[test]
 fn test_physical_core_numbers() {
-    use sysinfo::SystemExt;
-
-    if sysinfo::System::IS_SUPPORTED {
+    if sysinfo::IS_SUPPORTED {
         let s = sysinfo::System::new();
         let count = s.physical_core_count();
         assert_ne!(count, None);
@@ -42,7 +40,7 @@ fn test_physical_core_numbers() {
 
 #[test]
 fn test_global_cpu_info_not_set() {
-    use sysinfo::{CpuExt, SystemExt};
+    use sysinfo::CpuExt;
 
     let mut s = sysinfo::System::new();
     assert_eq!(s.global_cpu_info().vendor_id(), "");
diff --git a/tests/disk_list.rs b/tests/disk_list.rs
index 0e857ac..bae256e 100644
--- a/tests/disk_list.rs
+++ b/tests/disk_list.rs
@@ -2,9 +2,7 @@
 
 #[test]
 fn test_disks() {
-    use sysinfo::SystemExt;
-
-    if sysinfo::System::IS_SUPPORTED {
+    if sysinfo::IS_SUPPORTED {
         let s = sysinfo::System::new_all();
         // If we don't have any physical core present, it's very likely that we're inside a VM...
         if s.physical_core_count().unwrap_or_default() > 0 {
diff --git a/tests/network.rs b/tests/network.rs
index d1df092..0b01ac9 100644
--- a/tests/network.rs
+++ b/tests/network.rs
@@ -4,9 +4,9 @@
 
 #[test]
 fn test_networks() {
-    use sysinfo::{Networks, NetworksExt, SystemExt};
+    use sysinfo::{Networks, NetworksExt};
 
-    if sysinfo::System::IS_SUPPORTED {
+    if sysinfo::IS_SUPPORTED {
         let mut n = Networks::new();
         assert_eq!(n.iter().count(), 0);
         n.refresh();
diff --git a/tests/process.rs b/tests/process.rs
index 71aa42c..2e0cd60 100644
--- a/tests/process.rs
+++ b/tests/process.rs
@@ -1,13 +1,13 @@
 // Take a look at the license at the top of the repository in the LICENSE file.
 
-use sysinfo::{Pid, PidExt, ProcessExt, SystemExt};
+use sysinfo::{Pid, PidExt, ProcessExt};
 
 #[test]
 fn test_process() {
     let mut s = sysinfo::System::new();
     assert_eq!(s.processes().len(), 0);
     s.refresh_processes();
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     assert!(!s.processes().is_empty());
@@ -19,7 +19,7 @@ fn test_process() {
 
 #[test]
 fn test_cwd() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     let mut p = if cfg!(target_os = "windows") {
@@ -57,7 +57,7 @@ fn test_cwd() {
 
 #[test]
 fn test_cmd() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     let mut p = if cfg!(target_os = "windows") {
@@ -97,7 +97,7 @@ fn test_cmd() {
 
 #[test]
 fn test_environ() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     let mut p = if cfg!(target_os = "windows") {
@@ -145,7 +145,7 @@ fn test_environ() {
 // More information in <https://github.com/GuillaumeGomez/sysinfo/issues/886>.
 #[test]
 fn test_big_environ() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     const SIZE: usize = 30_000;
@@ -197,7 +197,7 @@ fn test_process_refresh() {
     let mut s = sysinfo::System::new();
     assert_eq!(s.processes().len(), 0);
 
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     s.refresh_process(sysinfo::get_current_pid().expect("failed to get current pid"));
@@ -211,9 +211,9 @@ fn test_process_disk_usage() {
     use std::fs;
     use std::fs::File;
     use std::io::prelude::*;
-    use sysinfo::{get_current_pid, ProcessExt, SystemExt};
+    use sysinfo::{get_current_pid, ProcessExt};
 
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     if std::env::var("FREEBSD_CI").is_ok() {
@@ -271,7 +271,7 @@ fn cpu_usage_is_not_nan() {
     let mut system = sysinfo::System::new();
     system.refresh_processes();
 
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
 
@@ -299,7 +299,7 @@ fn cpu_usage_is_not_nan() {
 fn test_process_times() {
     use std::time::{SystemTime, UNIX_EPOCH};
 
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     let mut p = if cfg!(target_os = "windows") {
@@ -347,7 +347,7 @@ fn test_process_times() {
 // Checks that `session_id` is working.
 #[test]
 fn test_process_session_id() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     let mut s = sysinfo::System::new();
@@ -358,7 +358,7 @@ fn test_process_session_id() {
 // Checks that `refresh_processes` is removing dead processes.
 #[test]
 fn test_refresh_processes() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     let mut p = if cfg!(target_os = "windows") {
@@ -406,7 +406,7 @@ fn test_refresh_processes() {
     not(feature = "unknown-ci")
 ))]
 fn test_refresh_tasks() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     let task_name = "task_1_second";
@@ -446,7 +446,7 @@ fn test_refresh_tasks() {
 // Checks that `refresh_process` is NOT removing dead processes.
 #[test]
 fn test_refresh_process() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     let mut p = if cfg!(target_os = "windows") {
@@ -489,7 +489,7 @@ fn test_refresh_process() {
 
 #[test]
 fn test_wait_child() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
     let p = if cfg!(target_os = "windows") {
@@ -527,7 +527,7 @@ fn test_wait_child() {
 
 #[test]
 fn test_wait_non_child() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
 
@@ -572,7 +572,7 @@ fn test_wait_non_child() {
 
 #[test]
 fn test_process_iterator_lifetimes() {
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
 
@@ -599,14 +599,14 @@ fn test_process_iterator_lifetimes() {
 // Regression test for <https://github.com/GuillaumeGomez/sysinfo/issues/918>.
 #[test]
 fn test_process_cpu_usage() {
-    use sysinfo::{ProcessExt, System, SystemExt};
+    use sysinfo::{ProcessExt, System};
 
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
 
     let mut sys = System::new_all();
-    std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL);
+    std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
     sys.refresh_all();
 
     let max_usage = sys.cpus().len() as f32 * 100.;
@@ -618,9 +618,9 @@ fn test_process_cpu_usage() {
 
 #[test]
 fn test_process_creds() {
-    use sysinfo::{ProcessExt, System, SystemExt};
+    use sysinfo::{ProcessExt, System};
 
-    if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+    if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
         return;
     }
 
diff --git a/tests/uptime.rs b/tests/uptime.rs
index d5eae73..388feca 100644
--- a/tests/uptime.rs
+++ b/tests/uptime.rs
@@ -2,9 +2,7 @@
 
 #[test]
 fn test_uptime() {
-    use sysinfo::SystemExt;
-
-    if sysinfo::System::IS_SUPPORTED {
+    if sysinfo::IS_SUPPORTED {
         let mut s = sysinfo::System::new();
         s.refresh_all();
         assert!(s.uptime() != 0);