@@ -11,11 +11,20 @@ const free_list_count: usize = 6;
11
11
12
12
const Alloc = @This ();
13
13
14
+ /// The lists of free chunks.
14
15
free_lists : [free_list_count ]? * Chunk = @splat (null ),
15
16
17
+ /// The beginning address of the memory region that can be allocated from.
16
18
low_boundary : usize ,
19
+
20
+ /// The next address beyond the highest address of the memory region can allocated from.
17
21
high_boundary : usize ,
18
22
23
+ /// An optional fallback allocator that is used when the allocator runs out of memory.
24
+ /// This allows allocation from multiple disjoint memory regions.
25
+ fallback : ? * Alloc = null ,
26
+
27
+ /// A mutex used to protect access to the allocator.
19
28
mutex : microzig.interrupt.Mutex = .{},
20
29
21
30
/// Return a []u8 slice that contains the memory located between the
@@ -152,7 +161,7 @@ const vtable: std.mem.Allocator.VTable =
152
161
///
153
162
/// Returns:
154
163
/// - `?[*]u8`: A pointer to the allocated memory, or null if insufficient memory is available
155
- fn do_alloc (ptr : * anyopaque , len : usize , alignment : Alignment , _ : usize ) ? [* ]u8 {
164
+ fn do_alloc (ptr : * anyopaque , len : usize , alignment : Alignment , pc : usize ) ? [* ]u8 {
156
165
const self : * Alloc = @ptrCast (@alignCast (ptr ));
157
166
158
167
self .mutex .lock ();
@@ -241,6 +250,10 @@ fn do_alloc(ptr: *anyopaque, len: usize, alignment: Alignment, _: usize) ?[*]u8
241
250
free_index += 1 ;
242
251
}
243
252
253
+ if (self .fallback ) | f | {
254
+ return do_alloc (f , len , alignment , pc );
255
+ }
256
+
244
257
return null ;
245
258
}
246
259
@@ -307,9 +320,19 @@ fn do_resize(ptr: *anyopaque, memory: []u8, _: Alignment, new_len: usize, _: usi
307
320
///
308
321
/// Parameters:
309
322
/// - `memory` : The memory to free
310
- fn do_free (ptr : * anyopaque , memory : []u8 , _ : Alignment , _ : usize ) void {
323
+ fn do_free (ptr : * anyopaque , memory : []u8 , alignment : Alignment , pc : usize ) void {
311
324
const self : * Alloc = @ptrCast (@alignCast (ptr ));
312
325
326
+ const addr = @intFromPtr (memory .ptr );
327
+ if (addr < self .low_boundary or addr >= self .high_boundary ) {
328
+ if (self .fallback ) | f | {
329
+ do_free (f , memory , alignment , pc );
330
+ return ;
331
+ }
332
+
333
+ @panic ("free - address is not in range" );
334
+ }
335
+
313
336
self .mutex .lock ();
314
337
defer self .mutex .unlock ();
315
338
0 commit comments