aboutsummaryrefslogtreecommitdiff
path: root/src/alloc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.rs')
-rw-r--r--src/alloc.rs92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/alloc.rs b/src/alloc.rs
new file mode 100644
index 0000000..4fe44ee
--- /dev/null
+++ b/src/alloc.rs
@@ -0,0 +1,92 @@
+use crate::sync::NullLock;
+use crate::sync::interface::Mutex;
+
+const CHAR_COUNT: usize = 20;
+const CHAR_POOL_SIZE: usize = CHAR_COUNT + 2;
+
+#[derive(Copy,Clone)]
+pub struct CharCell {
+ pub data: char,
+ next: Option<*mut CharCell>,
+}
+
+impl CharCell {
+ pub const fn new() -> Self {
+ Self {
+ data: '\0',
+ next: None,
+ }
+ }
+}
+
+use core::fmt::{Debug,Formatter,Result};
+impl Debug for CharCell {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ write!(f, "{}", self.data)
+ }
+}
+
+unsafe impl Send for CharCell {}
+
+pub struct CharAllocator(NullLock<[CharCell; CHAR_POOL_SIZE]>);
+
+impl CharAllocator {
+ pub const fn new() -> Self {
+ Self(NullLock::new([CharCell::new(); CHAR_POOL_SIZE]))
+ }
+
+ pub fn init(&self) {
+ self.0.lock(|char_pool| {
+ for idx in 2..CHAR_POOL_SIZE {
+ if idx != CHAR_POOL_SIZE - 1 {
+ char_pool[idx].next = Some(&mut char_pool[idx+1] as *mut CharCell);
+ } else {
+ char_pool[idx].next = None;
+ }
+ }
+ char_pool[0].next = Some(&mut char_pool[2] as *mut CharCell);
+ char_pool[1].next = Some(&mut char_pool[CHAR_POOL_SIZE-1] as *mut CharCell);
+ });
+ }
+
+ pub fn alloc(&self) -> Option<&mut CharCell> {
+ return self.0.lock(|char_pool| {
+ if let Some(char_cell) = char_pool[0].next {
+ char_pool[0].next = unsafe{(*char_cell).next};
+ unsafe {
+ (*char_cell).next = None;
+ }
+ return Some(unsafe{&mut *char_cell as &mut CharCell});
+ } else {
+ return None;
+ }
+ });
+ }
+
+ pub fn free(&self, cell: &mut CharCell) {
+ self.0.lock(|char_pool| {
+ cell.next = None;
+ match char_pool[1].next {
+ None => {
+ char_pool[0].next = Some(cell as *mut CharCell);
+ }
+ Some(ocell) => {
+ unsafe {
+ (*ocell).next = Some(cell as *mut CharCell);
+ }
+ }
+ }
+ char_pool[1].next = Some(cell as *mut CharCell);
+ });
+ }
+}
+
+impl Debug for CharAllocator {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ self.0.lock(|pool| {
+ write!(f, "{:?}", pool)
+ })
+ }
+}
+
+pub static CHAR_ALLOCATOR: CharAllocator = CharAllocator::new();