don't unnecessarily lock for pointer derefs
This commit is contained in:
		
							parent
							
								
									d581440210
								
							
						
					
					
						commit
						4bb748246c
					
				
					 1 changed files with 49 additions and 17 deletions
				
			
		
							
								
								
									
										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