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");
|
const vk = @import("vulkan");
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
allocations: std.AutoHashMapUnmanaged(?*anyopaque, usize) = .empty,
|
allocations: std.AutoHashMapUnmanaged(*anyopaque, usize) = .empty,
|
||||||
mutex: std.Thread.Mutex = .{},
|
mutex: std.Thread.Mutex = .{},
|
||||||
|
allocated_bytes: usize = 0,
|
||||||
|
|
||||||
interface: vk.AllocationCallbacks,
|
interface: vk.AllocationCallbacks,
|
||||||
|
|
||||||
@@ -15,6 +16,8 @@ interface: vk.AllocationCallbacks,
|
|||||||
// with the same, relatively big alignment and hope for the best.
|
// with the same, relatively big alignment and hope for the best.
|
||||||
const actual_alignment: std.mem.Alignment = .@"16";
|
const actual_alignment: std.mem.Alignment = .@"16";
|
||||||
|
|
||||||
|
const log = std.log.scoped(.vk_allocator);
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) !*VkAllocator {
|
pub fn init(allocator: std.mem.Allocator) !*VkAllocator {
|
||||||
// NOTE We allocate the structure to pin its address.
|
// NOTE We allocate the structure to pin its address.
|
||||||
const self = try allocator.create(VkAllocator);
|
const self = try allocator.create(VkAllocator);
|
||||||
@@ -33,6 +36,19 @@ pub fn init(allocator: std.mem.Allocator) !*VkAllocator {
|
|||||||
|
|
||||||
pub fn deinit(self: *VkAllocator) void {
|
pub fn deinit(self: *VkAllocator) void {
|
||||||
std.log.debug("Deinitializing {*}", .{self});
|
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;
|
const allocator = self.allocator;
|
||||||
|
|
||||||
@@ -60,6 +76,8 @@ fn allocationFunction(
|
|||||||
const memory = self.allocator.alignedAlloc(u8, actual_alignment, size) catch return null;
|
const memory = self.allocator.alignedAlloc(u8, actual_alignment, size) catch return null;
|
||||||
|
|
||||||
self.allocations.putAssumeCapacity(memory.ptr, size);
|
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;
|
return memory.ptr;
|
||||||
}
|
}
|
||||||
@@ -94,11 +112,13 @@ fn reallocationFunction(
|
|||||||
std.debug.assert(std.mem.isAligned(@intFromPtr(memory.ptr), alignment));
|
std.debug.assert(std.mem.isAligned(@intFromPtr(memory.ptr), alignment));
|
||||||
|
|
||||||
if (maybe_p_original) |p_original| {
|
if (maybe_p_original) |p_original| {
|
||||||
const removed = self.allocations.remove(p_original);
|
const old_size = self.allocations.fetchRemove(p_original).?.value;
|
||||||
std.debug.assert(removed);
|
self.allocated_bytes -= old_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.allocations.putAssumeCapacityNoClobber(memory.ptr, 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;
|
return memory.ptr;
|
||||||
}
|
}
|
||||||
@@ -114,6 +134,7 @@ fn freeFunction(
|
|||||||
defer self.mutex.unlock();
|
defer self.mutex.unlock();
|
||||||
|
|
||||||
const size = self.allocations.fetchRemove(p_memory).?.value;
|
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];
|
const memory = @as([*]align(actual_alignment.toByteUnits()) u8, @ptrCast(@alignCast(p_memory)))[0..size];
|
||||||
|
|
||||||
self.allocator.free(memory);
|
self.allocator.free(memory);
|
||||||
|
|||||||
Reference in New Issue
Block a user