Next Generation WASM Microkernel Operating System
wasm os rust microkernel
at trap_handler 67 lines 2.3 kB view raw
1// Copyright 2025 Jonas Kruckenberg 2// 3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or 4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or 5// http://opensource.org/licenses/MIT>, at your option. This file may not be 6// copied, modified, or distributed except according to those terms. 7 8//! Very small, fast, non-cryptographic random number generator. 9//! 10//! This random number generator implements the `xorshift64+` algorithm, generating random numbers 11//! adding two 32-bit `xorshift` sequences together. 12 13#![cfg_attr(not(test), no_std)] 14 15/// Fast, non-cryptographic random number generator. 16/// 17/// Implement `xorshift64+`: 2 32-bit `xorshift` sequences added together. 18/// Shift triplet `[17,7,16]` was calculated as indicated in Marsaglia's 19/// `Xorshift` paper: <https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf> 20/// This generator passes the SmallCrush suite, part of TestU01 framework: 21/// <http://simul.iro.umontreal.ca/testu01/tu01.html> 22#[derive(Clone, Copy, Debug)] 23pub struct FastRand { 24 one: u32, 25 two: u32, 26} 27 28impl FastRand { 29 /// Initializes a new, thread-local, fast random number generator from the provided seed. 30 pub fn from_seed(seed: u64) -> FastRand { 31 let one = (seed >> 32_u64) as u32; 32 #[expect( 33 clippy::cast_possible_truncation, 34 reason = "we actually want to truncate here" 35 )] 36 let mut two = seed as u32; 37 38 if two == 0 { 39 // This value cannot be zero 40 two = 1; 41 } 42 43 FastRand { one, two } 44 } 45 46 /// Generate a random `u32` between `0` and `n`. 47 pub fn fastrand_n(&mut self, n: u32) -> u32 { 48 // This is similar to fastrand() % n, but faster. 49 // See https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ 50 let mul = u64::from(self.fastrand()).wrapping_mul(u64::from(n)); 51 (mul >> 32) as u32 52 } 53 54 /// Generate a random `u32` number. 55 pub fn fastrand(&mut self) -> u32 { 56 let mut s1 = self.one; 57 let s0 = self.two; 58 59 s1 ^= s1 << 17_u32; 60 s1 = s1 ^ s0 ^ s1 >> 7_u32 ^ s0 >> 16_u32; 61 62 self.one = s0; 63 self.two = s1; 64 65 s0.wrapping_add(s1) 66 } 67}