Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions src/memory.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const std = @import("std");
const options = @import("zmesh_options");

pub fn init(alloc: std.mem.Allocator) void {
std.debug.assert(mem_allocator == null and mem_allocations == null);
Expand All @@ -7,10 +8,27 @@ pub fn init(alloc: std.mem.Allocator) void {
mem_allocations = std.AutoHashMap(usize, usize).init(alloc);
mem_allocations.?.ensureTotalCapacity(32) catch unreachable;

zmeshMallocPtr = zmeshMalloc;
zmeshCallocPtr = zmeshCalloc;
zmeshReallocPtr = zmeshRealloc;
zmeshFreePtr = zmeshFree;
const zmeshMallocPtr = @extern(*?*const fn (size: usize) callconv(.C) ?*anyopaque, .{
.name = "zmeshMallocPtr",
.is_dll_import = options.shared,
});
const zmeshCallocPtr = @extern(*?*const fn (num: usize, size: usize) callconv(.C) ?*anyopaque, .{
.name = "zmeshCallocPtr",
.is_dll_import = options.shared,
});
const zmeshReallocPtr = @extern(*?*const fn (ptr: ?*anyopaque, size: usize) callconv(.C) ?*anyopaque, .{
.name = "zmeshReallocPtr",
.is_dll_import = options.shared,
});
const zmeshFreePtr = @extern(*?*const fn (maybe_ptr: ?*anyopaque) callconv(.C) void, .{
.name = "zmeshFreePtr",
.is_dll_import = options.shared,
});

zmeshMallocPtr.* = zmeshMalloc;
zmeshCallocPtr.* = zmeshCalloc;
zmeshReallocPtr.* = zmeshRealloc;
zmeshFreePtr.* = zmeshFree;
meshopt_setAllocator(zmeshMalloc, zmeshFree);
}

Expand All @@ -31,9 +49,7 @@ extern fn meshopt_setAllocator(
var mem_allocator: ?std.mem.Allocator = null;
var mem_allocations: ?std.AutoHashMap(usize, usize) = null;
var mem_mutex: std.Thread.Mutex = .{};
const mem_alignment = 16;

extern var zmeshMallocPtr: ?*const fn (size: usize) callconv(.C) ?*anyopaque;
const mem_alignment: std.mem.Alignment = .@"16";

pub fn zmeshMalloc(size: usize) callconv(.C) ?*anyopaque {
mem_mutex.lock();
Expand All @@ -50,8 +66,6 @@ pub fn zmeshMalloc(size: usize) callconv(.C) ?*anyopaque {
return mem.ptr;
}

extern var zmeshCallocPtr: ?*const fn (num: usize, size: usize) callconv(.C) ?*anyopaque;

fn zmeshCalloc(num: usize, size: usize) callconv(.C) ?*anyopaque {
const ptr = zmeshMalloc(num * size);
if (ptr != null) {
Expand All @@ -66,18 +80,16 @@ pub fn zmeshAllocUser(user: ?*anyopaque, size: usize) callconv(.C) ?*anyopaque {
return zmeshMalloc(size);
}

extern var zmeshReallocPtr: ?*const fn (ptr: ?*anyopaque, size: usize) callconv(.C) ?*anyopaque;

fn zmeshRealloc(ptr: ?*anyopaque, size: usize) callconv(.C) ?*anyopaque {
mem_mutex.lock();
defer mem_mutex.unlock();

const old_size = if (ptr != null) mem_allocations.?.get(@intFromPtr(ptr.?)).? else 0;

const old_mem = if (old_size > 0)
@as([*]align(mem_alignment) u8, @ptrCast(@alignCast(ptr)))[0..old_size]
@as([*]align(mem_alignment.toByteUnits()) u8, @ptrCast(@alignCast(ptr)))[0..old_size]
else
@as([*]align(mem_alignment) u8, undefined)[0..0];
@as([*]align(mem_alignment.toByteUnits()) u8, undefined)[0..0];

const mem = mem_allocator.?.realloc(old_mem, size) catch @panic("zmesh: out of memory");

Expand All @@ -91,15 +103,13 @@ fn zmeshRealloc(ptr: ?*anyopaque, size: usize) callconv(.C) ?*anyopaque {
return mem.ptr;
}

extern var zmeshFreePtr: ?*const fn (maybe_ptr: ?*anyopaque) callconv(.C) void;

fn zmeshFree(maybe_ptr: ?*anyopaque) callconv(.C) void {
if (maybe_ptr) |ptr| {
mem_mutex.lock();
defer mem_mutex.unlock();

const size = mem_allocations.?.fetchRemove(@intFromPtr(ptr)).?.value;
const mem = @as([*]align(mem_alignment) u8, @ptrCast(@alignCast(ptr)))[0..size];
const mem = @as([*]align(mem_alignment.toByteUnits()) u8, @ptrCast(@alignCast(ptr)))[0..size];
mem_allocator.?.free(mem);
}
}
Expand Down
Loading