Skip to content

Commit a703d57

Browse files
committed
added resize testing function for cpu_caching_allocator
1 parent 91f0ece commit a703d57

File tree

1 file changed

+92
-5
lines changed

1 file changed

+92
-5
lines changed

src/experimental/cpu_caching_allocator.zig

+92-5
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,6 @@ const OrderedCache = struct {
152152
}
153153
};
154154

155-
// Similar to the GeneralPurposeAllocator, the CachingAllocator
156-
// will support bit alignment within [1, 2048]. Each step up
157-
// in index will be equivalent to another power of two for
158-
// alignment. So tabl[0] : align 1, table[3] : align 4...
159-
160155
// I'm making a distinction for a CPU allocator because
161156
// other devices can use the caching allocator as well.
162157

@@ -485,3 +480,95 @@ test "CPUCachingAllocator: alignment" {
485480
item.y = false;
486481
}
487482
}
483+
484+
test "CPUCachingAllocator: resize" {
485+
486+
// So testing resize is tough. Resizes can "fail"
487+
// legitimately. That's why they return a bool and
488+
// not an error. Unfortunately, that means it's
489+
// awkward to test it directly.
490+
491+
// That said, we can keep a few things in mind:
492+
493+
// 1. The resize function dispatches to the
494+
// backing_allocator.rawResize function.
495+
// Therfore, we would technically be
496+
// testing that ultimately.
497+
498+
// 2. Because of 1, the only way we can be
499+
// the source of failure is by either
500+
// failing to find the memory in cache,
501+
// identifying the wrong memory, failing
502+
// to deposit the memory, or leaking the
503+
// memory after resize.
504+
505+
// At this point, the deposit function is well
506+
// established. So we need to show that the
507+
// search function locateMemory identifies the
508+
// correct memory in cache, and returns null
509+
// on invalid requests.
510+
511+
const rand = @import("std").rand;
512+
513+
const TypeA = struct {
514+
x: usize = 0
515+
};
516+
517+
var cpu_caching_allocator = CPUCachingAllocator{ };
518+
519+
defer cpu_caching_allocator.deinit();
520+
521+
var allocator = cpu_caching_allocator.allocator();
522+
523+
var PCG = rand.Pcg.init(42);
524+
var pcg = PCG.random();
525+
526+
// To test locateMemory, we'll allocate in 100
527+
// elements and force it to find the element after
528+
// depositing it.
529+
530+
for (0..100) |_| {
531+
532+
var n = pcg.int(usize) % 100;
533+
534+
n = if(n == 0) 1 else n;
535+
536+
var data = try allocator.alloc(TypeA, n);
537+
538+
// deposit into cache...
539+
allocator.free(data);
540+
541+
var check: []u8 = std.mem.sliceAsBytes(data);
542+
543+
// lookup memory in allocator cache...
544+
var index = cpu_caching_allocator.buffer.locateMemory(check);
545+
546+
// null means we didn't find it.
547+
try std.testing.expect(index != null);
548+
549+
var item = cpu_caching_allocator.buffer.itemData(index.?);
550+
551+
// ensure that it is the same data.
552+
try std.testing.expect(@intFromPtr(check.ptr) == @intFromPtr(item.ptr));
553+
}
554+
555+
// we need to be beyond the heuristic to test.
556+
var data = try allocator.alloc(TypeA, 300);
557+
558+
{ // check that un-cached memory isn't "found".
559+
var check: []u8 = std.mem.sliceAsBytes(data);
560+
var index = cpu_caching_allocator.buffer.locateMemory(check);
561+
try std.testing.expect(index == null);
562+
}
563+
564+
// deposit into cache...
565+
allocator.free(data);
566+
567+
{ // check that cached memory is found.
568+
var check: []u8 = std.mem.sliceAsBytes(data);
569+
var index = cpu_caching_allocator.buffer.locateMemory(check);
570+
try std.testing.expect(index != null);
571+
var item = cpu_caching_allocator.buffer.itemData(index.?);
572+
try std.testing.expect(@intFromPtr(check.ptr) == @intFromPtr(item.ptr));
573+
}
574+
}

0 commit comments

Comments
 (0)