Skip to content

Commit

Permalink
fix: define xorshift64star and xorshift32 functions
Browse files Browse the repository at this point in the history
Signed-off-by: Yuuki Takano <ytakanoster@gmail.com>
  • Loading branch information
ytakano committed Jan 14, 2025
1 parent 4f776f9 commit 9e7d2f7
Showing 1 changed file with 36 additions and 19 deletions.
55 changes: 36 additions & 19 deletions futures-util/src/async_await/random.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::num::Wrapping;

// Based on [Fisher–Yates shuffle].
//
// [Fisher–Yates shuffle]: https://en.wikipedia.org/wiki/Fisher–Yates_shuffle
Expand All @@ -22,7 +24,6 @@ fn random() -> u64 {
cell::Cell,
collections::hash_map::DefaultHasher,
hash::Hasher,
num::Wrapping,
sync::atomic::{AtomicUsize, Ordering},
};

Expand All @@ -44,35 +45,51 @@ fn random() -> u64 {
}

RNG.with(|rng| {
let mut x = rng.get();
debug_assert_ne!(x.0, 0);
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
rng.set(x);
x.0.wrapping_mul(0x2545_f491_4f6c_dd1d)
let x = rng.get();
let (next, result) = xorshift64star(x);
rng.set(next);
result
})
}

#[cfg(not(feature = "std"))]
fn random() -> u64 {
fn random_nostd() -> u64 {
use core::sync::atomic::{AtomicUsize, Ordering};

static RNG: AtomicUsize = AtomicUsize::new(1);

let mut x = RNG.load(Ordering::Relaxed);
let x = RNG.load(Ordering::Relaxed);

if core::mem::size_of::<usize>() == 4 {
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
let next = xorshift32(x as u32);
RNG.store(next as usize, Ordering::Relaxed);
next as u64
} else if core::mem::size_of::<usize>() == 8 {
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
x = x.wrapping_mul(0x2545_f491_4f6c_dd1d);
let (next, result) = xorshift64star(Wrapping(x as u64));
RNG.store(next.0 as usize, Ordering::Relaxed);
result
} else {
panic!("random() function is not supported on this platform");
}
}

RNG.store(x, Ordering::Relaxed);
x as u64
/// Xorshift64* algorithm.
/// Returns the next state and the random number; `(next_state, random_number)`.
#[inline]
fn xorshift64star(mut x: Wrapping<u64>) -> (Wrapping<u64>, u64) {
debug_assert_ne!(x.0, 0);
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
(x, x.0.wrapping_mul(0x2545_f491_4f6c_dd1d))
}

/// Xorshift32 algorithm.
#[cfg(not(feature = "std"))]
#[inline]
fn xorshift32(mut x: u32) -> u32 {
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
x
}

0 comments on commit 9e7d2f7

Please sign in to comment.