Skip to content
Snippets Groups Projects
Commit a93a4ca1 authored by Per Lindgren's avatar Per Lindgren
Browse files

with error

parent 79eb089e
No related branches found
No related tags found
No related merge requests found
...@@ -22,6 +22,11 @@ impl<T> RacyCell<T> { ...@@ -22,6 +22,11 @@ impl<T> RacyCell<T> {
//unsafe impl<T> Sync for RacyCell<T> where T: Sync {} //unsafe impl<T> Sync for RacyCell<T> where T: Sync {}
unsafe impl<T> Sync for RacyCell<T> {} unsafe impl<T> Sync for RacyCell<T> {}
#[derive(Debug)]
enum Error {
Unitialized,
OutOfMemory,
}
struct Box<T: 'static + Sized, const S: usize> { struct Box<T: 'static + Sized, const S: usize> {
// data: &'static mut T, // data: &'static mut T,
index: usize, index: usize,
...@@ -30,21 +35,30 @@ struct Box<T: 'static + Sized, const S: usize> { ...@@ -30,21 +35,30 @@ struct Box<T: 'static + Sized, const S: usize> {
impl<T: 'static, const S: usize> Drop for Box<T, S> { impl<T: 'static, const S: usize> Drop for Box<T, S> {
fn drop(&mut self) { fn drop(&mut self) {
self.allocator.dealloc(self.index) unsafe { self.allocator.dealloc(self.index) }
} }
} }
impl<T: 'static, const S: usize> Deref for Box<T, S> { impl<T: 'static, const S: usize> Deref for Box<T, S> {
type Target = T; type Target = T;
fn deref(&self) -> &T { fn deref(&self) -> &T {
unsafe { &self.allocator.data.get_mut_unchecked()[self.index] } unsafe {
self.allocator
.data /* RacyCell */
.get_mut_unchecked() /* Array */
.get_unchecked(self.index)
}
} }
} }
impl<T: 'static, const S: usize> DerefMut for Box<T, S> { impl<T: 'static, const S: usize> DerefMut for Box<T, S> {
// type Target = T;
fn deref_mut(&mut self) -> &mut T { fn deref_mut(&mut self) -> &mut T {
unsafe { &mut self.allocator.data.get_mut_unchecked()[self.index] } unsafe {
self.allocator
.data /* RacyCell */
.get_mut_unchecked() /* Array */
.get_unchecked_mut(self.index)
}
} }
} }
...@@ -72,6 +86,9 @@ where ...@@ -72,6 +86,9 @@ where
} }
fn init(&self) { fn init(&self) {
if *unsafe { self.init.get_mut_unchecked() } {
panic!("already initialized")
};
let free = unsafe { self.free.get_mut_unchecked() }; let free = unsafe { self.free.get_mut_unchecked() };
for (index, value) in free.iter_mut().enumerate() { for (index, value) in free.iter_mut().enumerate() {
*value = index + 1; *value = index + 1;
...@@ -81,30 +98,31 @@ where ...@@ -81,30 +98,31 @@ where
println!("init : free {:?}", unsafe { self.free.get_mut_unchecked() }); println!("init : free {:?}", unsafe { self.free.get_mut_unchecked() });
} }
fn dealloc(&self, index: usize) { // dealloc can only be called by dropping Box
unsafe { // which can happen only if already initialized
if !*self.init.get_mut_unchecked() { // in a library we could hide this as a crate local
panic!(); unsafe fn dealloc(&self, index: usize) {
} self.free.get_mut_unchecked()[index] = *self.head.get_mut_unchecked();
self.free.get_mut_unchecked()[index] = *self.head.get_mut_unchecked(); *self.head.get_mut_unchecked() = index;
*self.head.get_mut_unchecked() = index;
}
println!("dealloc index {}", index) println!("dealloc index {}", index)
} }
fn alloc(&'static self) -> Result<Box<T, S>, ()> { fn alloc(&'static self) -> Result<Box<T, S>, Error> {
unsafe { unsafe {
if !*self.init.get_mut_unchecked() { if !*self.init.get_mut_unchecked() {
panic!(); return Err(Error::Unitialized);
} }
let index = *self.head.get_mut_unchecked(); let index = *self.head.get_mut_unchecked();
println!("index {}", self.head.get_mut_unchecked()); println!("index {}", self.head.get_mut_unchecked());
println!("head {}", self.head.get_mut_unchecked()); println!("head {}", self.head.get_mut_unchecked());
*self.head.get_mut_unchecked() = self.free.get_mut_unchecked()[index]; if *self.head.get_mut_unchecked() >= S {
println!("new head {}", self.head.get_mut_unchecked()); Err(Error::OutOfMemory)
if *self.head.get_mut_unchecked() > S {
Err(())
} else { } else {
*self.head.get_mut_unchecked() =
*self.free.get_mut_unchecked().get_unchecked_mut(index);
println!("new head {}", self.head.get_mut_unchecked());
Ok(Box { Ok(Box {
index, index,
allocator: self, allocator: self,
...@@ -114,6 +132,49 @@ where ...@@ -114,6 +132,49 @@ where
} }
} }
mod tests {
use super::*;
static P: PoolMan<u32, 2> = PoolMan::new([0; 2]);
#[test]
fn test() {
P.init();
{
let e = P.alloc().unwrap();
println!("e {}", *e);
mem::drop(e);
let mut e1 = P.alloc().unwrap();
println!("e1 {}", *e1);
*e1 = 2;
println!("e1 {}", *e1);
let e2 = P.alloc().unwrap();
println!("e2 {}", *e2);
}
let e = P.alloc().unwrap();
println!("e {}", *e);
}
#[test]
fn test2() {
P.init();
{
let e = P.alloc().unwrap();
println!("e {}", *e);
mem::drop(e);
let mut e1 = P.alloc().unwrap();
println!("e1 {}", *e1);
*e1 = 2;
println!("e1 {}", *e1);
let e2 = P.alloc().unwrap();
println!("e2 {}", *e2);
}
let e = P.alloc().unwrap();
println!("e {}", *e);
}
}
static P: PoolMan<u32, 2> = PoolMan::new([0; 2]); static P: PoolMan<u32, 2> = PoolMan::new([0; 2]);
fn main() { fn main() {
P.init(); P.init();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment