@@ -152,11 +152,6 @@ const OrderedCache = struct {
152
152
}
153
153
};
154
154
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
-
160
155
// I'm making a distinction for a CPU allocator because
161
156
// other devices can use the caching allocator as well.
162
157
@@ -485,3 +480,95 @@ test "CPUCachingAllocator: alignment" {
485
480
item .y = false ;
486
481
}
487
482
}
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