1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/// This function is useful for inducing random jitter into our atomic
/// operations, shaking out more possible interleavings quickly. It gets
/// fully elliminated by the compiler in non-test code.
#[cfg_attr(not(feature = "no_inline"), inline)]
pub fn debug_delay() {
    #[cfg(any(test, feature = "lock_free_delays"))]
    {
        use std::sync::atomic::spin_loop_hint;
        use std::thread;
        use std::time::Duration;

        use rand::{
            distributions::{Distribution, Gamma},
            thread_rng, Rng,
        };

        if thread_rng().gen_bool(1. / 1000.) {
            let gamma = Gamma::new(0.3, 100000.0);
            let duration = gamma.sample(&mut thread_rng());
            thread::sleep(Duration::from_micros(duration as u64));
        }

        spin_loop_hint();

        if thread_rng().gen::<bool>() {
            thread::yield_now();
        }
    }
}

pub(crate) fn u64_to_arr(u: u64) -> [u8; 8] {
    [
        u as u8,
        (u >> 8) as u8,
        (u >> 16) as u8,
        (u >> 24) as u8,
        (u >> 32) as u8,
        (u >> 40) as u8,
        (u >> 48) as u8,
        (u >> 56) as u8,
    ]
}

pub(crate) fn arr_to_u64(arr: [u8; 8]) -> u64 {
    arr[0] as u64
        + ((arr[1] as u64) << 8)
        + ((arr[2] as u64) << 16)
        + ((arr[3] as u64) << 24)
        + ((arr[4] as u64) << 32)
        + ((arr[5] as u64) << 40)
        + ((arr[6] as u64) << 48)
        + ((arr[7] as u64) << 56)
}

pub(crate) fn arr_to_u32(arr: [u8; 4]) -> u32 {
    arr[0] as u32
        + ((arr[1] as u32) << 8)
        + ((arr[2] as u32) << 16)
        + ((arr[3] as u32) << 24)
}

pub(crate) fn u32_to_arr(u: u32) -> [u8; 4] {
    [u as u8, (u >> 8) as u8, (u >> 16) as u8, (u >> 24) as u8]
}