lib/gpalloc/src/large/medium/class.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const size_class = @import("../../root.zig").class;
3 const model = @import("../root.zig").model;
4
5 const Alignment = std.mem.Alignment;
6 const Class = model.Class;
7
8 pub fn classFor(len: usize, requested_alignment: Alignment) ?Class {
9 if (requested_alignment.toByteUnits() > size_class.min_alignment) return null;
10 if (len <= model.max_small_cached_size or len > model.max_medium_cached_size) return null;
11 const class_size = std.mem.alignForward(usize, len, model.medium_class_step);
12 if (class_size < model.min_medium_cached_size or class_size > model.max_medium_cached_size) return null;
13 return .{
14 .index = (class_size - model.min_medium_cached_size) / model.medium_class_step,
15 .size = class_size,
16 };
17 }
18
19 pub fn backingSize(class: Class) usize {
20 return backingSizeForClassSize(class.size);
21 }
22
23 pub fn classForIndex(index: usize) Class {
24 return .{
25 .index = index,
26 .size = sizeForIndex(index),
27 };
28 }
29
30 pub fn sizeForIndex(index: usize) usize {
31 return model.min_medium_cached_size + index * model.medium_class_step;
32 }
33
34 pub fn backingSizeForClassSize(class_size: usize) usize {
35 return class_size + model.header_size;
36 }
37
38 test "medium cache classes cover Barnes page-run sizes" {
39 try std.testing.expect(classFor(model.max_small_cached_size, .@"1") == null);
40 try std.testing.expectEqual(
41 @as(usize, 320 * 1024),
42 classFor(model.max_small_cached_size + 1, .@"1").?.size,
43 );
44 try std.testing.expectEqual(
45 @as(usize, 448 * 1024),
46 classFor(400 * 1024, .@"1").?.size,
47 );
48 try std.testing.expectEqual(
49 @as(usize, 512 * 1024),
50 classFor(model.max_medium_cached_size, .@"1").?.size,
51 );
52 try std.testing.expect(classFor(model.max_medium_cached_size + 1, .@"1") == null);
53 try std.testing.expect(classFor(400 * 1024, .fromByteUnits(32)) == null);
54 }