Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 46 additions & 6 deletions core/src/parking_lot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, 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;
Expand All @@ -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<Duration> 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`.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()),
Expand All @@ -89,22 +129,22 @@ 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,
}

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;
Expand Down