don't unnecessarily lock for pointer derefs

This commit is contained in:
lifning 2021-11-27 17:20:44 -08:00
parent d581440210
commit 4bb748246c

View file

@ -9,20 +9,51 @@ use std::sync::Mutex;
use lazy_static::lazy_static; use lazy_static::lazy_static;
#[repr(C, align(65536))] lazy_static! {
static ref POOL: Pool = Pool::default();
}
struct Pool { struct Pool {
data: [u8; 65536], inner: Mutex<PoolInner>,
base_ptr: usize,
}
impl Default for Pool {
fn default() -> Self {
let inner = Mutex::new(PoolInner { data: [0; 0x10000], begin: 0, end: 0, last_position: 0 });
let base_ptr = inner.lock().unwrap().data.as_ptr() as usize;
Pool {
inner,
base_ptr,
}
}
}
impl Pool {
fn alloc(&self, layout: Layout) -> u16 {
self.inner.lock().unwrap().alloc(layout)
}
fn dealloc(&self, sptr: u16) {
self.inner.lock().unwrap().dealloc(sptr)
}
}
impl std::fmt::Debug for Pool {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.inner.lock().unwrap().fmt(f)
}
}
#[repr(C, align(0x10000))]
struct PoolInner {
data: [u8; 0x10000],
begin: usize, begin: usize,
end: usize, end: usize,
last_position: usize, last_position: usize,
} }
lazy_static! {
static ref POOL: Mutex<Pool> = Mutex::new(Pool { data: [0; 65536], begin: 0, end: 0, last_position: 0 });
}
// halfassed bump allocator just to prove a point. // halfassed bump allocator just to prove a point.
impl Pool { impl PoolInner {
fn alloc(&mut self, layout: Layout) -> u16 { fn alloc(&mut self, layout: Layout) -> u16 {
let size = layout.size(); let size = layout.size();
let align = layout.align(); let align = layout.align();
@ -78,10 +109,11 @@ impl Pool {
} }
} }
impl std::fmt::Debug for Pool { impl std::fmt::Debug for PoolInner {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!( write!(
f, "Pool {{ data: [_; 65536], begin: {}, end: {}, last_position: {} }}", f, "Pool {{ data: [_; {}], begin: {}, end: {}, last_position: {} }}",
self.data.len(),
self.begin, self.begin,
self.end, self.end,
self.last_position, self.last_position,
@ -93,20 +125,20 @@ pub struct ShortPointer<T>(u16, PhantomData<T>);
impl<T> Drop for ShortPointer<T> { impl<T> Drop for ShortPointer<T> {
fn drop(&mut self) { fn drop(&mut self) {
POOL.lock().unwrap().dealloc(self.0) POOL.dealloc(self.0)
} }
} }
impl<T> ShortPointer<T> { impl<T> ShortPointer<T> {
fn deref_inner(&self) -> &mut T { fn deref_inner(&self) -> &mut T {
unsafe { unsafe {
((((POOL.lock().unwrap().data.as_mut_ptr()) as usize) + (self.0 as usize)) as *mut T).as_mut().unwrap() ((POOL.base_ptr + (self.0 as usize)) as *mut T).as_mut().unwrap()
} }
} }
pub fn new(obj: T) -> Self { pub fn new(obj: T) -> Self {
let layout = Layout::for_value(&obj); let layout = Layout::for_value(&obj);
let mut sptr = Self(POOL.lock().unwrap().alloc(layout), PhantomData::default()); let mut sptr = Self(POOL.alloc(layout), PhantomData::default());
let uninitialized = core::mem::replace(sptr.deref_mut(), obj); let uninitialized = core::mem::replace(sptr.deref_mut(), obj);
core::mem::forget(uninitialized); core::mem::forget(uninitialized);
sptr sptr
@ -129,16 +161,16 @@ impl<T> DerefMut for ShortPointer<T> {
#[allow(unused_must_use)] // dbg! statements #[allow(unused_must_use)] // dbg! statements
fn main() { fn main() {
dbg!(POOL.lock().unwrap()); dbg!(&*POOL);
{ {
let foo = ShortPointer::new([1, 2, 3, 4, 5]); let foo = ShortPointer::new([1, 2, 3, 4, 5]);
dbg!(POOL.lock().unwrap()); dbg!(&*POOL);
{ {
let bar = ShortPointer::new(0x900dCafeDa7e5_u64); let bar = ShortPointer::new(0x900dCafeDa7e5_u64);
dbg!(POOL.lock().unwrap()); dbg!(&*POOL);
println!("{} | {:?} | {:x}", size_of_val(&foo), *foo, *bar); println!("{} | {:?} | {:x}", size_of_val(&foo), *foo, *bar);
} }
dbg!(POOL.lock().unwrap()); dbg!(&*POOL);
} }
dbg!(POOL.lock().unwrap()); dbg!(&*POOL);
} }