don't unnecessarily lock for pointer derefs
This commit is contained in:
parent
d581440210
commit
4bb748246c
66
src/main.rs
66
src/main.rs
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue