diff --git a/examples/usage.rs b/examples/usage.rs
index a7268d07973c95c1bdba5ddf9f2a106d80f961a1..2749788edc7ad49c722598c74b80d5c529fb81e7 100644
--- a/examples/usage.rs
+++ b/examples/usage.rs
@@ -1,5 +1,5 @@
 use core::mem;
-use poolman::PoolMan;
+use poolman::{PoolMan, P};
 
 #[derive(Debug)]
 struct IDrop(u32);
diff --git a/src/lib.rs b/src/lib.rs
index 9b7a0398e436a805d8b4b79082ff7aeef8a62fce..1d3c384e56a6eee5a4e5527df34b6d166f00e538 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -42,37 +42,27 @@ pub enum Error {
     AlreadyInitialized,
 }
 
-pub struct Box<T: 'static + Sized, const S: usize> {
+pub struct Box<T: 'static + Sized> {
     index: usize,
-    allocator: &'static PoolMan<T, S>,
+    p: &'static dyn P<T>,
 }
 
-impl<T: 'static, const S: usize> Drop for Box<T, S> {
+impl<T: 'static> Drop for Box<T> {
     fn drop(&mut self) {
-        self.allocator.dealloc(self.index)
+        self.p.dealloc(self.index)
     }
 }
 
-impl<T: 'static, const S: usize> Deref for Box<T, S> {
+impl<T: 'static> Deref for Box<T> {
     type Target = T;
     fn deref(&self) -> &T {
-        unsafe {
-            self.allocator
-                .data /* RacyCell */
-                .get_mut_unchecked() /* Array */
-                .get_unchecked(self.index)
-        }
+        self.p.deref_index(self.index)
     }
 }
 
-impl<T: 'static, const S: usize> DerefMut for Box<T, S> {
+impl<T: 'static> DerefMut for Box<T> {
     fn deref_mut(&mut self) -> &mut T {
-        unsafe {
-            self.allocator
-                .data /* RacyCell */
-                .get_mut_unchecked() /* Array */
-                .get_unchecked_mut(self.index)
-        }
+        self.p.deref_mut_index(self.index)
     }
 }
 
@@ -83,6 +73,50 @@ pub struct PoolMan<T: 'static, const S: usize> {
     init: RacyCell<bool>,
 }
 
+pub trait P<T> {
+    fn deref_index(&self, index: usize) -> &T;
+    fn deref_mut_index(&self, index: usize) -> &mut T;
+    fn dealloc(&self, index: usize);
+}
+
+impl<T: 'static, const S: usize> P<T> for PoolMan<T, S> {
+    #[inline]
+    fn deref_index(&self, index: usize) -> &T {
+        unsafe {
+            self.data /* RacyCell */
+                .get_mut_unchecked() /* Array */
+                .get_unchecked(index)
+        }
+    }
+
+    #[inline]
+    fn deref_mut_index(&self, index: usize) -> &mut T {
+        unsafe {
+            self.data /* RacyCell */
+                .get_mut_unchecked() /* Array */
+                .get_unchecked_mut(index)
+        }
+    }
+
+    // Safety:
+    //  dealloc can only be called by dropping Box
+    //  which can happen only if already initialized
+    //  thus it is safe to assume init == true
+    //
+    // not accissible from user code
+    #[inline]
+    fn dealloc(&self, index: usize) {
+        interrupt_free(|| unsafe {
+            *self.free.get_mut_unchecked().get_unchecked_mut(index) =
+                *self.head.get_mut_unchecked();
+            *self.head.get_mut_unchecked() = index;
+        });
+    }
+}
+
+unsafe impl<T: 'static, const S: usize> Sync for PoolMan<T, S> {}
+unsafe impl<T: 'static, const S: usize> Send for PoolMan<T, S> {}
+
 impl<T, const S: usize> PoolMan<T, S>
 where
     T: Sized,
@@ -115,38 +149,26 @@ where
         })
     }
 
-    // Safety:
-    //  dealloc can only be called by dropping Box
-    //  which can happen only if already initialized
-    //  thus it is safe to assume init == true
-    //
-    // not accissible from user code
-    #[inline]
-    fn dealloc(&self, index: usize) {
-        interrupt_free(|| unsafe {
-            *self.free.get_mut_unchecked().get_unchecked_mut(index) =
-                *self.head.get_mut_unchecked();
-            *self.head.get_mut_unchecked() = index;
-        });
-    }
-
     #[inline]
-    pub fn alloc(&'static self) -> Result<Box<T, S>, Error> {
+    pub fn alloc(&'static self) -> Result<Box<T>, Error> {
         // this check does not need to be inside of critical section
         // as initialization is monotonic, cannot be undone
         if !unsafe { *self.init.get_mut_unchecked() } {
             Err(Error::Uninitialized)
         } else {
             interrupt_free(|| unsafe {
-                let index = *self.head.get_mut_unchecked();
-                *self.head.get_mut_unchecked() =
-                    *self.free.get_mut_unchecked().get_unchecked(index);
-                if *self.head.get_mut_unchecked() > S {
+                // head of free list
+                let head = *self.head.get_mut_unchecked();
+                if head >= S {
                     Err(Error::OutOfMemory)
                 } else {
+                    // update head to `next` free
+                    *self.head.get_mut_unchecked() =
+                        *self.free.get_mut_unchecked().get_unchecked(head);
                     Ok(Box {
-                        index,
-                        allocator: self,
+                        index: head,
+                        // allocator: self,
+                        p: self,
                     })
                 }
             })