Last active
November 12, 2025 02:26
-
-
Save Tetralux/aa77d9d2f6d476ecdfa487220f2d92cb to your computer and use it in GitHub Desktop.
Use the custom allocator function of convhull3d
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define ZALLOCATOR_MODE_ALLOC 1 | |
| #define ZALLOCATOR_MODE_FREE 2 | |
| #define ZALLOCATOR_MODE_REALLOC 3 | |
| #define ZALLOCATOR_MODE_RESIZE 4 | |
| void *zallocator_interact(void *allocator, size_t mode, uint8_t should_zero, void *old_memory, size_t new_size); | |
| #define ch_stateful_malloc (ally, size) zallocator_interact(ally, ZALLOCATOR_MODE_ALLOC, false, NULL, size) | |
| #define ch_stateful_calloc (ally, size) zallocator_interact(ally, ZALLOCATOR_MODE_ALLOC, true, NULL, size) | |
| #define ch_stateful_realloc(ally, ptr, size) zallocator_interact(ally, ZALLOCATOR_MODE_REALLOC, false, ptr, size) | |
| #define ch_stateful_free (ally, ptr) (void)zallocator_interact(ally, ZALLOCATOR_MODE_FREE, false, ptr, 0) | |
| #define ch_stateful_resize (ally, ptr, size) zallocator_interact(ally, ZALLOCATOR_MODE_RESIZE, false, ptr, size) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pub fn main() !void { | |
| var gpa_state = std.heap.DebugAllocator({}){}; | |
| defer _ = gpa_state.deinit(); | |
| const gpa = gpa_state.allocator(); | |
| const vertices: []mmath.Vec3 = ...; | |
| var faces_ptr: ?[*]c_int = null; | |
| var faces_len: c_int = 0; | |
| c.convhull_3d_build_alloc(vertices.ptr, @intCast(vertices.len), &faces_ptr, &faces_len, &gpa); | |
| const faces = faces_ptr.?[0..faces_len]; // allocated with 'gpa' above | |
| defer gpa.free(faces); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const Zallocator_Mode = enum(usize) { | |
| alloc = 1, | |
| free = 2, | |
| realloc = 3, | |
| resize = 4, | |
| }; | |
| const Allocation = extern struct { | |
| size: usize, // number of bytes allocated after 'user_memory_start' field | |
| _pad: usize, // NOTE: align next field to same as malloc() | |
| user_memory_start: [0]u8, // the pointer handed out to fulfil allocations | |
| fn create(ally: std.mem.Allocator, size: usize) !*Allocation { | |
| const memory = try ally.alignedAlloc(u8, .fromByteUnits(2 * @alignOf(usize)), @sizeOf(Allocation) + size); | |
| const a: *Allocation = @ptrCast(memory.ptr); | |
| a.size = size; | |
| return a; | |
| } | |
| fn destroy(a: *Allocation, ally: std.mem.Allocator) void { | |
| ally.free(a.allocatedSlice()); | |
| } | |
| fn fromOldMemory(start_field: *anyopaque) *Allocation { | |
| const user_memory_start: *[0]u8 = @ptrCast(start_field); | |
| const a: *Allocation = @alignCast(@fieldParentPtr("user_memory_start", user_memory_start)); | |
| return a; | |
| } | |
| fn data(a: *Allocation) []u8 { | |
| const p: [*]u8 = @ptrCast(&a.user_memory_start); | |
| return p[0..a.size]; | |
| } | |
| fn allocatedSlice(a: *Allocation) []u8 { | |
| const p: [*]u8 = @ptrCast(a); | |
| return p[0 .. @sizeOf(Allocation) + a.size]; | |
| } | |
| }; | |
| export fn zallocator_interact(allocator: ?*anyopaque, mode_: Zallocator_Mode, zero: u8, old_memory: ?*anyopaque, new_size: usize) callconv(.c) ?*anyopaque { | |
| const ally: *std.mem.Allocator = @alignCast(@ptrCast(allocator orelse @panic("zallocator given null state"))); | |
| const mode = if(mode_ == .resize and old_memory == null) .alloc else mode_; | |
| switch (mode) { | |
| .alloc => { | |
| const allocation = Allocation.create(ally.*, new_size) catch return null; | |
| if (zero > 0) @memset(allocation.data(), 0); | |
| return &allocation.user_memory_start; | |
| }, | |
| .free => { | |
| const allocation = Allocation.fromOldMemory(old_memory orelse return null); | |
| allocation.destroy(ally.*); | |
| return null; | |
| }, | |
| .resize => { | |
| const allocation = Allocation.fromOldMemory(old_memory orelse @panic("zallocator asked to resize without old memory")); | |
| if (ally.rawResize(allocation.allocatedSlice(), .fromByteUnits(2 * @alignOf(usize)), @sizeOf(Allocation) + new_size, @returnAddress())) { | |
| allocation.size = new_size; | |
| return &allocation.user_memory_start; | |
| } | |
| return null; | |
| }, | |
| .realloc => { | |
| const allocation = Allocation.fromOldMemory(old_memory orelse @panic("zallocator asked to realloc without old memory")); | |
| const new_total_size = @sizeOf(Allocation) + new_size; | |
| const new_ptr = ally.rawRemap(allocation.allocatedSlice(), .fromByteUnits(2 * @alignOf(usize)), new_total_size, @returnAddress()) orelse return null; | |
| const new_memory = new_ptr[0..new_total_size]; | |
| const new_allocation: *Allocation = @alignCast(@ptrCast(new_memory.ptr)); | |
| new_allocation.size = new_size; | |
| return &new_allocation.user_memory_start; | |
| }, | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment