/ kernel / src / memory / instanced_alloc.rs
instanced_alloc.rs
 1  use core::ops::{Deref, DerefMut};
 2  
 3  use alloc::vec::Vec;
 4  use spin::{Mutex, MutexGuard, RwLock};
 5  
 6  pub struct InstancedAlloc<T: Default + 'static> {
 7      inner: RwLock<InstancedAllocInner<T>>,
 8  }
 9  
10  pub struct InstancedAllocInner<T: Default + 'static> {
11      data: Vec<(bool, Mutex<T>)>,
12      next: usize,
13  }
14  
15  impl<T: Default> InstancedAlloc<T> {
16      pub fn with_size(size: usize) -> Self {
17          let mut data = Vec::with_capacity(size);
18  
19          for _ in 0..size {
20              data.push((false, Mutex::new(T::default())));
21          }
22  
23          Self {
24              inner: RwLock::new(InstancedAllocInner { data, next: 0 }),
25          }
26      }
27  
28      pub fn get(&'static self) -> InstanceHandle<T> {
29          let mut inner = self.inner.write();
30          let start = inner.next;
31          let mut looped = false;
32          let mut found = None;
33          loop {
34              if !looped && inner.next > inner.data.len() {
35                  inner.next = 0;
36                  looped = true;
37              } else if looped && inner.next > start {
38                  break;
39              }
40  
41              if !inner.data[inner.next].0 {
42                  found = Some(inner.next);
43              }
44  
45              inner.next += 1;
46  
47              if found.is_some() {
48                  break;
49              }
50          }
51  
52          inner.data[found.unwrap()].0 = true;
53  
54          InstanceHandle {
55              instances: &self.inner,
56              index: found.unwrap(),
57          }
58      }
59  }
60  
61  pub struct InstanceHandle<T: Default + 'static> {
62      instances: &'static RwLock<InstancedAllocInner<T>>,
63      index: usize,
64  }
65  
66  impl<T: Default + 'static> InstanceHandle<T> {
67      pub fn lock(&mut self) -> InstanceLock<T> {
68          // THIS SHOULD BE SAFE BUT I HATE IT
69          let instance = self.instances.read();
70          let bypassed_mutex = unsafe {
71              let mutex = &instance.data[self.index].1;
72              (mutex as *const Mutex<T> as *mut Mutex<T>)
73                  .as_mut()
74                  .unwrap()
75          };
76  
77          InstanceLock {
78              _parent: self,
79              lock: bypassed_mutex.lock(),
80          }
81      }
82  }
83  
84  pub struct InstanceLock<'a, T: Default + 'static> {
85      _parent: &'a InstanceHandle<T>,
86      lock: MutexGuard<'a, T>,
87  }
88  
89  impl<'a, T: Default + 'static> Deref for InstanceLock<'a, T> {
90      type Target = T;
91      fn deref(&self) -> &Self::Target {
92          &self.lock
93      }
94  }
95  impl<'a, T: Default + 'static> DerefMut for InstanceLock<'a, T> {
96      fn deref_mut(&mut self) -> &mut Self::Target {
97          &mut self.lock
98      }
99  }