diff --git a/Cargo.toml b/Cargo.toml index f3778b9..20eeed8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,9 @@ libc = "0.2.26" [target.'cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_os = "hermit"))'.dependencies] hermit-abi = "0.1.3" + +[target.'cfg(target_arch = "wasm32")'.dependencies] +# This feature must be enabled only by top-level crate (cdylib) using wasm-bindgen on WebAssembly target. +# When enabled, it will tell `num_cpus` to retrieve real number of user cores from the browser via JavaScript. +# Any regular crates (leaf libraries) should continue use `num_cpus` as they normally would, and not touch this feature. +wasm-bindgen = { version = "0.2", optional = true } diff --git a/src/lib.rs b/src/lib.rs index 6c8280f..a6ac207 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ //! current system. //! //! Sometimes the CPU will exaggerate the number of CPUs it contains, because it can use -//! [processor tricks] to deliver increased performance when there are more threads. This +//! [processor tricks] to deliver increased performance when there are more threads. This //! crate provides methods to get both the logical and physical numbers of cores. //! //! This information can be used as a guide to how many tasks can be run in parallel. @@ -37,6 +37,9 @@ extern crate libc; #[cfg(target_os = "hermit")] extern crate hermit_abi; +#[cfg(feature = "wasm-bindgen")] +extern crate wasm_bindgen; + #[cfg(target_os = "linux")] mod linux; #[cfg(target_os = "linux")] @@ -89,7 +92,7 @@ pub fn get() -> usize { /// let physical_cpus = num_cpus::get_physical(); /// if logical_cpus > physical_cpus { /// println!("We have simultaneous multithreading with about {:.2} \ -/// logical cores to 1 physical core.", +/// logical cores to 1 physical core.", /// (logical_cpus as f64) / (physical_cpus as f64)); /// } else if logical_cpus == physical_cpus { /// println!("Either we don't have simultaneous multithreading, or our \ @@ -405,6 +408,19 @@ fn get_num_cpus() -> usize { unsafe { hermit_abi::get_processor_count() } } +#[cfg(feature = "wasm-bindgen")] +fn get_num_cpus() -> usize { + use wasm_bindgen::prelude::*; + + #[wasm_bindgen] + extern "C" { + #[wasm_bindgen(js_namespace = navigator, js_name = hardwareConcurrency)] + static HARDWARE_CONCURRENCY: usize; + } + + std::cmp::max(*HARDWARE_CONCURRENCY, 1) +} + #[cfg(not(any( target_os = "nacl", target_os = "macos", @@ -420,6 +436,7 @@ fn get_num_cpus() -> usize { target_os = "netbsd", target_os = "haiku", target_os = "hermit", + feature = "wasm-bindgen", windows, )))] fn get_num_cpus() -> usize {