Skip to content

Instantly share code, notes, and snippets.

@Tetralux
Last active November 12, 2025 02:26
Show Gist options
  • Select an option

  • Save Tetralux/aa77d9d2f6d476ecdfa487220f2d92cb to your computer and use it in GitHub Desktop.

Select an option

Save Tetralux/aa77d9d2f6d476ecdfa487220f2d92cb to your computer and use it in GitHub Desktop.
Use the custom allocator function of convhull3d
#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)
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);
}
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