Deleak the leaks
There is a chance that leaks from VkAllocator result from leaky allocations while deinitializing.
This commit is contained in:
@@ -4,8 +4,9 @@ const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
allocations: std.AutoHashMapUnmanaged(?*anyopaque, usize) = .empty,
|
||||
allocations: std.AutoHashMapUnmanaged(*anyopaque, usize) = .empty,
|
||||
mutex: std.Thread.Mutex = .{},
|
||||
allocated_bytes: usize = 0,
|
||||
|
||||
interface: vk.AllocationCallbacks,
|
||||
|
||||
@@ -15,6 +16,8 @@ interface: vk.AllocationCallbacks,
|
||||
// with the same, relatively big alignment and hope for the best.
|
||||
const actual_alignment: std.mem.Alignment = .@"16";
|
||||
|
||||
const log = std.log.scoped(.vk_allocator);
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*VkAllocator {
|
||||
// NOTE We allocate the structure to pin its address.
|
||||
const self = try allocator.create(VkAllocator);
|
||||
@@ -33,6 +36,19 @@ pub fn init(allocator: std.mem.Allocator) !*VkAllocator {
|
||||
|
||||
pub fn deinit(self: *VkAllocator) void {
|
||||
std.log.debug("Deinitializing {*}", .{self});
|
||||
if (self.allocated_bytes > 0) {
|
||||
log.warn("{d} byte(s) still allocated while deinitializing", .{self.allocated_bytes});
|
||||
}
|
||||
if (self.allocations.size > 0) {
|
||||
log.warn("{d} allocation(s) still tracked while deinitializing", .{self.allocations.size});
|
||||
var it = self.allocations.iterator();
|
||||
var index: usize = 0;
|
||||
while (it.next()) |entry| : (index += 1) {
|
||||
log.warn("Leaked allocation ({d}/{d}) at 0x{x} of {d} byte(s)", .{ index + 1, self.allocations.size, @intFromPtr(entry.key_ptr.*), entry.value_ptr.* });
|
||||
const memory = @as([*]align(actual_alignment.toByteUnits()) u8, @ptrCast(@alignCast(entry.key_ptr.*)))[0..entry.value_ptr.*];
|
||||
self.allocator.free(memory);
|
||||
}
|
||||
}
|
||||
|
||||
const allocator = self.allocator;
|
||||
|
||||
@@ -60,6 +76,8 @@ fn allocationFunction(
|
||||
const memory = self.allocator.alignedAlloc(u8, actual_alignment, size) catch return null;
|
||||
|
||||
self.allocations.putAssumeCapacity(memory.ptr, size);
|
||||
self.allocated_bytes += size;
|
||||
//log.debug("Allocated {d} bytes(s) at 0x{x}", .{ size, @intFromPtr(memory.ptr) });
|
||||
|
||||
return memory.ptr;
|
||||
}
|
||||
@@ -94,11 +112,13 @@ fn reallocationFunction(
|
||||
std.debug.assert(std.mem.isAligned(@intFromPtr(memory.ptr), alignment));
|
||||
|
||||
if (maybe_p_original) |p_original| {
|
||||
const removed = self.allocations.remove(p_original);
|
||||
std.debug.assert(removed);
|
||||
const old_size = self.allocations.fetchRemove(p_original).?.value;
|
||||
self.allocated_bytes -= old_size;
|
||||
}
|
||||
|
||||
self.allocations.putAssumeCapacityNoClobber(memory.ptr, size);
|
||||
self.allocated_bytes += size;
|
||||
//log.debug("Reallocated into {d} bytes(s) at 0x{x} from 0x{x}", .{ size, @intFromPtr(memory.ptr), @intFromPtr(maybe_p_original) });
|
||||
|
||||
return memory.ptr;
|
||||
}
|
||||
@@ -114,6 +134,7 @@ fn freeFunction(
|
||||
defer self.mutex.unlock();
|
||||
|
||||
const size = self.allocations.fetchRemove(p_memory).?.value;
|
||||
self.allocated_bytes -= size;
|
||||
const memory = @as([*]align(actual_alignment.toByteUnits()) u8, @ptrCast(@alignCast(p_memory)))[0..size];
|
||||
|
||||
self.allocator.free(memory);
|
||||
|
||||
Reference in New Issue
Block a user