Run stronghold gen on dedicated thread pool

This commit is contained in:
embeddedt 2026-05-23 17:00:08 -04:00
parent b62eb1845b
commit 538c52bc2a
No known key found for this signature in database
GPG Key ID: A69433EC199B5613

View File

@ -2,6 +2,8 @@ package org.embeddedt.modernfix.common.mixin.perf.cache_strongholds;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import net.minecraft.Util; import net.minecraft.Util;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.nbt.*; import net.minecraft.nbt.*;
@ -17,6 +19,8 @@ import org.embeddedt.modernfix.duck.IChunkGenerator;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -29,6 +33,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Mixin(ChunkGeneratorStructureState.class) @Mixin(ChunkGeneratorStructureState.class)
public class ChunkGeneratorMixin implements IChunkGenerator { public class ChunkGeneratorMixin implements IChunkGenerator {
@ -55,8 +61,9 @@ public class ChunkGeneratorMixin implements IChunkGenerator {
@WrapMethod(method = "generateRingPositions") @WrapMethod(method = "generateRingPositions")
private CompletableFuture<List<ChunkPos>> modernfix$cacheRingPositions(Holder<StructureSet> structureSet, private CompletableFuture<List<ChunkPos>> modernfix$cacheRingPositions(Holder<StructureSet> structureSet,
ConcentricRingsStructurePlacement placement, ConcentricRingsStructurePlacement placement,
Operation<CompletableFuture<List<ChunkPos>>> original) { Operation<CompletableFuture<List<ChunkPos>>> original,
@Share("threadPool") LocalRef<ExecutorService> threadPoolRef) {
if (this.mfix$server == null || this.mfix$dimensionPath == null) { if (this.mfix$server == null || this.mfix$dimensionPath == null) {
return original.call(structureSet, placement); return original.call(structureSet, placement);
} }
@ -71,13 +78,30 @@ public class ChunkGeneratorMixin implements IChunkGenerator {
} }
var server = this.mfix$server; var server = this.mfix$server;
return original.call(structureSet, placement).thenApplyAsync(positions -> { ExecutorService strongholdPool = Executors.newFixedThreadPool(Math.max(1, Runtime.getRuntime().availableProcessors() - 2));
// Skip write if server exited before we finished threadPoolRef.set(strongholdPool);
if (server.isRunning()) { try {
mfix$writeToCache(cacheKey, positions); return original.call(structureSet, placement).thenApplyAsync(positions -> {
} // Skip write if server exited before we finished
return positions; if (server.isRunning()) {
}, Util.ioPool()); mfix$writeToCache(cacheKey, positions);
}
return positions;
}, Util.ioPool());
} finally {
strongholdPool.shutdown();
}
}
/**
* @author embeddedt
* @reason Ring position calculation is often not required for initial chunk generation, but the tasks still occupy
* CPU time on the main worker pool and prevent higher priority work from progressing. To fix this we use a
* dedicated pool.
*/
@Redirect(method = "generateRingPositions", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;backgroundExecutor()Ljava/util/concurrent/ExecutorService;"))
private ExecutorService useDedicatedService(@Share("threadPool") LocalRef<ExecutorService> threadPoolRef) {
return threadPoolRef.get();
} }
private String mfix$makeCacheKey(ConcentricRingsStructurePlacement placement) { private String mfix$makeCacheKey(ConcentricRingsStructurePlacement placement) {