1
1
use crate :: { debug, memory:: PAGE_SIZE } ;
2
- use core:: {
3
- fmt:: Debug ,
4
- ops:: Range ,
5
- ptr:: { null_mut, NonNull } ,
6
- } ;
2
+ use core:: { fmt:: Debug , ops:: Range , ptr:: NonNull } ;
7
3
8
4
use super :: page:: Page ;
9
5
@@ -30,14 +26,7 @@ impl<'a> Debug for MetadataPageAllocator<'a> {
30
26
}
31
27
32
28
impl < ' a > MetadataPageAllocator < ' a > {
33
- pub ( super ) const fn new ( ) -> Self {
34
- Self {
35
- metadata : & mut [ ] ,
36
- pages : null_mut ( ) ..null_mut ( ) ,
37
- }
38
- }
39
-
40
- pub ( super ) fn init ( & mut self , memory : & ' a mut [ u8 ] ) {
29
+ pub ( super ) fn new ( memory : & ' a mut [ u8 ] ) -> Self {
41
30
let heap_size = memory. len ( ) ;
42
31
let number_of_heap_pages = heap_size / ( PAGE_SIZE + 1 ) ; // We need one byte per page as metadata
43
32
@@ -57,14 +46,14 @@ impl<'a> MetadataPageAllocator<'a> {
57
46
58
47
metadata. iter_mut ( ) . for_each ( |x| * x = PageStatus :: Free ) ;
59
48
60
- self . metadata = metadata;
61
-
62
- self . pages = heap. as_mut_ptr_range ( ) ;
49
+ let pages = heap. as_mut_ptr_range ( ) ;
63
50
64
51
debug ! ( "Page allocator initalized" ) ;
65
- debug ! ( "Metadata start:\t \t {:p}" , self . metadata) ;
66
- debug ! ( "Heap start:\t \t {:p}" , self . pages. start) ;
67
- debug ! ( "Number of pages:\t {}\n " , self . total_heap_pages( ) ) ;
52
+ debug ! ( "Metadata start:\t \t {:p}" , metadata) ;
53
+ debug ! ( "Heap start:\t \t {:p}" , pages. start) ;
54
+ debug ! ( "Number of pages:\t {}\n " , metadata. len( ) ) ;
55
+
56
+ Self { metadata, pages }
68
57
}
69
58
70
59
fn total_heap_pages ( & self ) -> usize {
@@ -134,53 +123,31 @@ pub trait PageAllocator {
134
123
135
124
#[ cfg( test) ]
136
125
mod tests {
137
- use core:: {
138
- ops:: Range ,
139
- ptr:: { addr_of_mut, NonNull } ,
140
- } ;
141
-
142
- use common:: mutex:: Mutex ;
126
+ use core:: ptr:: addr_of_mut;
143
127
144
128
use crate :: memory:: page_allocator:: PageStatus ;
145
129
146
- use super :: { MetadataPageAllocator , Page , PAGE_SIZE } ;
130
+ use super :: { MetadataPageAllocator , PAGE_SIZE } ;
147
131
148
132
static mut PAGE_ALLOC_MEMORY : [ u8 ; PAGE_SIZE * 8 ] = [ 0 ; PAGE_SIZE * 8 ] ;
149
- static PAGE_ALLOC : Mutex < MetadataPageAllocator > = Mutex :: new ( MetadataPageAllocator :: new ( ) ) ;
150
133
151
- fn init_allocator ( ) {
152
- unsafe {
153
- PAGE_ALLOC
154
- . lock ( )
155
- . init ( & mut * addr_of_mut ! ( PAGE_ALLOC_MEMORY ) ) ;
156
- }
157
- }
158
-
159
- fn alloc ( number_of_pages : usize ) -> Option < Range < NonNull < Page > > > {
160
- PAGE_ALLOC . lock ( ) . alloc ( number_of_pages)
161
- }
162
-
163
- fn dealloc ( pages : Range < NonNull < Page > > ) {
164
- PAGE_ALLOC . lock ( ) . dealloc ( pages. start )
134
+ fn create_allocator ( ) -> MetadataPageAllocator < ' static > {
135
+ unsafe { MetadataPageAllocator :: new ( & mut * addr_of_mut ! ( PAGE_ALLOC_MEMORY ) ) }
165
136
}
166
137
167
138
#[ test_case]
168
139
fn clean_start ( ) {
169
- init_allocator ( ) ;
170
- assert ! ( PAGE_ALLOC
171
- . lock( )
172
- . metadata
173
- . iter( )
174
- . all( |s| * s == PageStatus :: Free ) ) ;
140
+ let allocator = create_allocator ( ) ;
141
+ assert ! ( allocator. metadata. iter( ) . all( |s| * s == PageStatus :: Free ) ) ;
175
142
}
176
143
177
144
#[ test_case]
178
145
fn exhaustion_allocation ( ) {
179
- init_allocator ( ) ;
180
- let number_of_pages = PAGE_ALLOC . lock ( ) . total_heap_pages ( ) ;
181
- let _pages = alloc ( number_of_pages) . unwrap ( ) ;
182
- assert ! ( alloc( 1 ) . is_none( ) ) ;
183
- let allocator = PAGE_ALLOC . lock ( ) ;
146
+ let mut allocator = create_allocator ( ) ;
147
+ let number_of_pages = allocator . total_heap_pages ( ) ;
148
+ let _pages = allocator . alloc ( number_of_pages) . unwrap ( ) ;
149
+ assert ! ( allocator . alloc( 1 ) . is_none( ) ) ;
150
+ let allocator = allocator ;
184
151
let ( last, all_metadata_except_last) = allocator. metadata . split_last ( ) . unwrap ( ) ;
185
152
assert ! ( all_metadata_except_last
186
153
. iter( )
@@ -190,41 +157,41 @@ mod tests {
190
157
191
158
#[ test_case]
192
159
fn beyond_capacity ( ) {
193
- init_allocator ( ) ;
194
- let number_of_pages = PAGE_ALLOC . lock ( ) . total_heap_pages ( ) ;
195
- let pages = alloc ( number_of_pages + 1 ) ;
160
+ let mut allocator = create_allocator ( ) ;
161
+ let number_of_pages = allocator . total_heap_pages ( ) ;
162
+ let pages = allocator . alloc ( number_of_pages + 1 ) ;
196
163
assert ! ( pages. is_none( ) ) ;
197
164
}
198
165
199
166
#[ test_case]
200
167
fn all_single_allocations ( ) {
201
- init_allocator ( ) ;
202
- let number_of_pages = PAGE_ALLOC . lock ( ) . total_heap_pages ( ) ;
168
+ let mut allocator = create_allocator ( ) ;
169
+ let number_of_pages = allocator . total_heap_pages ( ) ;
203
170
for _ in 0 ..number_of_pages {
204
- assert ! ( alloc( 1 ) . is_some( ) ) ;
171
+ assert ! ( allocator . alloc( 1 ) . is_some( ) ) ;
205
172
}
206
- assert ! ( alloc( 1 ) . is_none( ) ) ;
173
+ assert ! ( allocator . alloc( 1 ) . is_none( ) ) ;
207
174
}
208
175
209
176
#[ test_case]
210
177
fn metadata_integrity ( ) {
211
- init_allocator ( ) ;
212
- let page1 = alloc ( 1 ) . unwrap ( ) ;
213
- assert_eq ! ( PAGE_ALLOC . lock ( ) . metadata[ 0 ] , PageStatus :: Last ) ;
214
- assert ! ( PAGE_ALLOC . lock ( ) . metadata[ 1 ..]
178
+ let mut allocator = create_allocator ( ) ;
179
+ let page1 = allocator . alloc ( 1 ) . unwrap ( ) ;
180
+ assert_eq ! ( allocator . metadata[ 0 ] , PageStatus :: Last ) ;
181
+ assert ! ( allocator . metadata[ 1 ..]
215
182
. iter( )
216
183
. all( |s| * s == PageStatus :: Free ) ) ;
217
- let page2 = alloc ( 2 ) . unwrap ( ) ;
184
+ let page2 = allocator . alloc ( 2 ) . unwrap ( ) ;
218
185
assert_eq ! (
219
- PAGE_ALLOC . lock ( ) . metadata[ ..3 ] ,
186
+ allocator . metadata[ ..3 ] ,
220
187
[ PageStatus :: Last , PageStatus :: Used , PageStatus :: Last ]
221
188
) ;
222
- assert ! ( PAGE_ALLOC . lock ( ) . metadata[ 3 ..]
189
+ assert ! ( allocator . metadata[ 3 ..]
223
190
. iter( )
224
191
. all( |s| * s == PageStatus :: Free ) ) ;
225
- let page3 = alloc ( 3 ) . unwrap ( ) ;
192
+ let page3 = allocator . alloc ( 3 ) . unwrap ( ) ;
226
193
assert_eq ! (
227
- PAGE_ALLOC . lock ( ) . metadata[ ..6 ] ,
194
+ allocator . metadata[ ..6 ] ,
228
195
[
229
196
PageStatus :: Last ,
230
197
PageStatus :: Used ,
@@ -234,12 +201,12 @@ mod tests {
234
201
PageStatus :: Last
235
202
]
236
203
) ;
237
- assert ! ( PAGE_ALLOC . lock ( ) . metadata[ 6 ..]
204
+ assert ! ( allocator . metadata[ 6 ..]
238
205
. iter( )
239
206
. all( |s| * s == PageStatus :: Free ) , ) ;
240
- dealloc ( page2) ;
207
+ allocator . dealloc ( page2. start ) ;
241
208
assert_eq ! (
242
- PAGE_ALLOC . lock ( ) . metadata[ ..6 ] ,
209
+ allocator . metadata[ ..6 ] ,
243
210
[
244
211
PageStatus :: Last ,
245
212
PageStatus :: Free ,
@@ -249,9 +216,9 @@ mod tests {
249
216
PageStatus :: Last
250
217
]
251
218
) ;
252
- dealloc ( page1) ;
219
+ allocator . dealloc ( page1. start ) ;
253
220
assert_eq ! (
254
- PAGE_ALLOC . lock ( ) . metadata[ ..6 ] ,
221
+ allocator . metadata[ ..6 ] ,
255
222
[
256
223
PageStatus :: Free ,
257
224
PageStatus :: Free ,
@@ -261,9 +228,9 @@ mod tests {
261
228
PageStatus :: Last
262
229
]
263
230
) ;
264
- dealloc ( page3) ;
231
+ allocator . dealloc ( page3. start ) ;
265
232
assert_eq ! (
266
- PAGE_ALLOC . lock ( ) . metadata[ ..6 ] ,
233
+ allocator . metadata[ ..6 ] ,
267
234
[
268
235
PageStatus :: Free ,
269
236
PageStatus :: Free ,
0 commit comments