added ffi rng

master
Avril 5 years ago
parent ac69a923a2
commit 5c5b68627a
Signed by: flanchan
GPG Key ID: 284488987C31F630

2
.gitignore vendored

@ -1 +1,3 @@
*~
libsrng/target/
libsrng/Cargo.lock

@ -0,0 +1,12 @@
install:
cp -f libsrng.so /usr/local/lib/libsrng.so
ln -sf /usr/local/lib/libsrng.so /usr/lib/libsrng.so
uninstall:
rm -f /usr/local/lib/libsrng.so
rm /usr/lib/libsrng.so
build:
cd libsrng && cargo build --release
cp libsrng/target/release/libsrng.so ./
gpg --sign libsrng.so

@ -0,0 +1,5 @@
Prebuild binary signed with https://flanchan.moe/flanchan.asc
To build dependencies yourself run:
make build && sudo make install
(requires Rust)

@ -6,6 +6,8 @@
:license "None"
:version "0.0.1"
:serial t
:depends-on (:cffi)
:components ((:file "package")
(:file "ffi")
(:file "urandom")
(:file "cl-rng")))

@ -2,9 +2,9 @@
(in-package :cl-rng)
(defparameter *default-precision* 100
(defparameter *default-precision* 1
"Default precision for the default RNG provider")
(defparameter *default-randomness-provider* #'(lambda (&rest args) (apply #'urandom (append `(:precision ,*default-precision*) args)))
(defparameter *default-randomness-provider* #'(lambda (&rest args) (apply #'crandom (append `(:precision ,*default-precision*) args)))
"The default randomness provider used by cl-rng functions")
(defun chance (fraction &key (provider *default-randomness-provider*))
@ -58,6 +58,7 @@
;; Exports
(export '*default-randomness-provider*)
(export '*default-precision*)
(defsetf within within-set)
(export 'range)
(export 'within)

@ -0,0 +1,19 @@
(in-package #:cl-rng)
(defun crandom (&key (limit 1.0) (precision 1) (transform nil))
(let ((transform (or transform #'identity)))
(multiple-value-bind (result ok) (cl-rng-ffi:ffi-sample)
(and ok
(funcall transform
(* limit
(if (< precision 2)
result
(/ (apply #'+ (mapcan #'(lambda (x)
(and (not (null x))
(list x)))
(loop for x from 0 below precision collect
(crandom))))
precision))))))))
(export 'crandom)

@ -0,0 +1,19 @@
(in-package #:cl-rng-ffi)
(define-foreign-library libsrng
(:unix (:or "libsrng.so" "libsrng" "./libsrng.so"))
(t (:default "libsrng")))
(use-foreign-library libsrng)
(defcfun "sample" :int (to :pointer))
(defun ffi-sample ()
(with-foreign-pointer (value 8)
(let ((rval (sample value)))
(values
(mem-ref value :double 0)
(= rval 1)))))
(export 'ffi-sample)

Binary file not shown.

Binary file not shown.

@ -0,0 +1,13 @@
[package]
name = "srng"
version = "0.1.0"
authors = ["Avril <flanchan@cumallover.me>"]
edition = "2018"
[lib]
crate-type = ["cdylib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
getrandom = "0.1"

@ -0,0 +1,56 @@
extern crate getrandom;
use getrandom::*;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let mut f: f64 = 0.0;
assert_eq!(sample(&mut f as *mut f64), 1);
}
}
fn get<T: Default>() -> Result<T, Error>
{
let mut value: T = Default::default();
unsafe {
let mut slice = std::slice::from_raw_parts_mut(&mut value as *mut T as *mut u8, std::mem::size_of::<T>());
populate(&mut slice)?;
}
Ok(value)
}
fn double() -> Result<f64, Error>
{
let long: i64 = get::<i64>()?;
Ok( ((long & ((1i64 << 53) - 1)) as f64) * (1_f64 / ((1_i64 << 53) as f64)))
}
fn populate(mut value: &mut [u8]) -> Result<(), Error>
{
getrandom(&mut value)?;
Ok(())
}
#[no_mangle]
pub extern "C" fn sample(value: *mut f64) -> i32
{
match std::panic::catch_unwind(|| {
unsafe {
match double() {
Ok(x) => *value = x,
Err(_) => return 0,
}
}
1
}) {
Ok(v) => v,
Err(_) => 0,
}
}

@ -2,3 +2,6 @@
(defpackage #:cl-rng
(:use #:cl))
(defpackage #:cl-rng-ffi
(:use :cl :cffi :cl-rng))

Loading…
Cancel
Save