use std::sync::Arc;
use crate::bindings::cache::*;
use crate::flags::RandomXFlags;
use crate::try_alloc;
use crate::RResult;
#[derive(Debug)]
pub struct Cache {
inner: Arc<CacheInner>,
}
#[derive(Debug)]
struct CacheInner {
cache: *mut randomx_cache,
}
unsafe impl Send for CacheInner {}
unsafe impl Sync for CacheInner {}
#[derive(Clone, Debug)]
pub struct CacheHandle {
inner: Arc<CacheInner>,
}
impl Cache {
pub fn new(global_nonce: &[u8], flags: RandomXFlags) -> RResult<Self> {
let cache = try_alloc!(
randomx_alloc_cache(flags.bits()),
crate::RandomXError::CacheAllocationFailed { flags }
);
let cache_inner = CacheInner { cache };
let mut cache = Self {
inner: Arc::new(cache_inner),
};
cache.initialize(global_nonce);
Ok(cache)
}
pub fn initialize(&mut self, global_nonce: &[u8]) {
unsafe {
randomx_init_cache(
self.raw(),
global_nonce.as_ptr() as *const std::ffi::c_void,
global_nonce.len(),
)
};
}
pub fn handle(&self) -> CacheHandle {
CacheHandle {
inner: self.inner.clone(),
}
}
pub(crate) fn raw(&self) -> *mut randomx_cache {
self.inner.cache
}
}
impl CacheHandle {
pub fn raw(&self) -> *mut randomx_cache {
self.inner.cache
}
}
impl Drop for CacheInner {
fn drop(&mut self) {
unsafe { randomx_release_cache(self.cache) }
}
}
pub trait CacheRawAPI {
fn raw(&self) -> *mut randomx_cache;
}
impl CacheRawAPI for Cache {
fn raw(&self) -> *mut randomx_cache {
self.raw()
}
}
impl CacheRawAPI for CacheHandle {
fn raw(&self) -> *mut randomx_cache {
self.raw()
}
}