alloc_no_stdlib/
stack_allocator.rs
1extern crate core;
2use super::allocated_memory;
3use super::allocated_stack_memory::AllocatedStackMemory;
4use super::SliceWrapper;
5
6pub trait Allocator<T> {
7 type AllocatedMemory : allocated_memory::AllocatedSlice<T>;
8 fn alloc_cell(&mut self, len : usize) -> Self::AllocatedMemory;
9 fn free_cell(&mut self, data : Self::AllocatedMemory);
10}
11
12
13pub struct StackAllocator<'a,
14 T :'a,
15 U : allocated_memory::AllocatedSlice<&'a mut [T]>> {
16 pub nop : &'a mut [T],
17 pub system_resources : U,
18 pub free_list_start : usize,
19 pub free_list_overflow_count : usize,
20 pub initialize : fn(&mut[T]),
21}
22
23impl <'a, T : 'a, U : allocated_memory::AllocatedSlice<&'a mut[T]> >
24 StackAllocator <'a, T, U> {
25 fn clear_if_necessary(self : &Self, index : usize, data : AllocatedStackMemory<'a, T>)
26 -> AllocatedStackMemory<'a, T> {
27 if index + 1 != self.system_resources.slice().len() {
28 let fnp = self.initialize;
29 fnp(data.mem);
30 }
31 return data;
32 }
33}
34impl<'a, T : 'a, U : allocated_memory::AllocatedSlice<&'a mut[T]> >
35 Allocator<T> for StackAllocator <'a, T, U> {
36 type AllocatedMemory = AllocatedStackMemory<'a, T>;
37 fn alloc_cell(self : &mut StackAllocator<'a, T, U>,
38 len : usize) -> AllocatedStackMemory<'a, T> {
39 if len == 0 {
40 return AllocatedStackMemory::<'a, T>::default();
41 }
42 let mut index : usize = self.free_list_start;
43 let mut found : bool = false;
44 for free_resource in self.system_resources.slice()[self.free_list_start..].iter() {
45 if free_resource.len() >= len {
46 found = true;
47 break;
48 }
49 index += 1;
50 }
51 if !found {
52 panic!("OOM");
53 }
54 let available_slice = core::mem::replace(&mut self.system_resources.slice_mut()[index],
55 &mut[]);
56 if available_slice.len() == len
57 || (available_slice.len() < len + 32
58 && index + 1 != self.system_resources.slice().len()) {
59 if index != self.free_list_start {
62 assert!(index > self.free_list_start);
63 let farthest_free_list = core::mem::replace(
64 &mut self.system_resources.slice_mut()[self.free_list_start],
65 &mut []);
66 let _ = core::mem::replace(&mut self.system_resources.slice_mut()[index],
67 farthest_free_list);
68 }
69 self.free_list_start += 1;
70 return self.clear_if_necessary(index,
71 AllocatedStackMemory::<'a, T>{mem:available_slice});
72 } else { let (retval, return_to_sender) = available_slice.split_at_mut(len);
74 let _ = core::mem::replace(&mut self.system_resources.slice_mut()[index], return_to_sender);
75 return self.clear_if_necessary(index, AllocatedStackMemory::<'a, T>{mem:retval});
76 }
77 }
78 fn free_cell(self : &mut StackAllocator<'a, T, U>,
79 val : AllocatedStackMemory<'a, T>) {
80 if val.slice().len() == 0 {
81 return;
82 }
83 if self.free_list_start > 0 {
84 self.free_list_start -=1;
85 let _ = core::mem::replace(&mut self.system_resources.slice_mut()[self.free_list_start],
86 val.mem);
87
88 } else {
89 for _i in 0..3 {
90 self.free_list_overflow_count += 1;
91 self.free_list_overflow_count %= self.system_resources.slice().len();
92 if self.system_resources.slice()[self.free_list_overflow_count].len() < val.mem.len() {
93 let _ = core::mem::replace(&mut self.system_resources.slice_mut()[self.free_list_overflow_count],
94 val.mem);
95 return;
96 }
97 }
98 }
99 }
100}