diff --git a/core/src/parking_lot.rs b/core/src/parking_lot.rs index fb87aefe..440b7c70 100644 --- a/core/src/parking_lot.rs +++ b/core/src/parking_lot.rs @@ -4,7 +4,7 @@ // http://apache.org/licenses/LICENSE-2.0> or the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. - +use cfg_if::cfg_if; use crate::thread_parker::{ThreadParker, ThreadParkerT, UnparkHandleT}; use crate::util::UncheckedOptionExt; use crate::word_lock::WordLock; @@ -16,6 +16,46 @@ use core::{ use smallvec::SmallVec; use std::time::{Duration, Instant}; +cfg_if! { + if #[cfg(all( + target_arch = "wasm32", + target_os = "unknown", + target_vendor = "unknown" + ))] { + use core::ops::Add; + + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] + struct DummyInstant(Duration); + + impl DummyInstant { + pub fn now() -> DummyInstant { + DummyInstant::zero() + } + + const fn zero() -> DummyInstant { + DummyInstant(Duration::from_secs(0)) + } + } + + impl Add for DummyInstant { + type Output = DummyInstant; + + fn add(self, _rhs: Duration) -> DummyInstant { + DummyInstant::zero() + } + } + + // Use dummy implementation for `Instant` on `wasm32`. The reason for this is + // that `Instant::now()` will always panic because time is currently not implemented + // on wasm32-unknown-unknown. + // See https://github.com/rust-lang/rust/blob/master/src/libstd/sys/wasm/time.rs + type InstantType = DummyInstant; + } else { + // Otherwise use `std::time::Instant` + type InstantType = Instant; + } +} + static NUM_THREADS: AtomicUsize = AtomicUsize::new(0); /// Holds the pointer to the currently active `HashTable`. @@ -47,7 +87,7 @@ impl HashTable { let new_size = (num_threads * LOAD_FACTOR).next_power_of_two(); let hash_bits = 0usize.leading_zeros() - new_size.leading_zeros() - 1; - let now = Instant::now(); + let now = InstantType::now(); let mut entries = Vec::with_capacity(new_size); for i in 0..new_size { // We must ensure the seed is not zero @@ -77,7 +117,7 @@ struct Bucket { impl Bucket { #[inline] - pub fn new(timeout: Instant, seed: u32) -> Self { + pub fn new(timeout: InstantType, seed: u32) -> Self { Self { mutex: WordLock::new(), queue_head: Cell::new(ptr::null()), @@ -89,7 +129,7 @@ impl Bucket { struct FairTimeout { // Next time at which point be_fair should be set - timeout: Instant, + timeout: InstantType, // the PRNG state for calculating the next timeout seed: u32, @@ -97,14 +137,14 @@ struct FairTimeout { impl FairTimeout { #[inline] - fn new(timeout: Instant, seed: u32) -> FairTimeout { + fn new(timeout: InstantType, seed: u32) -> FairTimeout { FairTimeout { timeout, seed } } // Determine whether we should force a fair unlock, and update the timeout #[inline] fn should_timeout(&mut self) -> bool { - let now = Instant::now(); + let now = InstantType::now(); if now > self.timeout { // Time between 0 and 1ms. let nanos = self.gen_u32() % 1_000_000;