1#[macro_export]
2macro_rules! static_array {
3 (@accum (0, $($_ignored:expr),*) -> ($($body:tt)*))
4 => {static_array!(@as_expr [$($body)*])};
5 (@accum (1, $($expr:expr),*) -> ($($body:tt)*))
6 => {static_array!(@accum (0, $($expr),*) -> ($($body)* $($expr,)*))};
7 (@accum (2, $($expr:expr),*) -> ($($body:tt)*))
8 => {static_array!(@accum (0, $($expr),*) -> ($($body)* $($expr,)* $($expr,)*))};
9 (@accum (4, $($expr:expr),*) -> ($($body:tt)*))
10 => {static_array!(@accum (2, $($expr,)* $($expr),*) -> ($($body)*))};
11 (@accum (8, $($expr:expr),*) -> ($($body:tt)*))
12 => {static_array!(@accum (4, $($expr,)* $($expr),*) -> ($($body)*))};
13 (@accum (16, $($expr:expr),*) -> ($($body:tt)*))
14 => {static_array!(@accum (8, $($expr,)* $($expr),*) -> ($($body)*))};
15 (@accum (32, $($expr:expr),*) -> ($($body:tt)*))
16 => {static_array!(@accum (16, $($expr,)* $($expr),*) -> ($($body)*))};
17 (@accum (64, $($expr:expr),*) -> ($($body:tt)*))
18 => {static_array!(@accum (32, $($expr,)* $($expr),*) -> ($($body)*))};
19 (@accum (128, $($expr:expr),*) -> ($($body:tt)*))
20 => {static_array!(@accum (64, $($expr,)* $($expr),*) -> ($($body)*))};
21 (@accum (256, $($expr:expr),*) -> ($($body:tt)*))
22 => {static_array!(@accum (128, $($expr,)* $($expr),*) -> ($($body)*))};
23 (@accum (512, $($expr:expr),*) -> ($($body:tt)*))
24 => {static_array!(@accum (256, $($expr,)* $($expr),*) -> ($($body)*))};
25 (@accum (1024, $($expr:expr),*) -> ($($body:tt)*))
26 => {static_array!(@accum (512, $($expr,)* $($expr),*) -> ($($body)*))};
27 (@accum (2048, $($expr:expr),*) -> ($($body:tt)*))
28 => {static_array!(@accum (1024, $($expr,)* $($expr),*) -> ($($body)*))};
29 (@accum (4096, $($expr:expr),*) -> ($($body:tt)*))
30 => {static_array!(@accum (2048, $($expr,)* $($expr),*) -> ($($body)*))};
31 (@accum (8192, $($expr:expr),*) -> ($($body:tt)*))
32 => {static_array!(@accum (4096, $($expr,)* $($expr),*) -> ($($body)*))};
33
34 (@as_expr $expr:expr) => {$expr};
35
36 ($expr:expr; $n:tt) => { static_array!(@accum ($n, $expr) -> ()) };
37}
38
39
40#[macro_export]
41macro_rules! define_stack_allocator_traits(
42 ($name : ident, global) => {
43 impl<'a, T: 'a> Default for $name<'a, T> {
44 fn default() -> Self {
45 return $name::<'a, T>{freelist : &mut[],};
46 }
47 }
48 define_stack_allocator_traits!($name, generic);
49 };
50 ($name : ident, $freelist_size : tt, stack) => {
51 impl<'a, T: 'a> Default for $name<'a, T> {
52 fn default() -> Self {
53 return $name::<'a, T>{freelist : static_array!(&mut[]; $freelist_size)};
54 }
55 }
56 define_stack_allocator_traits!($name, generic);
57 };
58 ($name : ident, heap) => {
59 impl<'a, T: 'a> Default for $name<'a, T> {
60 fn default() -> Self {
61 let v : Vec<&mut [T]> = Vec::new();
62 let b = v.into_boxed_slice();
63 return $name::<'a, T>{freelist : b};
64 }
65 }
66 define_stack_allocator_traits!($name, generic);
67 };
68 ($name : ident, $freelist_size : tt, malloc) => {
69 define_stack_allocator_traits!($name, calloc);
70 };
71 ($name : ident, $freelist_size : tt, calloc) => {
72
73 impl<'a, T: 'a> Default for $name<'a, T> {
74 fn default() -> Self {
75 return $name::<'a, T>{freelist : static_array!(&mut[]; $freelist_size)};
76 }
77 }
78 define_stack_allocator_traits!($name, generic);
79 };
80 ($name : ident, generic) => {
81 impl<'a, T: 'a> SliceWrapper<&'a mut[T]> for $name<'a, T> {
82 fn slice(& self) -> & [&'a mut[T]] {
83 return & self.freelist;
84 }
85 }
86 impl<'a, T: 'a> SliceWrapperMut<&'a mut [T]> for $name<'a, T> {
87 fn slice_mut(& mut self) ->&mut [&'a mut [T]] {
88 return &mut self.freelist;
89 }
90 }
91 impl<'a, T: 'a> ops::Index<usize> for $name<'a, T> {
92 type Output = [T];
93 fn index<'b> (&'b self, _index : usize) -> &'b [T] {
94 return &self.freelist[_index];
95 }
96 }
97
98 impl<'a, T: 'a> ops::IndexMut<usize> for $name<'a, T> {
99 fn index_mut<'b>(&'b mut self, _index : usize) -> &'b mut [T] {
100 return &mut self.freelist[_index];
101 }
102 }
103 };
104);
105
106#[macro_export]
107macro_rules! declare_stack_allocator_struct(
108 (@as_expr $expr : expr) => {$expr};
109 (@new_method $name : ident, $freelist_size : tt) => {
110 impl<'a, T: 'a> $name<'a, T> {
111 fn new_allocator(global_buffer : &'a mut [T],
112 initializer : fn(&mut[T])) -> StackAllocator<'a, T, $name<'a, T> > {
113 let mut retval = StackAllocator::<T, $name<T> > {
114 nop : &mut [],
115 system_resources : $name::<T>::default(),
116 free_list_start : declare_stack_allocator_struct!(@as_expr $freelist_size),
117 free_list_overflow_count : 0,
118 initialize : initializer,
119 };
120 retval.free_cell(AllocatedStackMemory::<T>{mem:global_buffer});
121 return retval;
122 }
123 }
124 };
125
126 (@new_calloc_method $name : ident, $freelist_size : tt) => {
127 impl<'a, T: 'a> $name<'a, T> {
128 fn new_allocator(mut global_buffer : &'a mut [T],
129 initializer : fn(&mut[T])) -> StackAllocator<'a, T, $name<'a, T> > {
130 let mut retval = StackAllocator::<T, $name<T> > {
131 nop : &mut [],
132 system_resources : $name::<T>::default(),
133 free_list_start : declare_stack_allocator_struct!(@as_expr $freelist_size),
134 free_list_overflow_count : 0,
135 initialize : initializer,
136 };
137 retval.free_cell(AllocatedStackMemory::<T>{mem:core::mem::replace(&mut global_buffer, &mut[])});
138 return retval;
139 }
140 }
141 };
142 ($name :ident, $freelist_size : tt, malloc) => {
143 declare_stack_allocator_struct!($name, $freelist_size, calloc);
144 };
145 ($name :ident, $freelist_size : tt, calloc) => {
146 struct $name<'a, T : 'a> {
147 freelist : [&'a mut [T]; declare_stack_allocator_struct!(@as_expr $freelist_size)],
148 }
149 define_stack_allocator_traits!($name,
150 $freelist_size,
151 calloc);
152 declare_stack_allocator_struct!( @new_calloc_method $name, $freelist_size);
153 };
154 ($name :ident, $freelist_size : tt, stack) => {
155 struct $name<'a, T : 'a> {
156 freelist : [&'a mut [T];declare_stack_allocator_struct!(@as_expr $freelist_size)],
157 }
159 define_stack_allocator_traits!($name,
160 $freelist_size,
161 stack);
162 declare_stack_allocator_struct!( @new_method $name, $freelist_size);
163 };
164 ($name :ident, $freelist_size : expr, global) => {
165 struct $name <'a, T: 'a> {freelist : &'a mut [&'a mut [T]]}
166 define_stack_allocator_traits!($name, global);
167 impl<'a, T: 'a> $name<'a, T> {
168 fn new_allocator(initializer : fn (&mut[T])) -> StackAllocator<'a, T, $name<'a, T> > {
169 return StackAllocator::<T, $name<T> > {
170 nop : &mut [],
171 system_resources : $name::<T>::default(),
172 free_list_start : 0,
173 free_list_overflow_count : 0,
174 initialize : initializer,
175 };
176 }
177 }
178 };
179);
180#[macro_export]
181macro_rules! bind_global_buffers_to_allocator(
182 ($allocator : expr, $buffer : ident, $T : ty) => {
183 $allocator.free_list_start = $buffer::FREELIST.len();
184 $allocator.system_resources.freelist = &mut $buffer::FREELIST;
185 $allocator.free_cell(AllocatedStackMemory::<$T>{mem:&mut $buffer::HEAP});
186 };
187);
188
189#[macro_export]
190macro_rules! define_allocator_memory_pool(
191 (@as_expr $expr:expr) => {$expr};
192
193
194 ($freelist_size : tt, $T : ty, [0; $heap_size : expr], calloc) => {
195 alloc_no_stdlib::CallocBackingStore::<$T>::new($heap_size, alloc_no_stdlib::AllocatorC::Calloc(calloc), free, true);
196 };
197 ($freelist_size : tt, $T : ty, [0; $heap_size : expr], calloc_no_free) => {
198 alloc_no_stdlib::CallocBackingStore::<$T>::new($heap_size, alloc_no_stdlib::AllocatorC::Calloc(calloc), free, false);
199 };
200 ($freelist_size : tt, $T : ty, [0; $heap_size : expr], malloc) => {
201 alloc_no_stdlib::CallocBackingStore::<$T>::new($heap_size, alloc_no_stdlib::AllocatorC::Malloc(malloc), free, true);
202 };
203 ($freelist_size : tt, $T : ty, [0; $heap_size : expr], malloc_no_free) => {
204 alloc_no_stdlib::CallocBackingStore::<$T>::new($heap_size, alloc_no_stdlib::AllocatorC::Malloc(malloc), free, false);
205 };
206 ($freelist_size : tt, $T : ty, [$default_value : expr; $heap_size : expr], heap) => {
207 (vec![$default_value; $heap_size]).into_boxed_slice();
208 };
209 ($freelist_size : tt, $T : ty, [$default_value : expr; $heap_size : expr], stack) => {
210 [$default_value; $heap_size];
211 };
212 ($freelist_size : tt, $T : ty, [$default_value : expr; $heap_size : expr], global, $name : ident) => {
213 pub mod $name {
214 pub static mut FREELIST : [&'static mut [$T];
215 define_allocator_memory_pool!(@as_expr $freelist_size)]
216 = static_array!(&mut[]; $freelist_size);
217 pub static mut HEAP : [$T; $heap_size] = [$default_value; $heap_size];
218 }
219 };
220
221);
222
223