@@ -17,6 +17,7 @@ const Err_T: type = if(!builtin.is_test) @import("root").lib.memory.allocator.Er
1717 AlreadyInitialized ,
1818 NoNInitialized ,
1919 InternalError ,
20+ DoubleFree ,
2021};
2122
2223const VTable_T : type = if (! builtin .is_test ) @import ("root" ).lib .memory .allocator .VTable_T else struct {
@@ -88,7 +89,6 @@ pub fn buildByteAllocator(
8889 bytes : usize = 0 ,
8990 size : usize = block_size ,
9091 blocks : usize = vector_blocks ,
91- bmarks : usize = 0 ,
9292 } else void ;
9393
9494 const block_size : comptime_int = block orelse default_block_size ;
@@ -172,8 +172,9 @@ pub fn buildByteAllocator(
172172 }
173173
174174 inline fn outbounds (self : * @This (), ptr : []u8 ) Err_T ! void {
175- return if ((@intFromPtr (ptr .ptr ) - @intFromPtr (self .pool .? )) > total_bytes_of_pool ) Err_T .IndexOutBounds else
176- {};
175+ return if ((@intFromPtr (ptr .ptr ) > @intFromPtr (& self .pool .? [comptime (total_bytes_of_pool - 1 )]))
176+ or @intFromPtr (ptr .ptr ) < @intFromPtr (& self .pool .? [0 ])) Err_T .IndexOutBounds else
177+ {};
177178 }
178179
179180 inline fn empty (self : * @This ()) bool {
@@ -239,6 +240,8 @@ pub fn buildByteAllocator(
239240 const initial_block_index : usize = (@intFromPtr (ptr .ptr ) - @intFromPtr (self .pool .? )) / block_size ;
240241
241242 for (0.. blocks ) | i | {
243+ if (self .bitmap [initial_block_index + i ] == 1 )
244+ return Err_T .DoubleFree ;
242245 self .bitmap [initial_block_index + i ] = 1 ;
243246 }
244247 self .flags .full = 0 ;
@@ -328,6 +331,7 @@ pub fn buildByteAllocator(
328331 const child_pool : Pool_T = current_pool .child ().* ;
329332 try current_pool .deinit ();
330333 current_pool .* = child_pool ;
334+ current_pool .prev = null ;
331335 } else {
332336 @as (* Pool_T , @alignCast (@ptrCast (& current_pool .prev .? .pool .? [0 ]))).*
333337 = @as (* Pool_T , @alignCast (@ptrCast (& current_pool .pool .? [0 ]))).* ;
@@ -407,12 +411,45 @@ test "Full Alloc" {
407411}
408412
409413test "Full Free" {
410-
414+ var sba = buildByteAllocator (null , .{
415+ .resize = false ,
416+ .debug = true ,
417+ }) {};
418+
419+ const BitmapInt_T : type = @Type (.{
420+ .int = .{
421+ .bits = @truncate (total_bytes_of_pool_test / 16 ),
422+ .signedness = .unsigned ,
423+ },
424+ });
425+
426+ var allocator = sba .allocator ();
427+ try allocator .init ();
428+
429+ var allocs : [256 ][]u8 = undefined ;
430+ for (0.. sba .debug .blocks ) | i | {
431+ allocs [i ] = try allocator .alloc (u8 , 1 );
432+ }
433+
434+ for (0.. sba .debug .blocks ) | i | {
435+ try allocator .free (
436+ allocs [i ]
437+ );
438+ allocator .free (allocs [i ]) catch | err | switch (err ) {
439+ Err_T .DoubleFree = > continue ,
440+ else = > return err ,
441+ };
442+ return error .NoNDoubleFree ;
443+ }
444+
445+ if (~ @as (BitmapInt_T , @bitCast (sba .root .bitmap )) != 0 ) return error .BusyBlock ;
446+ if (sba .debug .allocs != 0 ) return error .HaveAllocs ;
447+ if (sba .debug .bytes != 0 ) return error .HaveBytes ;
411448}
412449
413450// TEST WITH RESIZE
414451
415- test "Resized Full Alloc" {
452+ test "Resized Full Alloc And Free " {
416453 var sba = buildByteAllocator (null , .{
417454 .resize = true ,
418455 .debug = true ,
@@ -421,13 +458,22 @@ test "Resized Full Alloc" {
421458 var allocator = sba .allocator ();
422459 try allocator .init ();
423460
424- var current : []u8 = undefined ;
425-
426- for (0.. sba .debug .blocks * 12 ) | _ | {
427- current = try allocator .alloc (u8 , 1 );
461+ var allocs : [256 * 12 ][]u8 = undefined ;
462+ for (0.. sba .debug .blocks * 12 ) | i | {
463+ allocs [i ] = try allocator .alloc (u8 , 1 );
428464 }
429465
430- if (sba .debug .pools != 12 )
431- return error .ResizeMiss ;
432- try allocator .deinit ();
466+ if (sba .debug .pools != 12 ) return error .ResizeMiss ;
467+ if (sba .debug .bytes != (sba .debug .blocks * 12 )) return error .ByteMiss ;
468+ if (sba .debug .allocs != (sba .debug .blocks * 12 )) return error .AllocMiss ;
469+
470+ for (0.. 12) | i | {
471+ const total_pool : usize = sba .debug .pools ;
472+ for (0.. 256) | j | {
473+ try allocator .free (
474+ allocs [(256 * i ) + j ]
475+ );
476+ }
477+ if ((total_pool - 1 ) != sba .debug .pools and total_pool > 1 ) return error .EmptyChildPool ;
478+ }
433479}
0 commit comments