Repository: GuillaumeGomez/sysinfo
Pull request #255 (2020-02-07 15:25:39)

Processor


Patch:
diff --git a/README.md b/README.md
index ed38223..528b0f4 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ println!("total swap  : {} KiB", sys.get_total_swap());
 println!("used swap   : {} KiB", sys.get_used_swap());
 
 // Number of processors
-println!("NB processors: {}", sys.get_processor_list().len());
+println!("NB processors: {}", sys.get_processors().len());
 
 // To refresh all system information:
 sys.refresh_all();
diff --git a/examples/src/simple.rs b/examples/src/simple.rs
index 9bc94d4..a28ce21 100644
--- a/examples/src/simple.rs
+++ b/examples/src/simple.rs
@@ -79,7 +79,7 @@ fn print_help() {
     );
     writeln!(
         &mut io::stdout(),
-        "procd              : Displays processors state"
+        "processors         : Displays processors state"
     );
     writeln!(
         &mut io::stdout(),
@@ -140,17 +140,15 @@ fn interpret_input(input: &str, sys: &mut System) -> bool {
                 nb += 1;
             }
         }
-        "procs" => {
+        "processors" => {
             // Note: you should refresh a few times before using this, so that usage statistics
             // can be ascertained
-            let procs = sys.get_processor_list();
-
             writeln!(
                 &mut io::stdout(),
                 "total process usage: {}%",
-                procs[0].get_cpu_usage()
+                sys.get_global_processor_info().get_cpu_usage()
             );
-            for proc_ in procs.iter().skip(1) {
+            for proc_ in sys.get_processors() {
                 writeln!(&mut io::stdout(), "{:?}", proc_);
             }
         }
@@ -178,7 +176,7 @@ fn interpret_input(input: &str, sys: &mut System) -> bool {
         }
         "quit" | "exit" => return true,
         "all" => {
-            for (pid, proc_) in sys.get_process_list() {
+            for (pid, proc_) in sys.get_processes() {
                 writeln!(
                     &mut io::stdout(),
                     "{}:{} status={:?}",
@@ -189,26 +187,24 @@ fn interpret_input(input: &str, sys: &mut System) -> bool {
             }
         }
         "frequency" => {
-            let procs = sys.get_processor_list();
-            // On windows, the first processor is the "all processors", so not interesting in here.
             writeln!(
                 &mut io::stdout(),
                 "{} MHz",
-                procs[if procs.len() > 1 { 1 } else { 0 }].get_frequency()
+                sys.get_processors()[0].get_frequency()
             );
         }
         "vendor_id" => {
             writeln!(
                 &mut io::stdout(),
                 "vendor ID: {}",
-                sys.get_processor_list()[0].get_vendor_id()
+                sys.get_processors()[0].get_vendor_id()
             );
         }
         "brand" => {
             writeln!(
                 &mut io::stdout(),
                 "brand: {}",
-                sys.get_processor_list()[0].get_brand()
+                sys.get_processors()[0].get_brand()
             );
         }
         "load_avg" => {
diff --git a/src/c_interface.rs b/src/c_interface.rs
index 0d9c148..78ac3d6 100644
--- a/src/c_interface.rs
+++ b/src/c_interface.rs
@@ -15,7 +15,7 @@ pub type CSystem = *mut c_void;
 pub type CProcess = *const c_void;
 /// C string returned from `CString::into_raw`.
 pub type RString = *const c_char;
-/// Callback used by [`get_process_list`][crate::System#method.get_process_list].
+/// Callback used by [`get_processes`][crate::System#method.get_processes].
 pub type ProcessLoop = extern "C" fn(pid: pid_t, process: CProcess, data: *mut c_void) -> bool;
 
 /// Equivalent of [`System::new()`][crate::System#method.new].
@@ -247,7 +247,7 @@ pub extern "C" fn sysinfo_get_processors_usage(
     }
     let system: Box<System> = unsafe { Box::from_raw(system as *mut System) };
     {
-        let processors = system.get_processor_list();
+        let processors = system.get_processors();
         unsafe {
             if (*procs).is_null() {
                 (*procs) = libc::malloc(::std::mem::size_of::<c_float>() * processors.len())
@@ -262,7 +262,7 @@ pub extern "C" fn sysinfo_get_processors_usage(
     Box::into_raw(system);
 }
 
-/// Equivalent of [`System::get_process_list()`][crate::System#method.get_process_list]. Returns an
+/// Equivalent of [`System::get_processes()`][crate::System#method.get_processes]. Returns an
 /// array ended by a null pointer. Must be freed.
 ///
 /// # /!\ WARNING /!\
@@ -278,7 +278,7 @@ pub extern "C" fn sysinfo_get_processes(
     if let Some(fn_pointer) = fn_pointer {
         let system: Box<System> = unsafe { Box::from_raw(system as *mut System) };
         let len = {
-            let entries = system.get_process_list();
+            let entries = system.get_processes();
             for (pid, process) in entries {
                 if !fn_pointer(*pid, process as *const Process as CProcess, data) {
                     break;
diff --git a/src/common.rs b/src/common.rs
index b7c3215..32479da 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -112,7 +112,7 @@ assert_eq!(r.", stringify!($name), "(), false);
 /// let mut system = System::new_with_specifics(RefreshKind::everything().without_disks_list());
 ///
 /// assert_eq!(system.get_disks().len(), 0);
-/// assert!(system.get_process_list().len() > 0);
+/// assert!(system.get_processes().len() > 0);
 /// ```
 ///
 /// [`System`]: crate::System
@@ -204,7 +204,11 @@ impl RefreshKind {
     impl_get_set!(memory, with_memory, without_memory);
     impl_get_set!(cpu, with_cpu, without_cpu);
     impl_get_set!(components, with_components, without_components);
-    impl_get_set!(components_list, with_components_list, without_components_list);
+    impl_get_set!(
+        components_list,
+        with_components_list,
+        without_components_list
+    );
 }
 
 /// Iterator over network interfaces.
diff --git a/src/linux/processor.rs b/src/linux/processor.rs
index 8e79ba8..df2027d 100644
--- a/src/linux/processor.rs
+++ b/src/linux/processor.rs
@@ -124,13 +124,13 @@ impl CpuValues {
 pub struct Processor {
     old_values: CpuValues,
     new_values: CpuValues,
-    name: String,
+    pub(crate) name: String,
     cpu_usage: f32,
     total_time: u64,
     old_total_time: u64,
     frequency: u64,
-    vendor_id: String,
-    brand: String,
+    pub(crate) vendor_id: String,
+    pub(crate) brand: String,
 }
 
 impl Processor {
@@ -194,7 +194,8 @@ impl Processor {
             user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice,
         );
         self.cpu_usage = min(self.new_values.work_time(), self.old_values.work_time())
-            / min(self.new_values.total_time(), self.old_values.total_time());
+            / min(self.new_values.total_time(), self.old_values.total_time())
+            * 100.;
         self.old_total_time = self.old_values.total_time();
         self.total_time = self.new_values.total_time();
     }
diff --git a/src/linux/system.rs b/src/linux/system.rs
index 1dd0041..392ba60 100644
--- a/src/linux/system.rs
+++ b/src/linux/system.rs
@@ -103,6 +103,7 @@ pub struct System {
     mem_free: u64,
     swap_total: u64,
     swap_free: u64,
+    global_processor: Processor,
     processors: Vec<Processor>,
     page_size_kb: u64,
     components: Vec<Component>,
@@ -114,16 +115,15 @@ pub struct System {
 impl System {
     fn clear_procs(&mut self) {
         if !self.processors.is_empty() {
-            let (new, old) = get_raw_times(&self.processors[0]);
+            let (new, old) = get_raw_times(&self.global_processor);
             let total_time = (if old > new { 1 } else { new - old }) as f32;
             let mut to_delete = Vec::with_capacity(20);
-            let nb_processors = self.processors.len() as u64 - 1;
 
             for (pid, proc_) in &mut self.process_list.tasks {
                 if !has_been_updated(proc_) {
                     to_delete.push(*pid);
                 } else {
-                    compute_cpu_usage(proc_, nb_processors, total_time);
+                    compute_cpu_usage(proc_, self.processors.len() as u64, total_time);
                 }
             }
             for pid in to_delete {
@@ -133,65 +133,46 @@ impl System {
     }
 
     fn refresh_processors(&mut self, limit: Option<u32>) {
-        fn get_callbacks(
-            first: bool,
-        ) -> Box<dyn Fn(&mut dyn Iterator<Item = &[u8]>, &mut Vec<Processor>, &mut usize)> {
-            if first {
-                let frequency = get_cpu_frequency();
-                let (vendor_id, brand) = get_vendor_id_and_brand();
-                Box::new(
-                    move |parts: &mut dyn Iterator<Item = &[u8]>,
-                          processors: &mut Vec<Processor>,
-                          _| {
-                        processors.push(Processor::new_with_values(
-                            to_str!(parts.next().unwrap_or(&[])),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            frequency,
-                            vendor_id.clone(),
-                            brand.clone(),
-                        ));
-                    },
-                )
-            } else {
-                Box::new(
-                    |parts: &mut dyn Iterator<Item = &[u8]>,
-                     processors: &mut Vec<Processor>,
-                     i: &mut usize| {
-                        parts.next(); // we don't want the name again
-                        processors[*i].set(
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                            parts.next().map(|v| to_u64(v)).unwrap_or(0),
-                        );
-                        *i += 1;
-                    },
-                )
-            }
-        }
         if let Ok(f) = File::open("/proc/stat") {
             let buf = BufReader::new(f);
             let mut i = 0;
             let first = self.processors.is_empty();
             let mut it = buf.split(b'\n');
             let mut count = 0;
-            let callback = get_callbacks(first);
+            let frequency = if first { get_cpu_frequency() } else { 0 };
+            let (vendor_id, brand) = if first {
+                get_vendor_id_and_brand()
+            } else {
+                (String::new(), String::new())
+            };
 
+            if let Some(Ok(line)) = it.next() {
+                if &line[..3] != b"cpu" {
+                    return;
+                }
+                count += 1;
+                let mut parts = line.split(|x| *x == b' ').filter(|s| !s.is_empty());
+                if first {
+                    self.global_processor.name = to_str!(parts.next().unwrap_or(&[])).to_owned();
+                }
+                self.global_processor.set(
+                    parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                    parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                    parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                    parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                    parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                    parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                    parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                    parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                    parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                    parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                );
+                if let Some(limit) = limit {
+                    if count >= limit {
+                        return;
+                    }
+                }
+            }
             while let Some(Ok(line)) = it.next() {
                 if &line[..3] != b"cpu" {
                     break;
@@ -199,13 +180,49 @@ impl System {
 
                 count += 1;
                 let mut parts = line.split(|x| *x == b' ').filter(|s| !s.is_empty());
-                callback(&mut parts, &mut self.processors, &mut i);
+                if first {
+                    self.processors.push(Processor::new_with_values(
+                        to_str!(parts.next().unwrap_or(&[])),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        frequency,
+                        vendor_id.clone(),
+                        brand.clone(),
+                    ));
+                } else {
+                    parts.next(); // we don't want the name again
+                    self.processors[i].set(
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                        parts.next().map(|v| to_u64(v)).unwrap_or(0),
+                    );
+                    i += 1;
+                }
                 if let Some(limit) = limit {
                     if count >= limit {
                         break;
                     }
                 }
             }
+            if first {
+                self.global_processor.vendor_id = vendor_id;
+                self.global_processor.brand = brand;
+            }
         }
     }
 }
@@ -218,6 +235,22 @@ impl SystemExt for System {
             mem_free: 0,
             swap_total: 0,
             swap_free: 0,
+            global_processor: Processor::new_with_values(
+                "",
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                String::new(),
+                String::new(),
+            ),
             processors: Vec::with_capacity(4),
             page_size_kb: unsafe { sysconf(_SC_PAGESIZE) as u64 / 1024 },
             components: Vec::new(),
@@ -225,6 +258,9 @@ impl SystemExt for System {
             networks: Networks::new(),
             uptime: get_uptime(),
         };
+        if !refreshes.cpu() {
+            s.refresh_processors(None); // We need the processors to be filled.
+        }
         s.refresh_specifics(refreshes);
         s
     }
@@ -291,12 +327,11 @@ impl SystemExt for System {
         };
         if found && !self.processors.is_empty() {
             self.refresh_processors(Some(1));
-            let (new, old) = get_raw_times(&self.processors[0]);
+            let (new, old) = get_raw_times(&self.global_processor);
             let total_time = (if old > new { 1 } else { new - old }) as f32;
-            let nb_processors = self.processors.len() as u64 - 1;
 
             if let Some(p) = self.process_list.tasks.get_mut(&pid) {
-                compute_cpu_usage(p, nb_processors, total_time);
+                compute_cpu_usage(p, self.processors.len() as u64, total_time);
             }
         }
         found
@@ -310,7 +345,7 @@ impl SystemExt for System {
     //
     // Need to be moved into a "common" file to avoid duplication.
 
-    fn get_process_list(&self) -> &HashMap<Pid, Process> {
+    fn get_processes(&self) -> &HashMap<Pid, Process> {
         &self.process_list.tasks
     }
 
@@ -326,8 +361,12 @@ impl SystemExt for System {
         &mut self.networks
     }
 
-    fn get_processor_list(&self) -> &[Processor] {
-        &self.processors[..]
+    fn get_global_processor_info(&self) -> &Processor {
+        &self.global_processor
+    }
+
+    fn get_processors(&self) -> &[Processor] {
+        &self.processors
     }
 
     fn get_total_memory(&self) -> u64 {
diff --git a/src/mac/component.rs b/src/mac/component.rs
index 52d953c..56db664 100644
--- a/src/mac/component.rs
+++ b/src/mac/component.rs
@@ -55,14 +55,16 @@ impl Component {
         connection: ffi::io_connect_t,
     ) -> Option<Component> {
         let ffi_part = ComponentFFI::new(key, connection)?;
-        ffi_part.get_temperature(connection).map(|temperature| Component {
-            temperature,
-            label,
-            max: max.unwrap_or(0.0),
-            critical,
-            ffi_part,
-            connection,
-        })
+        ffi_part
+            .get_temperature(connection)
+            .map(|temperature| Component {
+                temperature,
+                label,
+                max: max.unwrap_or(0.0),
+                critical,
+                ffi_part,
+                connection,
+            })
     }
 }
 
diff --git a/src/mac/processor.rs b/src/mac/processor.rs
index 78db8d0..b325751 100644
--- a/src/mac/processor.rs
+++ b/src/mac/processor.rs
@@ -4,10 +4,12 @@
 // Copyright (c) 2015 Guillaume Gomez
 //
 
-use libc::c_char;
+use libc::{c_char, c_void};
+use std::mem;
 use std::ops::Deref;
 use std::sync::Arc;
 use sys::ffi;
+use sys::system::get_sys_value;
 
 use ProcessorExt;
 
@@ -130,6 +132,74 @@ pub fn get_cpu_frequency() -> u64 {
     speed / 1_000_000
 }
 
+pub fn init_processors(port: ffi::mach_port_t) -> (Processor, Vec<Processor>) {
+    let mut num_cpu = 0;
+    let mut processors = Vec::new();
+    let mut pourcent = 0f32;
+    let mut mib = [0, 0];
+
+    let (vendor_id, brand) = get_vendor_id_and_brand();
+    let frequency = get_cpu_frequency();
+
+    unsafe {
+        if !get_sys_value(
+            ffi::CTL_HW,
+            ffi::HW_NCPU,
+            mem::size_of::<u32>(),
+            &mut num_cpu as *mut usize as *mut c_void,
+            &mut mib,
+        ) {
+            num_cpu = 1;
+        }
+
+        let mut num_cpu_u = 0u32;
+        let mut cpu_info: *mut i32 = ::std::ptr::null_mut();
+        let mut num_cpu_info = 0u32;
+
+        if ffi::host_processor_info(
+            port,
+            ffi::PROCESSOR_CPU_LOAD_INFO,
+            &mut num_cpu_u as *mut u32,
+            &mut cpu_info as *mut *mut i32,
+            &mut num_cpu_info as *mut u32,
+        ) == ffi::KERN_SUCCESS
+        {
+            let proc_data = Arc::new(ProcessorData::new(cpu_info, num_cpu_info));
+            for i in 0..num_cpu {
+                let mut p = Processor::new(
+                    format!("{}", i + 1),
+                    Arc::clone(&proc_data),
+                    frequency,
+                    vendor_id.clone(),
+                    brand.clone(),
+                );
+                let in_use = *cpu_info
+                    .offset((ffi::CPU_STATE_MAX * i) as isize + ffi::CPU_STATE_USER as isize)
+                    + *cpu_info
+                        .offset((ffi::CPU_STATE_MAX * i) as isize + ffi::CPU_STATE_SYSTEM as isize)
+                    + *cpu_info
+                        .offset((ffi::CPU_STATE_MAX * i) as isize + ffi::CPU_STATE_NICE as isize);
+                let total = in_use
+                    + *cpu_info
+                        .offset((ffi::CPU_STATE_MAX * i) as isize + ffi::CPU_STATE_IDLE as isize);
+                p.set_cpu_usage(in_use as f32 / total as f32 * 100.);
+                pourcent += p.get_cpu_usage();
+                processors.push(p);
+            }
+        }
+    }
+    let mut global_processor = Processor::new(
+        "0".to_owned(),
+        Arc::new(ProcessorData::new(::std::ptr::null_mut(), 0)),
+        frequency,
+        vendor_id,
+        brand,
+    );
+    global_processor.set_cpu_usage(pourcent / processors.len() as f32);
+
+    (global_processor, processors)
+}
+
 fn get_sysctl_str(s: &[u8]) -> String {
     let mut len = 0;
 
diff --git a/src/mac/system.rs b/src/mac/system.rs
index 36a1792..a5b8559 100644
--- a/src/mac/system.rs
+++ b/src/mac/system.rs
@@ -29,6 +29,7 @@ pub struct System {
     mem_free: u64,
     swap_total: u64,
     swap_free: u64,
+    global_processor: Processor,
     processors: Vec<Processor>,
     page_size_kb: u64,
     components: Vec<Component>,
@@ -71,20 +72,24 @@ impl System {
 
 impl SystemExt for System {
     fn new_with_specifics(refreshes: RefreshKind) -> System {
+        let port = unsafe { ffi::mach_host_self() };
+        let (global_processor, processors) = init_processors(port);
+
         let mut s = System {
             process_list: HashMap::with_capacity(200),
             mem_total: 0,
             mem_free: 0,
             swap_total: 0,
             swap_free: 0,
-            processors: Vec::with_capacity(4),
+            global_processor,
+            processors,
             page_size_kb: unsafe { sysconf(_SC_PAGESIZE) as u64 >> 10 }, // divide by 1024
             components: Vec::with_capacity(2),
             connection: get_io_service_connection(),
             disks: Vec::with_capacity(1),
             networks: Networks::new(),
             uptime: get_uptime(),
-            port: unsafe { ffi::mach_host_self() },
+            port,
         };
         s.refresh_specifics(refreshes);
         s
@@ -168,68 +173,15 @@ impl SystemExt for System {
     fn refresh_cpu(&mut self) {
         self.uptime = get_uptime();
 
-        let mut mib = [0, 0];
-        unsafe {
-            // get processor values
-            let mut num_cpu_u = 0u32;
-            let mut cpu_info: *mut i32 = ::std::ptr::null_mut();
-            let mut num_cpu_info = 0u32;
-
-            if self.processors.is_empty() {
-                let mut num_cpu = 0;
-                let (vendor_id, brand) = get_vendor_id_and_brand();
-                let frequency = get_cpu_frequency();
+        // get processor values
+        let mut num_cpu_u = 0u32;
+        let mut cpu_info: *mut i32 = ::std::ptr::null_mut();
+        let mut num_cpu_info = 0u32;
 
-                if !get_sys_value(
-                    ffi::CTL_HW,
-                    ffi::HW_NCPU,
-                    mem::size_of::<u32>(),
-                    &mut num_cpu as *mut usize as *mut c_void,
-                    &mut mib,
-                ) {
-                    num_cpu = 1;
-                }
+        let mut pourcent = 0f32;
 
-                self.processors.push(Processor::new(
-                    "0".to_owned(),
-                    Arc::new(ProcessorData::new(::std::ptr::null_mut(), 0)),
-                    frequency,
-                    vendor_id.clone(),
-                    brand.clone(),
-                ));
-                if ffi::host_processor_info(
-                    self.port,
-                    ffi::PROCESSOR_CPU_LOAD_INFO,
-                    &mut num_cpu_u as *mut u32,
-                    &mut cpu_info as *mut *mut i32,
-                    &mut num_cpu_info as *mut u32,
-                ) == ffi::KERN_SUCCESS
-                {
-                    let proc_data = Arc::new(ProcessorData::new(cpu_info, num_cpu_info));
-                    for i in 0..num_cpu {
-                        let mut p = Processor::new(
-                            format!("{}", i + 1),
-                            Arc::clone(&proc_data),
-                            frequency,
-                            vendor_id.clone(),
-                            brand.clone(),
-                        );
-                        let in_use = *cpu_info.offset(
-                            (ffi::CPU_STATE_MAX * i) as isize + ffi::CPU_STATE_USER as isize,
-                        ) + *cpu_info.offset(
-                            (ffi::CPU_STATE_MAX * i) as isize + ffi::CPU_STATE_SYSTEM as isize,
-                        ) + *cpu_info.offset(
-                            (ffi::CPU_STATE_MAX * i) as isize + ffi::CPU_STATE_NICE as isize,
-                        );
-                        let total = in_use
-                            + *cpu_info.offset(
-                                (ffi::CPU_STATE_MAX * i) as isize + ffi::CPU_STATE_IDLE as isize,
-                            );
-                        p.set_cpu_usage(in_use as f32 / total as f32);
-                        self.processors.push(p);
-                    }
-                }
-            } else if ffi::host_processor_info(
+        unsafe {
+            if ffi::host_processor_info(
                 self.port,
                 ffi::PROCESSOR_CPU_LOAD_INFO,
                 &mut num_cpu_u as *mut u32,
@@ -237,9 +189,8 @@ impl SystemExt for System {
                 &mut num_cpu_info as *mut u32,
             ) == ffi::KERN_SUCCESS
             {
-                let mut pourcent = 0f32;
                 let proc_data = Arc::new(ProcessorData::new(cpu_info, num_cpu_info));
-                for (i, proc_) in self.processors.iter_mut().skip(1).enumerate() {
+                for (i, proc_) in self.processors.iter_mut().enumerate() {
                     let old_proc_data = &*proc_.get_data();
                     let in_use =
                         (*cpu_info.offset(
@@ -261,17 +212,13 @@ impl SystemExt for System {
                         ) - *old_proc_data.cpu_info.offset(
                             (ffi::CPU_STATE_MAX * i) as isize + ffi::CPU_STATE_IDLE as isize,
                         ));
-                    proc_.update(in_use as f32 / total as f32, Arc::clone(&proc_data));
+                    proc_.update(in_use as f32 / total as f32 * 100., Arc::clone(&proc_data));
                     pourcent += proc_.get_cpu_usage();
                 }
-                if self.processors.len() > 1 {
-                    let len = self.processors.len() - 1;
-                    if let Some(p) = self.processors.get_mut(0) {
-                        p.set_cpu_usage(pourcent / len as f32);
-                    }
-                }
             }
         }
+        self.global_processor
+            .set_cpu_usage(pourcent / self.processors.len() as f32);
     }
 
     fn refresh_processes(&mut self) {
@@ -320,7 +267,7 @@ impl SystemExt for System {
     //
     // Need to be moved into a "common" file to avoid duplication.
 
-    fn get_process_list(&self) -> &HashMap<Pid, Process> {
+    fn get_processes(&self) -> &HashMap<Pid, Process> {
         &self.process_list
     }
 
@@ -328,8 +275,12 @@ impl SystemExt for System {
         self.process_list.get(&pid)
     }
 
-    fn get_processor_list(&self) -> &[Processor] {
-        &self.processors[..]
+    fn get_global_processor_info(&self) -> &Processor {
+        &self.global_processor
+    }
+
+    fn get_processors(&self) -> &[Processor] {
+        &self.processors
     }
 
     fn get_networks(&self) -> &Networks {
@@ -483,7 +434,7 @@ fn get_arg_max() -> usize {
     }
 }
 
-unsafe fn get_sys_value(
+pub(crate) unsafe fn get_sys_value(
     high: u32,
     low: u32,
     mut len: usize,
diff --git a/src/sysinfo.rs b/src/sysinfo.rs
index 2181971..a5a280d 100644
--- a/src/sysinfo.rs
+++ b/src/sysinfo.rs
@@ -20,7 +20,7 @@
 //! system.refresh_all();
 //!
 //! // Now let's print every process' id and name:
-//! for (pid, proc_) in system.get_process_list() {
+//! for (pid, proc_) in system.get_processes() {
 //!     println!("{}:{} => status: {:?}", pid, proc_.name(), proc_.status());
 //! }
 //!
@@ -80,9 +80,7 @@ cfg_if! {
 }
 
 pub use common::{AsU32, DiskType, NetworksIter, Pid, RefreshKind};
-pub use sys::{
-    Component, Disk, NetworkData, Networks, Process, ProcessStatus, Processor, System,
-};
+pub use sys::{Component, Disk, NetworkData, Networks, Process, ProcessStatus, Processor, System};
 pub use traits::{
     ComponentExt, DiskExt, NetworkExt, NetworksExt, ProcessExt, ProcessorExt, SystemExt,
 };
@@ -232,7 +230,7 @@ mod test {
 
         s.refresh_all();
         assert_eq!(
-            s.get_process_list()
+            s.get_processes()
                 .iter()
                 .all(|(_, proc_)| proc_.memory() == 0),
             false
diff --git a/src/system.rs b/src/system.rs
index dd848ed..27f7682 100644
--- a/src/system.rs
+++ b/src/system.rs
@@ -26,7 +26,7 @@ mod tests {
     fn test_refresh_process() {
         let mut sys = System::new();
         assert!(
-            sys.get_process_list().is_empty(),
+            sys.get_processes().is_empty(),
             "no process should be listed!"
         );
         sys.refresh_processes();
diff --git a/src/traits.rs b/src/traits.rs
index 3c2637c..b1dfdd5 100644
--- a/src/traits.rs
+++ b/src/traits.rs
@@ -308,7 +308,7 @@ pub trait ProcessorExt {
     /// use sysinfo::{ProcessorExt, System, SystemExt};
     ///
     /// let s = System::new();
-    /// for processor in s.get_processor_list() {
+    /// for processor in s.get_processors() {
     ///     println!("{}%", processor.get_cpu_usage());
     /// }
     /// ```
@@ -320,7 +320,7 @@ pub trait ProcessorExt {
     /// use sysinfo::{ProcessorExt, System, SystemExt};
     ///
     /// let s = System::new();
-    /// for processor in s.get_processor_list() {
+    /// for processor in s.get_processors() {
     ///     println!("{}", processor.get_name());
     /// }
     /// ```
@@ -332,7 +332,7 @@ pub trait ProcessorExt {
     /// use sysinfo::{ProcessorExt, System, SystemExt};
     ///
     /// let s = System::new();
-    /// for processor in s.get_processor_list() {
+    /// for processor in s.get_processors() {
     ///     println!("{}", processor.get_vendor_id());
     /// }
     /// ```
@@ -344,7 +344,7 @@ pub trait ProcessorExt {
     /// use sysinfo::{ProcessorExt, System, SystemExt};
     ///
     /// let s = System::new();
-    /// for processor in s.get_processor_list() {
+    /// for processor in s.get_processors() {
     ///     println!("{}", processor.get_brand());
     /// }
     /// ```
@@ -356,7 +356,7 @@ pub trait ProcessorExt {
     /// use sysinfo::{ProcessorExt, System, SystemExt};
     ///
     /// let s = System::new();
-    /// for processor in s.get_processor_list() {
+    /// for processor in s.get_processors() {
     ///     println!("{}", processor.get_frequency());
     /// }
     /// ```
@@ -365,9 +365,9 @@ pub trait ProcessorExt {
 
 /// Contains all the methods of the [`System`][crate::System] type.
 pub trait SystemExt: Sized {
-    /// Creates a new [`System`] instance with nothing loaded. If you want to load components,
-    /// network interfaces or the disks, you'll have to use the `refresh_*_list` methods.
-    /// [`SystemExt::refresh_networks_list`] for example.
+    /// Creates a new [`System`] instance with nothing loaded except the processors list. If you
+    /// want to load components, network interfaces or the disks, you'll have to use the
+    /// `refresh_*_list` methods. [`SystemExt::refresh_networks_list`] for example.
     ///
     /// Use the [`refresh_all`] method to update its internal information (or any of the `refresh_`
     /// method).
@@ -413,7 +413,7 @@ pub trait SystemExt: Sized {
     /// let mut system = System::new_with_specifics(RefreshKind::everything().without_disks_list());
     ///
     /// assert_eq!(system.get_disks().len(), 0);
-    /// assert!(system.get_process_list().len() > 0);
+    /// assert!(system.get_processes().len() > 0);
     ///
     /// // If you want the disks list afterwards, just call the corresponding
     /// // "refresh_disks_list":
@@ -641,11 +641,11 @@ pub trait SystemExt: Sized {
     /// use sysinfo::{ProcessExt, System, SystemExt};
     ///
     /// let s = System::new_all();
-    /// for (pid, process) in s.get_process_list() {
+    /// for (pid, process) in s.get_processes() {
     ///     println!("{} {}", pid, process.name());
     /// }
     /// ```
-    fn get_process_list(&self) -> &HashMap<Pid, Process>;
+    fn get_processes(&self) -> &HashMap<Pid, Process>;
 
     /// Returns the process corresponding to the given pid or `None` if no such process exists.
     ///
@@ -671,7 +671,7 @@ pub trait SystemExt: Sized {
     /// ```
     fn get_process_by_name(&self, name: &str) -> Vec<&Process> {
         let mut ret = vec![];
-        for val in self.get_process_list().values() {
+        for val in self.get_processes().values() {
             if val.name().contains(name) {
                 ret.push(val);
             }
@@ -679,17 +679,27 @@ pub trait SystemExt: Sized {
         ret
     }
 
-    /// The first processor in the array is the "main" one (aka the addition of all the others).
+    /// Returns "global" processors information (aka the addition of all the processors).
     ///
     /// ```no_run
     /// use sysinfo::{ProcessorExt, System, SystemExt};
     ///
-    /// let s = System::new_all();
-    /// for processor in s.get_processor_list() {
+    /// let s = System::new();
+    /// println!("{}%", s.get_global_processor_info().get_cpu_usage());
+    /// ```
+    fn get_global_processor_info(&self) -> &Processor;
+
+    /// Returns the list of the processors.
+    ///
+    /// ```no_run
+    /// use sysinfo::{ProcessorExt, System, SystemExt};
+    ///
+    /// let s = System::new();
+    /// for processor in s.get_processors() {
     ///     println!("{}%", processor.get_cpu_usage());
     /// }
     /// ```
-    fn get_processor_list(&self) -> &[Processor];
+    fn get_processors(&self) -> &[Processor];
 
     /// Returns total RAM size in KiB.
     ///
diff --git a/src/unknown/processor.rs b/src/unknown/processor.rs
index dab8d59..5fd8ecd 100644
--- a/src/unknown/processor.rs
+++ b/src/unknown/processor.rs
@@ -12,6 +12,12 @@ use ProcessorExt;
 /// Dummy struct that represents a processor.
 pub struct Processor {}
 
+impl Processor {
+    pub(crate) fn new() -> Processor {
+        Processor {}
+    }
+}
+
 impl ProcessorExt for Processor {
     fn get_cpu_usage(&self) -> f32 {
         0.0
diff --git a/src/unknown/system.rs b/src/unknown/system.rs
index f47cccc..a14ca87 100644
--- a/src/unknown/system.rs
+++ b/src/unknown/system.rs
@@ -19,6 +19,7 @@ use std::collections::HashMap;
 pub struct System {
     processes_list: HashMap<Pid, Process>,
     networks: Networks,
+    global_processor: Processor,
 }
 
 impl SystemExt for System {
@@ -26,6 +27,7 @@ impl SystemExt for System {
         System {
             processes_list: Default::default(),
             networks: Networks::new(),
+            global_processor: Processor::new {},
         }
     }
 
@@ -49,7 +51,7 @@ impl SystemExt for System {
     //
     // Need to be moved into a "common" file to avoid duplication.
 
-    fn get_process_list(&self) -> &HashMap<Pid, Process> {
+    fn get_processes(&self) -> &HashMap<Pid, Process> {
         &self.processes_list
     }
 
@@ -65,7 +67,11 @@ impl SystemExt for System {
         &mut self.networks
     }
 
-    fn get_processor_list(&self) -> &[Processor] {
+    fn get_global_processor_info(&self) -> &Processor {
+        &self.global_processor
+    }
+
+    fn get_processors(&self) -> &[Processor] {
         &[]
     }
 
diff --git a/src/windows/processor.rs b/src/windows/processor.rs
index 42d1758..0833eb6 100644
--- a/src/windows/processor.rs
+++ b/src/windows/processor.rs
@@ -8,7 +8,7 @@ use std::collections::HashMap;
 use std::mem;
 use std::ops::DerefMut;
 use std::ptr::null_mut;
-use std::sync::{Arc, Mutex};
+use std::sync::Mutex;
 
 use windows::tools::KeyHandler;
 use LoadAvg;
@@ -20,9 +20,9 @@ use winapi::shared::minwindef::FALSE;
 use winapi::shared::winerror::ERROR_SUCCESS;
 use winapi::um::handleapi::CloseHandle;
 use winapi::um::pdh::{
-    PdhAddCounterW, PdhAddEnglishCounterA, PdhCloseQuery, PdhCollectQueryDataEx,
-    PdhGetFormattedCounterValue, PdhOpenQueryA, PdhRemoveCounter, PDH_FMT_COUNTERVALUE,
-    PDH_FMT_DOUBLE, PDH_HCOUNTER, PDH_HQUERY,
+    PdhAddCounterW, PdhAddEnglishCounterA, PdhCloseQuery, PdhCollectQueryData,
+    PdhCollectQueryDataEx, PdhGetFormattedCounterValue, PdhOpenQueryA, PdhRemoveCounter,
+    PDH_FMT_COUNTERVALUE, PDH_FMT_DOUBLE, PDH_HCOUNTER, PDH_HQUERY,
 };
 use winapi::um::powerbase::CallNtPowerInformation;
 use winapi::um::synchapi::CreateEventA;
@@ -120,51 +120,10 @@ unsafe fn init_load_avg() -> Mutex<Option<LoadAvg>> {
     }
 }
 
-#[derive(Debug)]
-pub enum CounterValue {
-    Float(f32),
-    Integer(u64),
-}
-
-impl CounterValue {
-    pub fn get_f32(&self) -> f32 {
-        match *self {
-            CounterValue::Float(v) => v,
-            _ => panic!("not a float"),
-        }
-    }
-}
-
-#[allow(dead_code)]
-#[derive(Debug)]
-struct Counter {
-    counter: PDH_HCOUNTER,
-    value: CounterValue,
-    getter: Vec<u16>,
-}
-
-impl Counter {
-    fn new_f32(counter: PDH_HCOUNTER, value: f32, getter: Vec<u16>) -> Counter {
-        Counter {
-            counter: counter,
-            value: CounterValue::Float(value),
-            getter: getter,
-        }
-    }
-
-    fn new_u64(counter: PDH_HCOUNTER, value: u64, getter: Vec<u16>) -> Counter {
-        Counter {
-            counter: counter,
-            value: CounterValue::Integer(value),
-            getter: getter,
-        }
-    }
-}
-
 struct InternalQuery {
     query: PDH_HQUERY,
     event: HANDLE,
-    data: Mutex<HashMap<String, Counter>>,
+    data: HashMap<String, PDH_HCOUNTER>,
 }
 
 unsafe impl Send for InternalQuery {}
@@ -173,10 +132,8 @@ unsafe impl Sync for InternalQuery {}
 impl Drop for InternalQuery {
     fn drop(&mut self) {
         unsafe {
-            if let Ok(ref data) = self.data.lock() {
-                for (_, counter) in data.iter() {
-                    PdhRemoveCounter(counter.counter);
-                }
+            for (_, counter) in self.data.iter() {
+                PdhRemoveCounter(*counter);
             }
 
             if !self.event.is_null() {
@@ -191,7 +148,7 @@ impl Drop for InternalQuery {
 }
 
 pub struct Query {
-    internal: Arc<InternalQuery>,
+    internal: InternalQuery,
 }
 
 impl Query {
@@ -199,19 +156,12 @@ impl Query {
         let mut query = null_mut();
         unsafe {
             if PdhOpenQueryA(null_mut(), 0, &mut query) == ERROR_SUCCESS as i32 {
-                let event =
-                    CreateEventA(null_mut(), FALSE, FALSE, b"some_ev\0".as_ptr() as *const i8);
-                if event.is_null() {
-                    PdhCloseQuery(query);
-                    None
-                } else {
-                    let q = Arc::new(InternalQuery {
-                        query: query,
-                        event: event,
-                        data: Mutex::new(HashMap::new()),
-                    });
-                    Some(Query { internal: q })
-                }
+                let q = InternalQuery {
+                    query,
+                    event: null_mut(),
+                    data: HashMap::new(),
+                };
+                Some(Query { internal: q })
             } else {
                 None
             }
@@ -219,35 +169,38 @@ impl Query {
     }
 
     pub fn get(&self, name: &String) -> Option<f32> {
-        if let Ok(data) = self.internal.data.lock() {
-            if let Some(ref counter) = data.get(name) {
-                return Some(counter.value.get_f32());
+        if let Some(ref counter) = self.internal.data.get(name) {
+            unsafe {
+                let mut display_value: PDH_FMT_COUNTERVALUE =
+                    mem::MaybeUninit::uninit().assume_init();
+                let counter: PDH_HCOUNTER = **counter;
+
+                let ret = PdhGetFormattedCounterValue(
+                    counter,
+                    PDH_FMT_DOUBLE,
+                    null_mut(),
+                    &mut display_value,
+                ) as u32;
+                return if ret == ERROR_SUCCESS as _ {
+                    let data = *display_value.u.doubleValue();
+                    Some(data as f32)
+                } else {
+                    Some(0.)
+                };
             }
         }
         None
     }
 
-    pub fn add_counter(&mut self, name: &String, getter: Vec<u16>, value: CounterValue) -> bool {
-        if let Ok(data) = self.internal.data.lock() {
-            if data.contains_key(name) {
-                return false;
-            }
+    pub fn add_counter(&mut self, name: &String, getter: Vec<u16>) -> bool {
+        if self.internal.data.contains_key(name) {
+            return false;
         }
         unsafe {
             let mut counter: PDH_HCOUNTER = ::std::mem::zeroed();
             let ret = PdhAddCounterW(self.internal.query, getter.as_ptr(), 0, &mut counter);
-            if ret == ERROR_SUCCESS as i32 {
-                self.internal
-                    .data
-                    .lock()
-                    .expect("couldn't add counter...")
-                    .insert(
-                        name.clone(),
-                        match value {
-                            CounterValue::Float(v) => Counter::new_f32(counter, v, getter),
-                            CounterValue::Integer(v) => Counter::new_u64(counter, v, getter),
-                        },
-                    );
+            if ret == ERROR_SUCCESS as _ {
+                self.internal.data.insert(name.clone(), counter);
             } else {
                 eprintln!("failed to add counter '{}': {:x}...", name, ret);
                 return false;
@@ -255,13 +208,20 @@ impl Query {
         }
         true
     }
+
+    pub fn refresh(&self) {
+        unsafe {
+            if PdhCollectQueryData(self.internal.query) != ERROR_SUCCESS as _ {
+                eprintln!("failed to refresh CPU data");
+            }
+        }
+    }
 }
 
 /// Struct containing a processor information.
 pub struct Processor {
     name: String,
     cpu_usage: f32,
-    key_idle: Option<KeyHandler>,
     key_used: Option<KeyHandler>,
     vendor_id: String,
     brand: String,
@@ -300,7 +260,6 @@ impl Processor {
         Processor {
             name: name.to_owned(),
             cpu_usage: 0f32,
-            key_idle: None,
             key_used: None,
             vendor_id,
             brand,
@@ -411,10 +370,6 @@ pub fn get_vendor_id_and_brand(info: &SYSTEM_INFO) -> (String, String) {
     (get_vendor_id_not_great(info), String::new())
 }
 
-pub fn get_key_idle(p: &mut Processor) -> &mut Option<KeyHandler> {
-    &mut p.key_idle
-}
-
 pub fn get_key_used(p: &mut Processor) -> &mut Option<KeyHandler> {
     &mut p.key_used
 }
diff --git a/src/windows/system.rs b/src/windows/system.rs
index ce0de82..137a0cd 100644
--- a/src/windows/system.rs
+++ b/src/windows/system.rs
@@ -23,7 +23,6 @@ use SystemExt;
 use windows::process::{
     compute_cpu_usage, get_handle, get_system_computation_time, update_proc_info, Process,
 };
-use windows::processor::CounterValue;
 use windows::tools::*;
 
 use ntapi::ntexapi::{
@@ -46,6 +45,7 @@ pub struct System {
     mem_free: u64,
     swap_total: u64,
     swap_free: u64,
+    global_processor: Processor,
     processors: Vec<Processor>,
     components: Vec<Component>,
     disks: Vec<Disk>,
@@ -63,13 +63,15 @@ unsafe impl<T> Sync for Wrap<T> {}
 impl SystemExt for System {
     #[allow(non_snake_case)]
     fn new_with_specifics(refreshes: RefreshKind) -> System {
+        let (processors, vendor_id, brand) = init_processors();
         let mut s = System {
             process_list: HashMap::with_capacity(500),
             mem_total: 0,
             mem_free: 0,
             swap_total: 0,
             swap_free: 0,
-            processors: init_processors(),
+            global_processor: Processor::new_with_values("Total CPU", vendor_id, brand, 0),
+            processors,
             components: Vec::new(),
             disks: Vec::with_capacity(2),
             query: Query::new(),
@@ -80,46 +82,28 @@ impl SystemExt for System {
         if let Some(ref mut query) = s.query {
             let x = unsafe { load_symbols() };
             if let Some(processor_trans) = get_translation(&"Processor".to_owned(), &x) {
-                let idle_time_trans = get_translation(&"% Idle Time".to_owned(), &x);
+                // let idle_time_trans = get_translation(&"% Idle Time".to_owned(), &x);
                 let proc_time_trans = get_translation(&"% Processor Time".to_owned(), &x);
                 if let Some(ref proc_time_trans) = proc_time_trans {
                     add_counter(
                         format!("\\{}(_Total)\\{}", processor_trans, proc_time_trans),
                         query,
-                        get_key_used(&mut s.processors[0]),
+                        get_key_used(&mut s.global_processor),
                         "tot_0".to_owned(),
-                        CounterValue::Float(0.),
                     );
                 }
-                if let Some(ref idle_time_trans) = idle_time_trans {
-                    add_counter(
-                        format!("\\{}(_Total)\\{}", processor_trans, idle_time_trans),
-                        query,
-                        get_key_idle(&mut s.processors[0]),
-                        "tot_1".to_owned(),
-                        CounterValue::Float(0.),
-                    );
-                }
-                for (pos, proc_) in s.processors.iter_mut().skip(1).enumerate() {
+                for (pos, proc_) in s.processors.iter_mut().enumerate() {
                     if let Some(ref proc_time_trans) = proc_time_trans {
                         add_counter(
                             format!("\\{}({})\\{}", processor_trans, pos, proc_time_trans),
                             query,
                             get_key_used(proc_),
                             format!("{}_0", pos),
-                            CounterValue::Float(0.),
-                        );
-                    }
-                    if let Some(ref idle_time_trans) = idle_time_trans {
-                        add_counter(
-                            format!("\\{}({})\\{}", processor_trans, pos, idle_time_trans),
-                            query,
-                            get_key_idle(proc_),
-                            format!("{}_1", pos),
-                            CounterValue::Float(0.),
                         );
                     }
                 }
+            } else {
+                eprintln!("failed to get `Processor` translation");
             }
         }
         s.refresh_specifics(refreshes);
@@ -129,13 +113,29 @@ impl SystemExt for System {
     fn refresh_cpu(&mut self) {
         self.uptime = get_uptime();
         if let Some(ref mut query) = self.query {
+            query.refresh();
+            let mut used_time = None;
+            if let &mut Some(ref key_used) = get_key_used(&mut self.global_processor) {
+                used_time = Some(
+                    query
+                        .get(&key_used.unique_id)
+                        .expect("global_key_idle disappeared"),
+                );
+            }
+            if let Some(used_time) = used_time {
+                self.global_processor.set_cpu_usage(used_time);
+            }
             for p in self.processors.iter_mut() {
-                let mut idle_time = None;
-                if let &mut Some(ref key_idle) = get_key_idle(p) {
-                    idle_time = Some(query.get(&key_idle.unique_id).expect("key disappeared"));
+                let mut used_time = None;
+                if let &mut Some(ref key_used) = get_key_used(p) {
+                    used_time = Some(
+                        query
+                            .get(&key_used.unique_id)
+                            .expect("key_used disappeared"),
+                    );
                 }
-                if let Some(idle_time) = idle_time {
-                    p.set_cpu_usage(1. - idle_time);
+                if let Some(used_time) = used_time {
+                    p.set_cpu_usage(used_time);
                 }
             }
         }
@@ -291,7 +291,7 @@ impl SystemExt for System {
         self.disks = unsafe { get_disks() };
     }
 
-    fn get_process_list(&self) -> &HashMap<Pid, Process> {
+    fn get_processes(&self) -> &HashMap<Pid, Process> {
         &self.process_list
     }
 
@@ -299,8 +299,12 @@ impl SystemExt for System {
         self.process_list.get(&(pid as usize))
     }
 
-    fn get_processor_list(&self) -> &[Processor] {
-        &self.processors[..]
+    fn get_global_processor_info(&self) -> &Processor {
+        &self.global_processor
+    }
+
+    fn get_processors(&self) -> &[Processor] {
+        &self.processors
     }
 
     fn get_total_memory(&self) -> u64 {
diff --git a/src/windows/tools.rs b/src/windows/tools.rs
index 8a8ba94..18565fd 100644
--- a/src/windows/tools.rs
+++ b/src/windows/tools.rs
@@ -4,10 +4,10 @@
 // Copyright (c) 2018 Guillaume Gomez
 //
 
-use windows::processor::{self, CounterValue, Processor, Query};
+use windows::processor::{self, Processor, Query};
 
-use DiskType;
 use sys::disk::{new_disk, Disk};
+use DiskType;
 
 use std::collections::HashMap;
 use std::ffi::OsStr;
@@ -45,7 +45,7 @@ impl KeyHandler {
     }
 }
 
-pub fn init_processors() -> Vec<Processor> {
+pub fn init_processors() -> (Vec<Processor>, String, String) {
     unsafe {
         let mut sys_info: SYSTEM_INFO = zeroed();
         GetSystemInfo(&mut sys_info);
@@ -60,11 +60,7 @@ pub fn init_processors() -> Vec<Processor> {
                 frequencies[nb as usize],
             ));
         }
-        ret.insert(
-            0,
-            Processor::new_with_values("Total CPU", vendor_id, brand, 0),
-        );
-        ret
+        (ret, vendor_id, brand)
     }
 }
 
@@ -319,11 +315,10 @@ pub fn add_counter(
     query: &mut Query,
     keys: &mut Option<KeyHandler>,
     counter_name: String,
-    value: CounterValue,
 ) {
     let mut full = s.encode_utf16().collect::<Vec<_>>();
     full.push(0);
-    if query.add_counter(&counter_name, full.clone(), value) {
+    if query.add_counter(&counter_name, full.clone()) {
         *keys = Some(KeyHandler::new(counter_name, full));
     }
 }


Test patch:
diff --git a/tests/disk_list.rs b/tests/disk_list.rs
index d59e4f1..9b49dbf 100644
--- a/tests/disk_list.rs
+++ b/tests/disk_list.rs
@@ -12,5 +12,5 @@ fn test_disks() {
 
     let s = sysinfo::System::new();
     println!("total memory: {}", s.get_total_memory());
-    println!("total cpu cores: {}", s.get_processor_list().len());
+    println!("total cpu cores: {}", s.get_processors().len());
 }
diff --git a/tests/process.rs b/tests/process.rs
index caaf6dc..a9b4c2e 100644
--- a/tests/process.rs
+++ b/tests/process.rs
@@ -13,11 +13,12 @@ fn test_process() {
     use sysinfo::SystemExt;
 
     let mut s = sysinfo::System::new();
+    assert_eq!(s.get_processes().len(), 0);
     s.refresh_processes();
-    assert!(s.get_process_list().len() != 0);
+    assert!(s.get_processes().len() != 0);
     #[cfg(not(windows))]
     assert!(s
-        .get_process_list()
+        .get_processes()
         .values()
         .any(|p| p.exe().to_str().unwrap_or_else(|| "").len() != 0));
 }
diff --git a/tests/processor.rs b/tests/processor.rs
new file mode 100644
index 0000000..39cafd6
--- /dev/null
+++ b/tests/processor.rs
@@ -0,0 +1,20 @@
+//
+// Sysinfo
+//
+// Copyright (c) 2020 Guillaume Gomez
+//
+
+// This test is used to ensure that the processors are loaded whatever the method
+// used to initialize `System`.
+
+extern crate sysinfo;
+
+#[test]
+fn test_processor() {
+    use sysinfo::SystemExt;
+
+    let s = sysinfo::System::new();
+    assert!(s.get_processors().len() > 0);
+    let s = sysinfo::System::new_all();
+    assert!(s.get_processors().len() > 0);
+}