diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index e166f3fd..a2ad6d18 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -711,7 +711,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh return self; } - fn privateDeinit(self: *ChunkMesh, _: usize) void { + fn privateDeinit(self: *ChunkMesh) void { chunkBuffer.free(self.chunkAllocation); self.opaqueMesh.deinit(); self.transparentMesh.deinit(); diff --git a/src/server/terrain/CaveBiomeMap.zig b/src/server/terrain/CaveBiomeMap.zig index f32781d7..37fde7b5 100644 --- a/src/server/terrain/CaveBiomeMap.zig +++ b/src/server/terrain/CaveBiomeMap.zig @@ -39,7 +39,7 @@ pub const CaveBiomeMapFragment = struct { // MARK: caveBiomeMapFragment }; } - fn privateDeinit(self: *CaveBiomeMapFragment, _: usize) void { + fn privateDeinit(self: *CaveBiomeMapFragment) void { memoryPool.destroy(self); } diff --git a/src/server/terrain/CaveMap.zig b/src/server/terrain/CaveMap.zig index b9b2a652..f65df386 100644 --- a/src/server/terrain/CaveMap.zig +++ b/src/server/terrain/CaveMap.zig @@ -35,7 +35,7 @@ pub const CaveMapFragment = struct { // MARK: CaveMapFragment @memset(&self.data, std.math.maxInt(u64)); } - fn privateDeinit(self: *CaveMapFragment, _: usize) void { + fn privateDeinit(self: *CaveMapFragment) void { memoryPool.destroy(self); } diff --git a/src/server/terrain/ClimateMap.zig b/src/server/terrain/ClimateMap.zig index 2ee9441f..fb8acf10 100644 --- a/src/server/terrain/ClimateMap.zig +++ b/src/server/terrain/ClimateMap.zig @@ -54,7 +54,7 @@ pub const ClimateMapFragment = struct { }; } - fn privateDeinit(self: *ClimateMapFragment, _: usize) void { + fn privateDeinit(self: *ClimateMapFragment) void { memoryPool.destroy(self); } diff --git a/src/server/terrain/LightMap.zig b/src/server/terrain/LightMap.zig index 4a9fe9f2..55517472 100644 --- a/src/server/terrain/LightMap.zig +++ b/src/server/terrain/LightMap.zig @@ -26,7 +26,7 @@ pub const LightMapFragment = struct { }; } - fn privateDeinit(self: *const LightMapFragment, _: usize) void { + fn privateDeinit(self: *const LightMapFragment) void { main.globalAllocator.destroy(self); } diff --git a/src/server/terrain/StructureMap.zig b/src/server/terrain/StructureMap.zig index 94034ac0..114c163c 100644 --- a/src/server/terrain/StructureMap.zig +++ b/src/server/terrain/StructureMap.zig @@ -67,7 +67,7 @@ pub const StructureMapFragment = struct { @memset(self.tempData.lists, .{}); } - fn privateDeinit(self: *StructureMapFragment, _: usize) void { + fn privateDeinit(self: *StructureMapFragment) void { self.arena.deinit(); memoryPool.destroy(self); } diff --git a/src/server/terrain/SurfaceMap.zig b/src/server/terrain/SurfaceMap.zig index ae78e4e3..3ac11a9a 100644 --- a/src/server/terrain/SurfaceMap.zig +++ b/src/server/terrain/SurfaceMap.zig @@ -80,7 +80,7 @@ pub const MapFragment = struct { // MARK: MapFragment }; } - fn privateDeinit(self: *MapFragment, _: usize) void { + fn privateDeinit(self: *MapFragment) void { memoryPool.destroy(self); } diff --git a/src/utils/heap.zig b/src/utils/heap.zig index 2d2fd7e8..2bd2c928 100644 --- a/src/utils/heap.zig +++ b/src/utils/heap.zig @@ -582,10 +582,14 @@ pub const GarbageCollection = struct { // MARK: GarbageCollection threadlocal var lastSyncPointTime: i64 = undefined; const FreeItem = struct { ptr: *anyopaque, - extraData: usize = 0, - freeFunction: *const fn(*anyopaque, usize) void, + freeFunction: *const fn(*anyopaque) void, + }; + const FreeSliceItem = struct { + slice: []const u8, + allocator: NeverFailingAllocator, }; threadlocal var lists: [4]main.ListUnmanaged(FreeItem) = undefined; + threadlocal var sliceLists: [4]main.ListUnmanaged(FreeSliceItem) = undefined; const State = packed struct { waitingThreads: u15 = 0, @@ -601,6 +605,9 @@ pub const GarbageCollection = struct { // MARK: GarbageCollection for(&lists) |*list| { list.* = .initCapacity(main.globalAllocator, 1024); } + for(&sliceLists) |*list| { + list.* = .initCapacity(main.globalAllocator, 1024); + } if(old.waitingThreads == 0) { startNewCycle(); } @@ -608,7 +615,13 @@ pub const GarbageCollection = struct { // MARK: GarbageCollection fn freeItemsFromList(list: *main.ListUnmanaged(FreeItem)) void { while(list.popOrNull()) |item| { - item.freeFunction(item.ptr, item.extraData); + item.freeFunction(item.ptr); + } + } + + fn freeItemsFromSliceList(list: *main.ListUnmanaged(FreeSliceItem)) void { + while(list.popOrNull()) |item| { + item.allocator.free(item.slice); } } @@ -625,6 +638,10 @@ pub const GarbageCollection = struct { // MARK: GarbageCollection freeItemsFromList(list); list.deinit(main.globalAllocator); } + for(&sliceLists) |*list| { + freeItemsFromSliceList(list); + list.deinit(main.globalAllocator); + } } pub fn assertAllThreadsStopped() void { @@ -662,13 +679,20 @@ pub const GarbageCollection = struct { // MARK: GarbageCollection if(old.cycle == threadCycle) return; removeThreadFromWaiting(); freeItemsFromList(&lists[threadCycle]); - // TODO: Free all the data here and swap lists + freeItemsFromSliceList(&sliceLists[threadCycle]); } pub fn deferredFree(item: FreeItem) void { lists[threadCycle].append(main.globalAllocator, item); } + pub fn deferredFreeSlice(allocator: NeverFailingAllocator, comptime T: type, items: []T) void { + sliceLists[threadCycle].append(main.globalAllocator, .{ + .slice = std.mem.sliceAsBytes(items), + .allocator = allocator, + }); + } + /// Waits until all deferred frees have been completed. pub fn waitForFreeCompletion() void { const startCycle = threadCycle;