lib/gpalloc/src/large/header.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 const size_class = @import("../root.zig").class;
 3 const class_policy = @import("class.zig");
 4 const model = @import("model.zig");
 5 
 6 const Class = model.Class;
 7 const Header = model.Header;
 8 
 9 pub fn initializeHeader(base: [*]u8, class: Class) [*]u8 {
10     const header: *Header = @ptrCast(@alignCast(base));
11     header.* = .{
12         .magic = model.header_magic,
13         .class_index = class.index,
14     };
15     return base + model.header_size;
16 }
17 
18 pub fn headerFromUserPointer(ptr: [*]u8) *Header {
19     return @ptrCast(@alignCast(ptr - model.header_size));
20 }
21 
22 pub fn classFromHeader(header: *const Header) ?Class {
23     if (header.magic != model.header_magic) return null;
24     if (header.class_index >= model.class_count) return null;
25     return class_policy.classForIndex(header.class_index);
26 }
27 
28 pub fn baseFromUserPointer(ptr: [*]u8) [*]u8 {
29     return ptr - model.header_size;
30 }
31 
32 test "large cache header stores only class identity" {
33     try std.testing.expectEqual(@as(usize, size_class.min_alignment), model.header_size);
34     const class = class_policy.classFor(size_class.max_small_size + 1, .@"1").?;
35     const storage_len = model.header_size + size_class.min_alignment;
36     var storage: [storage_len]u8 align(size_class.min_alignment) = undefined;
37     const user = initializeHeader(&storage, class);
38     try std.testing.expectEqual(@intFromPtr(&storage) + model.header_size, @intFromPtr(user));
39     try std.testing.expectEqual(class.index, classFromHeader(headerFromUserPointer(user)).?.index);
40 
41     var invalid: Header = .{ .magic = model.header_magic, .class_index = model.class_count };
42     try std.testing.expect(classFromHeader(&invalid) == null);
43     invalid = .{ .magic = 0, .class_index = class.index };
44     try std.testing.expect(classFromHeader(&invalid) == null);
45 }