uwd/
utils.rs

1/// Randomly shuffles the elements of a mutable slice in-place using a pseudo-random
2/// number generator seeded by the CPU's timestamp counter (`rdtsc`).
3///
4/// The shuffling algorithm is a variant of the Fisher-Yates shuffle.
5///
6/// # Arguments
7/// 
8/// * `list` — A mutable slice of elements to be shuffled.
9pub fn shuffle<T>(list: &mut [T]) {
10    let mut seed = rdtsc();
11    for i in (1..list.len()).rev() {
12        seed = seed.wrapping_mul(1103515245).wrapping_add(12345);
13        let j = seed as usize % (i + 1);
14        list.swap(i, j);
15    }
16}
17
18/// Reads the CPU's time-stamp counter using the `rdtsc` instruction, which returns the
19/// number of cycles since the last reset.
20///
21/// This can be used as a fast, low-quality entropy source for seeding simple randomization routines.
22///
23/// # Returns
24/// 
25/// * The 64-bit timestamp value combining the contents of EDX:EAX registers.
26#[inline(always)]
27fn rdtsc() -> u64 {
28    unsafe {
29        let mut low: u32;
30        let mut high: u32;
31        core::arch::asm!("rdtsc", out("eax") low, out("edx") high);
32        ((high as u64) << 32) | (low as u64)
33    }
34}