Simplify the process of garbage collecting a slice

This commit is contained in:
IntegratedQuantum 2025-07-28 16:26:17 +02:00
parent 2dc2a6e790
commit fe9b456cd8
8 changed files with 35 additions and 11 deletions

View File

@ -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();

View File

@ -39,7 +39,7 @@ pub const CaveBiomeMapFragment = struct { // MARK: caveBiomeMapFragment
};
}
fn privateDeinit(self: *CaveBiomeMapFragment, _: usize) void {
fn privateDeinit(self: *CaveBiomeMapFragment) void {
memoryPool.destroy(self);
}

View File

@ -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);
}

View File

@ -54,7 +54,7 @@ pub const ClimateMapFragment = struct {
};
}
fn privateDeinit(self: *ClimateMapFragment, _: usize) void {
fn privateDeinit(self: *ClimateMapFragment) void {
memoryPool.destroy(self);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -80,7 +80,7 @@ pub const MapFragment = struct { // MARK: MapFragment
};
}
fn privateDeinit(self: *MapFragment, _: usize) void {
fn privateDeinit(self: *MapFragment) void {
memoryPool.destroy(self);
}

View File

@ -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;