From b13e835a2183bc4f5898868a3a440f2f796e28c9 Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Sun, 9 Mar 2025 20:44:05 +0100 Subject: [PATCH] Add memory pools to all terrain generation data structures. --- src/server/terrain/CaveBiomeMap.zig | 8 ++++++-- src/server/terrain/CaveMap.zig | 8 ++++++-- src/server/terrain/ClimateMap.zig | 8 ++++++-- src/server/terrain/StructureMap.zig | 8 ++++++-- src/server/terrain/SurfaceMap.zig | 12 ++++++++---- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/server/terrain/CaveBiomeMap.zig b/src/server/terrain/CaveBiomeMap.zig index a1dfbf8b..cfef466e 100644 --- a/src/server/terrain/CaveBiomeMap.zig +++ b/src/server/terrain/CaveBiomeMap.zig @@ -92,7 +92,7 @@ pub const CaveBiomeMapFragment = struct { // MARK: caveBiomeMapFragment const prevVal = self.refCount.fetchSub(1, .monotonic); std.debug.assert(prevVal != 0); if(prevVal == 1) { - main.globalAllocator.destroy(self); + memoryPool.destroy(self); } } }; @@ -527,6 +527,8 @@ var cache: Cache(CaveBiomeMapFragment, cacheSize, associativity, CaveBiomeMapFra var profile: TerrainGenerationProfile = undefined; +var memoryPool: main.heap.MemoryPool(CaveBiomeMapFragment) = undefined; + pub fn initGenerators() void { const list = @import("cavebiomegen/_list.zig"); inline for(@typeInfo(list).@"struct".decls) |decl| { @@ -540,14 +542,16 @@ pub fn deinitGenerators() void { pub fn init(_profile: TerrainGenerationProfile) void { profile = _profile; + memoryPool = .init(main.globalAllocator); } pub fn deinit() void { cache.clear(); + memoryPool.deinit(); } fn cacheInit(pos: ChunkPosition) *CaveBiomeMapFragment { - const mapFragment = main.globalAllocator.create(CaveBiomeMapFragment); + const mapFragment = memoryPool.create(); mapFragment.init(pos.wx, pos.wy, pos.wz); for(profile.caveBiomeGenerators) |generator| { generator.generate(mapFragment, profile.seed ^ generator.generatorSeed); diff --git a/src/server/terrain/CaveMap.zig b/src/server/terrain/CaveMap.zig index 97c00d14..df6b3677 100644 --- a/src/server/terrain/CaveMap.zig +++ b/src/server/terrain/CaveMap.zig @@ -59,7 +59,7 @@ pub const CaveMapFragment = struct { // MARK: CaveMapFragment const prevVal = self.refCount.fetchSub(1, .monotonic); std.debug.assert(prevVal != 0); if(prevVal == 1) { - main.globalAllocator.destroy(self); + memoryPool.destroy(self); } } @@ -292,8 +292,10 @@ const associativity = 8; // 512 MiB Cache size var cache: Cache(CaveMapFragment, cacheSize, associativity, CaveMapFragment.decreaseRefCount) = .{}; var profile: TerrainGenerationProfile = undefined; +var memoryPool: main.heap.MemoryPool(CaveMapFragment) = undefined; + fn cacheInit(pos: ChunkPosition) *CaveMapFragment { - const mapFragment = main.globalAllocator.create(CaveMapFragment); + const mapFragment = memoryPool.create(); mapFragment.init(pos.wx, pos.wy, pos.wz, pos.voxelSize); for(profile.caveGenerators) |generator| { generator.generate(mapFragment, profile.seed ^ generator.generatorSeed); @@ -315,10 +317,12 @@ pub fn deinitGenerators() void { pub fn init(_profile: TerrainGenerationProfile) void { profile = _profile; + memoryPool = .init(main.globalAllocator); } pub fn deinit() void { cache.clear(); + memoryPool.deinit(); } fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32, wz: i32, voxelSize: u31) *CaveMapFragment { diff --git a/src/server/terrain/ClimateMap.zig b/src/server/terrain/ClimateMap.zig index ac7615a8..7cc0a7ac 100644 --- a/src/server/terrain/ClimateMap.zig +++ b/src/server/terrain/ClimateMap.zig @@ -73,7 +73,7 @@ pub const ClimateMapFragment = struct { const prevVal = self.refCount.fetchSub(1, .monotonic); std.debug.assert(prevVal != 0); if(prevVal == 1) { - main.globalAllocator.destroy(self); + memoryPool.destroy(self); } } }; @@ -109,6 +109,8 @@ const associativity = 8; // ~400 MiB var cache: Cache(ClimateMapFragment, cacheSize, associativity, ClimateMapFragment.decreaseRefCount) = .{}; var profile: TerrainGenerationProfile = undefined; +var memoryPool: main.heap.MemoryPool(ClimateMapFragment) = undefined; + pub fn initGenerators() void { const list = @import("climategen/_list.zig"); inline for(@typeInfo(list).@"struct".decls) |decl| { @@ -121,7 +123,7 @@ pub fn deinitGenerators() void { } fn cacheInit(pos: ClimateMapFragmentPosition) *ClimateMapFragment { - const mapFragment = main.globalAllocator.create(ClimateMapFragment); + const mapFragment = memoryPool.create(); mapFragment.init(pos.wx, pos.wy); profile.climateGenerator.generateMapFragment(mapFragment, profile.seed); _ = @atomicRmw(u16, &mapFragment.refCount.raw, .Add, 1, .monotonic); @@ -130,10 +132,12 @@ fn cacheInit(pos: ClimateMapFragmentPosition) *ClimateMapFragment { pub fn init(_profile: TerrainGenerationProfile) void { profile = _profile; + memoryPool = .init(main.globalAllocator); } pub fn deinit() void { cache.clear(); + memoryPool.deinit(); } pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32) *ClimateMapFragment { diff --git a/src/server/terrain/StructureMap.zig b/src/server/terrain/StructureMap.zig index 3e6e1d18..c4e980ef 100644 --- a/src/server/terrain/StructureMap.zig +++ b/src/server/terrain/StructureMap.zig @@ -70,7 +70,7 @@ pub const StructureMapFragment = struct { pub fn deinit(self: *StructureMapFragment) void { self.arena.deinit(); - main.globalAllocator.destroy(self); + memoryPool.destroy(self); } fn finishGeneration(self: *StructureMapFragment) void { @@ -178,8 +178,10 @@ const associativity = 8; var cache: Cache(StructureMapFragment, cacheSize, associativity, StructureMapFragment.decreaseRefCount) = .{}; var profile: TerrainGenerationProfile = undefined; +var memoryPool: main.heap.MemoryPool(StructureMapFragment) = undefined; + fn cacheInit(pos: ChunkPosition) *StructureMapFragment { - const mapFragment = main.globalAllocator.create(StructureMapFragment); + const mapFragment = memoryPool.create(); mapFragment.init(main.stackAllocator, pos.wx, pos.wy, pos.wz, pos.voxelSize); for(profile.structureMapGenerators) |generator| { generator.generate(mapFragment, profile.seed ^ generator.generatorSeed); @@ -202,10 +204,12 @@ pub fn deinitGenerators() void { pub fn init(_profile: TerrainGenerationProfile) void { profile = _profile; + memoryPool = .init(main.globalAllocator); } pub fn deinit() void { cache.clear(); + memoryPool.deinit(); } pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32, wz: i32, voxelSize: u31) *StructureMapFragment { diff --git a/src/server/terrain/SurfaceMap.zig b/src/server/terrain/SurfaceMap.zig index 6ab8ecad..442cd6aa 100644 --- a/src/server/terrain/SurfaceMap.zig +++ b/src/server/terrain/SurfaceMap.zig @@ -89,7 +89,7 @@ pub const MapFragment = struct { // MARK: MapFragment const prevVal = self.refCount.fetchSub(1, .monotonic); std.debug.assert(prevVal != 0); if(prevVal == 1) { - main.globalAllocator.destroy(self); + memoryPool.destroy(self); } } @@ -248,6 +248,8 @@ const associativity = 8; // ~400MiB MiB Cache size var cache: Cache(MapFragment, cacheSize, associativity, MapFragment.decreaseRefCount) = .{}; var profile: TerrainGenerationProfile = undefined; +var memoryPool: main.heap.MemoryPool(MapFragment) = undefined; + pub fn initGenerators() void { const list = @import("mapgen/_list.zig"); inline for(@typeInfo(list).@"struct".decls) |decl| { @@ -260,7 +262,7 @@ pub fn deinitGenerators() void { } fn cacheInit(pos: MapFragmentPosition) *MapFragment { - const mapFragment = main.globalAllocator.create(MapFragment); + const mapFragment = memoryPool.create(); mapFragment.init(pos.wx, pos.wy, pos.voxelSize); _ = mapFragment.load(main.server.world.?.biomePalette, null) catch { profile.mapFragmentGenerator.generateMapFragment(mapFragment, profile.seed); @@ -326,7 +328,7 @@ pub fn regenerateLOD(worldName: []const u8) !void { // MARK: regenerateLOD() } @field(neighborInfo, name) = isPresent; } - const mapFragment = main.globalAllocator.create(MapFragment); + const mapFragment = main.stackAllocator.create(MapFragment); defer main.stackAllocator.destroy(mapFragment); mapFragment.init(pos.wx, pos.wy, pos.voxelSize); var xNoise: [MapFragment.mapSize]f32 = undefined; @@ -466,7 +468,7 @@ pub fn regenerateLOD(worldName: []const u8) !void { // MARK: regenerateLOD() return @max(0, @min(0.99999, ((self.a*x + self.b)*x + self.c)*x*x)); } }; - const generatedMap = main.globalAllocator.create(MapFragment); + const generatedMap = main.stackAllocator.create(MapFragment); defer main.stackAllocator.destroy(generatedMap); generatedMap.init(pos.wx, pos.wy, pos.voxelSize); profile.mapFragmentGenerator.generateMapFragment(generatedMap, profile.seed); @@ -623,10 +625,12 @@ pub fn regenerateLOD(worldName: []const u8) !void { // MARK: regenerateLOD() pub fn init(_profile: TerrainGenerationProfile) void { profile = _profile; + memoryPool = .init(main.globalAllocator); } pub fn deinit() void { cache.clear(); + memoryPool.deinit(); } /// Call deinit on the result.