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            // we don't want really small wasted slices
60            // we must assign free_list_start
61            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 { // the memory allocated was not the entire range of items. Split and move on
73            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}