Merge branch 'main' of github.com:AFLplusplus/libAFLrs into main
This commit is contained in:
commit
6dfe253bb9
@ -33,4 +33,4 @@ num = "*"
|
|||||||
xxhash-rust = { version = "0.8.0", features = ["xxh3"] } # xxh3 hashing for rust
|
xxhash-rust = { version = "0.8.0", features = ["xxh3"] } # xxh3 hashing for rust
|
||||||
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
|
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
|
||||||
erased-serde = "0.3.12"
|
erased-serde = "0.3.12"
|
||||||
postcard = "0.5.1" # no_std compatible serde serialization fromat
|
postcard = { version = "0.5.1", features = ["alloc"] } # no_std compatible serde serialization fromat
|
@ -1,14 +1,22 @@
|
|||||||
//! Compare the speed of rand implementations
|
//! Compare the speed of rand implementations
|
||||||
|
|
||||||
use afl::utils::{Rand, XorShift64Rand, Xoshiro256StarRand};
|
use afl::utils::{
|
||||||
|
Lehmer64Rand, Rand, RomuDuoJrRand, RomuTrioRand, XorShift64Rand, Xoshiro256StarRand,
|
||||||
|
};
|
||||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||||
|
|
||||||
fn criterion_benchmark(c: &mut Criterion) {
|
fn criterion_benchmark(c: &mut Criterion) {
|
||||||
let mut xorshift = XorShift64Rand::new(0);
|
let mut xorshift = XorShift64Rand::new(1);
|
||||||
let mut xoshiro = Xoshiro256StarRand::new(0);
|
let mut xoshiro = Xoshiro256StarRand::new(1);
|
||||||
|
let mut romu = RomuDuoJrRand::new(1);
|
||||||
|
let mut lehmer = Lehmer64Rand::new(1);
|
||||||
|
let mut romu_trio = RomuTrioRand::new(1);
|
||||||
|
|
||||||
c.bench_function("xorshift", |b| b.iter(|| black_box(xorshift.next())));
|
c.bench_function("xorshift", |b| b.iter(|| black_box(xorshift.next())));
|
||||||
c.bench_function("xoshiro", |b| b.iter(|| black_box(xoshiro.next())));
|
c.bench_function("xoshiro", |b| b.iter(|| black_box(xoshiro.next())));
|
||||||
|
c.bench_function("romu", |b| b.iter(|| black_box(romu.next())));
|
||||||
|
c.bench_function("romu_trio", |b| b.iter(|| black_box(romu_trio.next())));
|
||||||
|
c.bench_function("lehmer", |b| b.iter(|| black_box(lehmer.next())));
|
||||||
}
|
}
|
||||||
|
|
||||||
criterion_group!(benches, criterion_benchmark);
|
criterion_group!(benches, criterion_benchmark);
|
||||||
|
@ -301,7 +301,8 @@ where
|
|||||||
let cur = current_milliseconds();
|
let cur = current_milliseconds();
|
||||||
if cur - last > 60 * 100 {
|
if cur - last > 60 * 100 {
|
||||||
last = cur;
|
last = cur;
|
||||||
manager.fire(Event::update_stats(state.executions(), state.executions_over_seconds()),
|
manager.fire(
|
||||||
|
Event::update_stats(state.executions(), state.executions_over_seconds()),
|
||||||
state,
|
state,
|
||||||
corpus,
|
corpus,
|
||||||
)?; // TODO self.new_execs});
|
)?; // TODO self.new_execs});
|
||||||
|
@ -865,6 +865,11 @@ impl LlmpBroker {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Broadcasts the given buf to all lients
|
||||||
|
fn send_buf(&mut self, tag: u32, buf: &[u8]) -> Result<(), AflError> {
|
||||||
|
self.llmp_out.send_buf(tag, buf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `n` clients connect to a broker. They share an outgoing map with the broker,
|
/// `n` clients connect to a broker. They share an outgoing map with the broker,
|
||||||
|
@ -1,89 +0,0 @@
|
|||||||
use core::marker::PhantomData;
|
|
||||||
use core::ptr;
|
|
||||||
use std::{ffi::c_void, io::Read, io::Write, net::TcpListener};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
corpus::Corpus, engines::State, executors::Executor, inputs::Input, utils::Rand, AflError,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
|
||||||
llmp_translated::{LlmpBroker, LlmpClient, LlmpClientloopFn, LlmpMsgHookFn},
|
|
||||||
Event, EventManager,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Eventmanager for multi-processed application
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
pub struct LLMPEventManager<C, E, I, R>
|
|
||||||
where
|
|
||||||
C: Corpus<I, R>,
|
|
||||||
I: Input,
|
|
||||||
E: Executor<I>,
|
|
||||||
R: Rand,
|
|
||||||
//CE: CustomEvent<C, E, I, R>,
|
|
||||||
{
|
|
||||||
// TODO...
|
|
||||||
phantom: PhantomData<(C, E, I, R)>,
|
|
||||||
is_broker: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl<C, E, I, R> EventManager<C, E, I, R> for LLMPEventManager<C, E, I, R>
|
|
||||||
where
|
|
||||||
C: Corpus<I, R>,
|
|
||||||
E: Executor<I>,
|
|
||||||
I: Input,
|
|
||||||
R: Rand,
|
|
||||||
//CE: CustomEvent<C, E, I, R>,
|
|
||||||
{
|
|
||||||
fn enabled(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fire(&mut self, _event: Event<C, E, I, R>) -> Result<(), AflError> {
|
|
||||||
//self.events.push(event);
|
|
||||||
|
|
||||||
// TODO: Serde serialize, llmp send
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn process(&mut self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<usize, AflError> {
|
|
||||||
// TODO: iterators
|
|
||||||
/*
|
|
||||||
let mut handled = vec![];
|
|
||||||
for x in self.events.iter() {
|
|
||||||
handled.push(x.handle_in_broker(state, corpus)?);
|
|
||||||
}
|
|
||||||
handled
|
|
||||||
.iter()
|
|
||||||
.zip(self.events.iter())
|
|
||||||
.map(|(x, event)| match x {
|
|
||||||
BrokerEventResult::Forward => event.handle_in_client(state, corpus),
|
|
||||||
// Ignore broker-only events
|
|
||||||
BrokerEventResult::Handled => Ok(()),
|
|
||||||
})
|
|
||||||
.for_each(drop);
|
|
||||||
let count = self.events.len();
|
|
||||||
dbg!("Handled {} events", count);
|
|
||||||
self.events.clear();
|
|
||||||
|
|
||||||
let num = self.events.len();
|
|
||||||
for event in &self.events {}
|
|
||||||
|
|
||||||
self.events.clear();
|
|
||||||
*/
|
|
||||||
|
|
||||||
Ok(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl<C, E, I, R> LLMPEventManager<C, E, I, R>
|
|
||||||
where
|
|
||||||
C: Corpus<I, R>,
|
|
||||||
I: Input,
|
|
||||||
E: Executor<I>,
|
|
||||||
R: Rand,
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
@ -1,19 +1,16 @@
|
|||||||
//#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
//pub mod llmp;
|
mod llmp;
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub mod shmem_translated;
|
||||||
|
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
//#[cfg(feature = "std")]
|
|
||||||
//pub mod llmp_translated; // TODO: Abstract away.
|
|
||||||
//#[cfg(feature = "std")]
|
//#[cfg(feature = "std")]
|
||||||
//pub mod shmem_translated;
|
//pub mod shmem_translated;
|
||||||
|
|
||||||
//#[cfg(feature = "std")]
|
|
||||||
//pub use crate::events::llmp::LLMPEventManager;
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
@ -33,9 +30,7 @@ pub enum BrokerEventResult {
|
|||||||
Forward,
|
Forward,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ShowStats {
|
pub trait ShowStats {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -192,10 +187,6 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
R: Rand,
|
R: Rand,
|
||||||
{
|
{
|
||||||
/// Check if this EventaManager support a given Event type
|
|
||||||
/// To compare events, use Event::name().as_ptr()
|
|
||||||
fn enabled(&self) -> bool;
|
|
||||||
|
|
||||||
/// Fire an Event
|
/// Fire an Event
|
||||||
fn fire<'a>(
|
fn fire<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -330,10 +321,6 @@ where
|
|||||||
W: Write,
|
W: Write,
|
||||||
//CE: CustomEvent<C, E, I, R>,
|
//CE: CustomEvent<C, E, I, R>,
|
||||||
{
|
{
|
||||||
fn enabled(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fire<'a>(
|
fn fire<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: Event<'a, C, E, I, R>,
|
event: Event<'a, C, E, I, R>,
|
||||||
@ -373,3 +360,169 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Eventmanager for multi-processed application
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub struct LlmpBrokerEventManager<C, E, I, R>
|
||||||
|
where
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
I: Input,
|
||||||
|
E: Executor<I>,
|
||||||
|
R: Rand,
|
||||||
|
//CE: CustomEvent<C, E, I, R>,
|
||||||
|
{
|
||||||
|
llmp_broker: llmp::LlmpBroker,
|
||||||
|
phantom: PhantomData<(C, E, I, R)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Eventmanager for multi-processed application
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub struct LlmpClientEventManager<C, E, I, R>
|
||||||
|
where
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
I: Input,
|
||||||
|
E: Executor<I>,
|
||||||
|
R: Rand,
|
||||||
|
//CE: CustomEvent<C, E, I, R>,
|
||||||
|
{
|
||||||
|
llmp_client: llmp::LlmpClient,
|
||||||
|
phantom: PhantomData<(C, E, I, R)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<C, E, I, R> EventManager<C, E, I, R> for LlmpBrokerEventManager<C, E, I, R>
|
||||||
|
where
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
|
I: Input,
|
||||||
|
R: Rand,
|
||||||
|
//CE: CustomEvent<C, E, I, R>,
|
||||||
|
{
|
||||||
|
/// Fire an Event
|
||||||
|
fn fire<'a>(
|
||||||
|
&mut self,
|
||||||
|
event: Event<'a, C, E, I, R>,
|
||||||
|
state: &mut State<I, R>,
|
||||||
|
corpus: &mut C,
|
||||||
|
) -> Result<(), AflError> {
|
||||||
|
// TODO let serialized = postcard::to_vec(&event)?;
|
||||||
|
// self.llmp_broker.send_buf(&serialized)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process(&mut self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<usize, AflError> {
|
||||||
|
// TODO: iterators
|
||||||
|
/*
|
||||||
|
let mut handled = vec![];
|
||||||
|
for x in self.events.iter() {
|
||||||
|
handled.push(x.handle_in_broker(state, corpus)?);
|
||||||
|
}
|
||||||
|
handled
|
||||||
|
.iter()
|
||||||
|
.zip(self.events.iter())
|
||||||
|
.map(|(x, event)| match x {
|
||||||
|
BrokerEventResult::Forward => event.handle_in_client(state, corpus),
|
||||||
|
// Ignore broker-only events
|
||||||
|
BrokerEventResult::Handled => Ok(()),
|
||||||
|
})
|
||||||
|
.for_each(drop);
|
||||||
|
let count = self.events.len();
|
||||||
|
dbg!("Handled {} events", count);
|
||||||
|
self.events.clear();
|
||||||
|
|
||||||
|
let num = self.events.len();
|
||||||
|
for event in &self.events {}
|
||||||
|
|
||||||
|
self.events.clear();
|
||||||
|
*/
|
||||||
|
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_recv(&self, _state: &mut State<I, R>, _corpus: &mut C) -> Result<(), AflError> {
|
||||||
|
// TODO: Better way to move out of testcase, or get ref
|
||||||
|
//Ok(corpus.add(self.testcase.take().unwrap()))
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_in_broker(
|
||||||
|
&self,
|
||||||
|
event: &Event<C, E, I, R>,
|
||||||
|
/*broker: &dyn EventManager<C, E, I, R>,*/ _state: &mut State<I, R>,
|
||||||
|
_corpus: &mut C,
|
||||||
|
) -> Result<BrokerEventResult, AflError> {
|
||||||
|
match event {
|
||||||
|
Event::LoadInitial {
|
||||||
|
sender_id: _,
|
||||||
|
phantom: _,
|
||||||
|
} => Ok(BrokerEventResult::Handled),
|
||||||
|
Event::NewTestcase {
|
||||||
|
sender_id: _,
|
||||||
|
input: _,
|
||||||
|
observers: _,
|
||||||
|
} => Ok(BrokerEventResult::Forward),
|
||||||
|
Event::UpdateStats {
|
||||||
|
sender_id: _,
|
||||||
|
executions: _,
|
||||||
|
execs_over_sec: _,
|
||||||
|
phantom: _,
|
||||||
|
} => {
|
||||||
|
// TODO
|
||||||
|
Ok(BrokerEventResult::Handled)
|
||||||
|
}
|
||||||
|
Event::Crash {
|
||||||
|
sender_id: _,
|
||||||
|
input: _,
|
||||||
|
phantom: _,
|
||||||
|
} => Ok(BrokerEventResult::Handled),
|
||||||
|
Event::Timeout {
|
||||||
|
sender_id: _,
|
||||||
|
input: _,
|
||||||
|
phantom: _,
|
||||||
|
} => {
|
||||||
|
// TODO
|
||||||
|
Ok(BrokerEventResult::Handled)
|
||||||
|
}
|
||||||
|
Event::Log {
|
||||||
|
sender_id,
|
||||||
|
severity_level,
|
||||||
|
message,
|
||||||
|
phantom: _,
|
||||||
|
} => {
|
||||||
|
//TODO: broker.log()
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
println!("{}[{}]: {}", sender_id, severity_level, message);
|
||||||
|
Ok(BrokerEventResult::Handled)
|
||||||
|
},
|
||||||
|
Event::None {
|
||||||
|
phantom: _,
|
||||||
|
} => Ok(BrokerEventResult::Handled)
|
||||||
|
//Event::Custom {sender_id, custom_event} => custom_event.handle_in_broker(state, corpus),
|
||||||
|
//_ => Ok(BrokerEventResult::Forward),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_in_client(
|
||||||
|
&self,
|
||||||
|
event: Event<C, E, I, R>,
|
||||||
|
/*client: &dyn EventManager<C, E, I, R>,*/ _state: &mut State<I, R>,
|
||||||
|
corpus: &mut C,
|
||||||
|
) -> Result<(), AflError> {
|
||||||
|
match event {
|
||||||
|
Event::NewTestcase {
|
||||||
|
sender_id: _,
|
||||||
|
input: _,
|
||||||
|
observers: _,
|
||||||
|
} => {
|
||||||
|
// here u should match sender_id, if equal to the current one do not re-execute
|
||||||
|
// we need to pass engine to process() too, TODO
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
println!("PLACEHOLDER: received NewTestcase");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
_ => Err(AflError::Unknown(
|
||||||
|
"Received illegal message that message should not have arrived.".into(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -180,11 +180,7 @@ unsafe fn afl_shmem_init(shm: *mut AflShmem, map_size: usize) -> *mut c_uchar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Uses a shmap id string to open a shared map
|
/// Uses a shmap id string to open a shared map
|
||||||
unsafe fn afl_shmem_by_str(
|
unsafe fn afl_shmem_by_str(shm: *mut AflShmem, shm_str: &CStr, map_size: usize) -> *mut c_uchar {
|
||||||
shm: *mut AflShmem,
|
|
||||||
shm_str: &CStr,
|
|
||||||
map_size: usize,
|
|
||||||
) -> *mut c_uchar {
|
|
||||||
if shm.is_null() || shm_str.to_bytes().len() == 0 || map_size == 0 {
|
if shm.is_null() || shm_str.to_bytes().len() == 0 || map_size == 0 {
|
||||||
return 0 as *mut c_uchar;
|
return 0 as *mut c_uchar;
|
||||||
}
|
}
|
||||||
|
@ -300,4 +300,3 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
130
afl/src/utils.rs
130
afl/src/utils.rs
@ -9,14 +9,16 @@ use xxhash_rust::xxh3::xxh3_64_with_seed;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
pub type StdRand = Xoshiro256StarRand;
|
pub type StdRand = RomuTrioRand;
|
||||||
|
|
||||||
/// Ways to get random around here
|
/// Ways to get random around here
|
||||||
pub trait Rand: Debug {
|
pub trait Rand: Debug {
|
||||||
// Sets the seed of this Rand
|
// Sets the seed of this Rand
|
||||||
fn set_seed(&mut self, seed: u64);
|
fn set_seed(&mut self, seed: u64);
|
||||||
|
|
||||||
// Gets the next 64 bit value
|
// Gets the next 64 bit value
|
||||||
fn next(&mut self) -> u64;
|
fn next(&mut self) -> u64;
|
||||||
|
|
||||||
// Gets a value below the given 64 bit val (inclusive)
|
// Gets a value below the given 64 bit val (inclusive)
|
||||||
fn below(&mut self, upper_bound_excl: u64) -> u64 {
|
fn below(&mut self, upper_bound_excl: u64) -> u64 {
|
||||||
if upper_bound_excl <= 1 {
|
if upper_bound_excl <= 1 {
|
||||||
@ -73,6 +75,15 @@ where
|
|||||||
|
|
||||||
const HASH_CONST: u64 = 0xa5b35705;
|
const HASH_CONST: u64 = 0xa5b35705;
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
/// Gets current nanoseconds since UNIX_EPOCH
|
||||||
|
pub fn current_nanos() -> u64 {
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_nanos() as u64
|
||||||
|
}
|
||||||
|
|
||||||
/// XXH3 Based, hopefully speedy, rnd implementation
|
/// XXH3 Based, hopefully speedy, rnd implementation
|
||||||
///
|
///
|
||||||
#[derive(Copy, Clone, Debug, Default)]
|
#[derive(Copy, Clone, Debug, Default)]
|
||||||
@ -91,6 +102,7 @@ impl Rand for Xoshiro256StarRand {
|
|||||||
self.seeded = true;
|
self.seeded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn next(&mut self) -> u64 {
|
fn next(&mut self) -> u64 {
|
||||||
let ret: u64 = self.rand_seed[0]
|
let ret: u64 = self.rand_seed[0]
|
||||||
.wrapping_add(self.rand_seed[3])
|
.wrapping_add(self.rand_seed[3])
|
||||||
@ -125,19 +137,11 @@ impl Xoshiro256StarRand {
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_rc_refcell(self) -> Rc<RefCell<Self>> {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a rand instance, pre-seeded with the current time in nanoseconds.
|
/// Creates a rand instance, pre-seeded with the current time in nanoseconds.
|
||||||
/// Needs stdlib timer
|
/// Needs stdlib timer
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn preseeded() -> Self {
|
pub fn preseeded() -> Self {
|
||||||
let seed = SystemTime::now()
|
Self::new(current_nanos())
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_nanos() as u64;
|
|
||||||
Self::new(seed)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +159,7 @@ impl Rand for XorShift64Rand {
|
|||||||
self.seeded = true;
|
self.seeded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn next(&mut self) -> u64 {
|
fn next(&mut self) -> u64 {
|
||||||
let mut x = self.rand_seed;
|
let mut x = self.rand_seed;
|
||||||
x ^= x << 13;
|
x ^= x << 13;
|
||||||
@ -179,19 +184,11 @@ impl XorShift64Rand {
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_rc_refcell(self) -> Rc<RefCell<Self>> {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a rand instance, pre-seeded with the current time in nanoseconds.
|
/// Creates a rand instance, pre-seeded with the current time in nanoseconds.
|
||||||
/// Needs stdlib timer
|
/// Needs stdlib timer
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn preseeded() -> Self {
|
pub fn preseeded() -> Self {
|
||||||
let seed = SystemTime::now()
|
Self::new(current_nanos())
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_nanos() as u64;
|
|
||||||
Self::new(seed)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +206,7 @@ impl Rand for Lehmer64Rand {
|
|||||||
self.seeded = true;
|
self.seeded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn next(&mut self) -> u64 {
|
fn next(&mut self) -> u64 {
|
||||||
self.rand_seed *= 0xda942042e4dd58b5;
|
self.rand_seed *= 0xda942042e4dd58b5;
|
||||||
return (self.rand_seed >> 64) as u64;
|
return (self.rand_seed >> 64) as u64;
|
||||||
@ -222,26 +220,98 @@ impl Into<Rc<RefCell<Self>>> for Lehmer64Rand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Lehmer64Rand {
|
impl Lehmer64Rand {
|
||||||
/// Creates a new Xoshiro rand with the given seed
|
/// Creates a new Lehmer rand with the given seed
|
||||||
pub fn new(seed: u64) -> Self {
|
pub fn new(seed: u64) -> Self {
|
||||||
let mut ret: Self = Default::default();
|
let mut ret: Self = Default::default();
|
||||||
ret.set_seed(seed); // TODO: Proper random seed?
|
ret.set_seed(seed);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_rc_refcell(self) -> Rc<RefCell<Self>> {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a rand instance, pre-seeded with the current time in nanoseconds.
|
/// Creates a rand instance, pre-seeded with the current time in nanoseconds.
|
||||||
/// Needs stdlib timer
|
/// Needs stdlib timer
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn preseeded() -> Self {
|
pub fn preseeded() -> Self {
|
||||||
let seed = SystemTime::now()
|
Self::new(current_nanos())
|
||||||
.duration_since(UNIX_EPOCH)
|
}
|
||||||
.unwrap()
|
}
|
||||||
.as_nanos() as u64;
|
|
||||||
Self::new(seed)
|
/// Extremely quick rand implementation
|
||||||
|
/// see https://arxiv.org/pdf/2002.11331.pdf
|
||||||
|
#[derive(Copy, Clone, Debug, Default)]
|
||||||
|
pub struct RomuTrioRand {
|
||||||
|
x_state: u64,
|
||||||
|
y_state: u64,
|
||||||
|
z_state: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RomuTrioRand {
|
||||||
|
pub fn new(seed: u64) -> Self {
|
||||||
|
let mut rand = Self::default();
|
||||||
|
rand.set_seed(seed);
|
||||||
|
rand
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a rand instance, pre-seeded with the current time in nanoseconds.
|
||||||
|
/// Needs stdlib timer
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub fn preseeded() -> Self {
|
||||||
|
Self::new(current_nanos())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rand for RomuTrioRand {
|
||||||
|
fn set_seed(&mut self, seed: u64) {
|
||||||
|
self.x_state = seed ^ 0x12345;
|
||||||
|
self.y_state = seed ^ 0x6789A;
|
||||||
|
self.z_state = seed ^ 0xBCDEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> u64 {
|
||||||
|
let xp = self.x_state;
|
||||||
|
let yp = self.y_state;
|
||||||
|
let zp = self.z_state;
|
||||||
|
self.x_state = 15241094284759029579u64.wrapping_mul(zp);
|
||||||
|
self.y_state = yp.wrapping_sub(xp).rotate_left(12);
|
||||||
|
self.z_state = zp.wrapping_sub(yp).rotate_left(44);
|
||||||
|
xp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// see https://arxiv.org/pdf/2002.11331.pdf
|
||||||
|
#[derive(Copy, Clone, Debug, Default)]
|
||||||
|
pub struct RomuDuoJrRand {
|
||||||
|
x_state: u64,
|
||||||
|
y_state: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RomuDuoJrRand {
|
||||||
|
pub fn new(seed: u64) -> Self {
|
||||||
|
let mut rand = Self::default();
|
||||||
|
rand.set_seed(seed);
|
||||||
|
rand
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a rand instance, pre-seeded with the current time in nanoseconds.
|
||||||
|
/// Needs stdlib timer
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub fn preseeded() -> Self {
|
||||||
|
Self::new(current_nanos())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rand for RomuDuoJrRand {
|
||||||
|
fn set_seed(&mut self, seed: u64) {
|
||||||
|
self.x_state = seed ^ 0x12345;
|
||||||
|
self.y_state = seed ^ 0x6789A;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> u64 {
|
||||||
|
let xp = self.x_state;
|
||||||
|
self.x_state = 15241094284759029579u64.wrapping_mul(self.y_state);
|
||||||
|
self.y_state = self.y_state.wrapping_sub(xp).rotate_left(27);
|
||||||
|
xp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user