feat(rand48): rwlock for global params
Signed-off-by: Anhad Singh <andypython@protonmail.com>
This commit is contained in:
@@ -297,7 +297,7 @@ pub extern "C" fn div(numer: c_int, denom: c_int) -> div_t {
|
||||
/// state.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn drand48() -> c_double {
|
||||
let params = rand48::params_lock();
|
||||
let params = rand48::params();
|
||||
let mut xsubi = rand48::xsubi_lock();
|
||||
*xsubi = params.step(*xsubi);
|
||||
xsubi.get_f64()
|
||||
@@ -330,7 +330,7 @@ pub extern "C" fn ecvt(
|
||||
/// state.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn erand48(xsubi: *mut c_ushort) -> c_double {
|
||||
let params = rand48::params_lock();
|
||||
let params = rand48::params();
|
||||
let xsubi_mut: &mut [c_ushort; 3] = slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap();
|
||||
let new_xsubi_value = params.step(xsubi_mut.into());
|
||||
*xsubi_mut = new_xsubi_value.into();
|
||||
@@ -521,7 +521,7 @@ pub unsafe extern "C" fn initstate(seed: c_uint, state: *mut c_char, size: size_
|
||||
/// state.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn jrand48(xsubi: *mut c_ushort) -> c_long {
|
||||
let params = rand48::params_lock();
|
||||
let params = rand48::params();
|
||||
let xsubi_mut: &mut [c_ushort; 3] = slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap();
|
||||
let new_xsubi_value = params.step(xsubi_mut.into());
|
||||
*xsubi_mut = new_xsubi_value.into();
|
||||
@@ -586,7 +586,7 @@ pub extern "C" fn labs(i: c_long) -> c_long {
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn lcong48(param: *mut c_ushort) {
|
||||
let mut xsubi = rand48::xsubi_lock();
|
||||
let mut params = rand48::params_lock();
|
||||
let mut params = rand48::params_mut();
|
||||
|
||||
let param_slice = slice::from_raw_parts(param, 7);
|
||||
|
||||
@@ -643,7 +643,7 @@ pub extern "C" fn lldiv(numer: c_longlong, denom: c_longlong) -> lldiv_t {
|
||||
/// state.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn lrand48() -> c_long {
|
||||
let params = rand48::params_lock();
|
||||
let params = rand48::params();
|
||||
let mut xsubi = rand48::xsubi_lock();
|
||||
*xsubi = params.step(*xsubi);
|
||||
xsubi.get_u31()
|
||||
@@ -843,7 +843,7 @@ pub unsafe extern "C" fn mktemp(name: *mut c_char) -> *mut c_char {
|
||||
/// state.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mrand48() -> c_long {
|
||||
let params = rand48::params_lock();
|
||||
let params = rand48::params();
|
||||
let mut xsubi = rand48::xsubi_lock();
|
||||
*xsubi = params.step(*xsubi);
|
||||
xsubi.get_i32()
|
||||
@@ -860,7 +860,7 @@ pub extern "C" fn mrand48() -> c_long {
|
||||
/// state.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn nrand48(xsubi: *mut c_ushort) -> c_long {
|
||||
let params = rand48::params_lock();
|
||||
let params = rand48::params();
|
||||
let xsubi_mut: &mut [c_ushort; 3] = slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap();
|
||||
let new_xsubi_value = params.step(xsubi_mut.into());
|
||||
*xsubi_mut = new_xsubi_value.into();
|
||||
@@ -1196,7 +1196,7 @@ pub unsafe extern "C" fn secure_getenv(name: *const c_char) -> *mut c_char {
|
||||
pub unsafe extern "C" fn seed48(seed16v: *mut c_ushort) -> *mut c_ushort {
|
||||
static mut BUFFER: [c_ushort; 3] = [0; 3];
|
||||
|
||||
let mut params = rand48::params_lock();
|
||||
let mut params = rand48::params_mut();
|
||||
let mut xsubi = rand48::xsubi_lock();
|
||||
|
||||
let seed16v_ref: &[c_ushort; 3] = slice::from_raw_parts(seed16v, 3).try_into().unwrap();
|
||||
@@ -1296,7 +1296,7 @@ pub unsafe extern "C" fn srand(seed: c_uint) {
|
||||
/// state.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn srand48(seedval: c_long) {
|
||||
let mut params = rand48::params_lock();
|
||||
let mut params = rand48::params_mut();
|
||||
let mut xsubi = rand48::xsubi_lock();
|
||||
|
||||
params.reset();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use crate::{
|
||||
platform::types::*,
|
||||
sync::{Mutex, MutexGuard},
|
||||
sync::{rwlock::{self, RwLock}, Mutex, MutexGuard},
|
||||
};
|
||||
|
||||
/// A 48-bit integer, used for the 48-bit arithmetic in these functions.
|
||||
@@ -119,13 +119,19 @@ impl Params {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: consider using rwlock instead of mutex for more fine-grained access
|
||||
/// Immediately get the global Params lock, or panic if unsuccessful.
|
||||
pub fn params_lock<'a>() -> MutexGuard<'a, Params> {
|
||||
static PARAMS: Mutex<Params> = Mutex::<Params>::new(Params::new());
|
||||
static PARAMS: RwLock<Params> = RwLock::<Params>::new(Params::new());
|
||||
|
||||
/// Immediately get the global [`Params`] lock for reading, or panic if unsuccessful.
|
||||
pub fn params<'a>() -> rwlock::ReadGuard<'a, Params> {
|
||||
PARAMS
|
||||
.try_lock()
|
||||
.try_read()
|
||||
.expect("unable to acquire LCG parameter lock")
|
||||
}
|
||||
|
||||
/// Immediately get the global [`Params`] lock for writing, or panic if unsuccessful.
|
||||
pub fn params_mut<'a>() -> rwlock::WriteGuard<'a, Params> {
|
||||
PARAMS
|
||||
.try_write()
|
||||
.expect("unable to acquire LCG parameter lock")
|
||||
}
|
||||
|
||||
|
||||
@@ -176,6 +176,22 @@ impl<T: ?Sized> RwLock<T> {
|
||||
self.inner.acquire_write_lock(None);
|
||||
unsafe { WriteGuard::new(self) }
|
||||
}
|
||||
|
||||
pub fn try_read(&self) -> Option<ReadGuard<'_, T>> {
|
||||
if self.inner.try_acquire_read_lock().is_ok() {
|
||||
Some(unsafe { ReadGuard::new(self) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_write(&self) -> Option<WriteGuard<'_, T>> {
|
||||
if self.inner.try_acquire_write_lock().is_ok() {
|
||||
Some(unsafe { WriteGuard::new(self) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReadGuard<'a, T: ?Sized + 'a> {
|
||||
|
||||
Reference in New Issue
Block a user