Skip to content

Commit 2458672

Browse files
committed
Use cached thread pool to process mob spawning tasks to fix some issue
1 parent 431aaa9 commit 2458672

File tree

1 file changed

+43
-26
lines changed

1 file changed

+43
-26
lines changed

patches/server/0041-Optimize-mob-spawning-Async-mob-spawn-state-calc.patch

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ index 0000000000000000000000000000000000000000..facd55463d44cb7e3d2ca6892982f549
124124
+ }
125125
+}
126126
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
127-
index 7ca275826609bcf96f103a8c50beaa47c3b4068b..045a83f944ebe3e5e969e4b414760413f8d634fc 100644
127+
index 7ca275826609bcf96f103a8c50beaa47c3b4068b..dc5399bd5dba9dd33a7cfd644327c2568a6ad051 100644
128128
--- a/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
129129
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
130130
@@ -4,6 +4,7 @@ import com.destroystokyo.paper.util.maplist.ReferenceList;
@@ -135,64 +135,71 @@ index 7ca275826609bcf96f103a8c50beaa47c3b4068b..045a83f944ebe3e5e969e4b414760413
135135
import io.papermc.paper.chunk.system.scheduling.ChunkHolderManager;
136136
import io.papermc.paper.util.CoordinateUtils;
137137
import io.papermc.paper.util.TickThread;
138-
@@ -14,6 +15,8 @@ import it.unimi.dsi.fastutil.longs.Long2ReferenceMap;
138+
@@ -14,6 +15,7 @@ import it.unimi.dsi.fastutil.longs.Long2ReferenceMap;
139139
import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
140140
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
141141
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
142142
+import me.earthme.luminol.LuminolConfig;
143-
+import me.earthme.luminol.utils.AsyncMobSpawnExecutor;
144143
import net.minecraft.CrashReport;
145144
import net.minecraft.ReportedException;
146145
import net.minecraft.core.BlockPos;
147-
@@ -58,6 +61,7 @@ import java.util.HashMap;
146+
@@ -58,6 +60,10 @@ import java.util.HashMap;
148147
import java.util.Iterator;
149148
import java.util.List;
150149
import java.util.Map;
151150
+import java.util.concurrent.CompletableFuture;
151+
+import java.util.concurrent.LinkedBlockingQueue;
152+
+import java.util.concurrent.ThreadPoolExecutor;
153+
+import java.util.concurrent.TimeUnit;
152154
import java.util.function.Consumer;
153155
import java.util.function.Predicate;
154156

155-
@@ -145,6 +149,11 @@ public final class RegionizedWorldData {
157+
@@ -145,6 +151,10 @@ public final class RegionizedWorldData {
156158
into.wanderingTraderSpawnDelay = Math.max(from.wanderingTraderSpawnDelay, into.wanderingTraderSpawnDelay);
157159
into.wanderingTraderSpawnChance = Math.max(from.wanderingTraderSpawnChance, into.wanderingTraderSpawnChance);
158160
}
159161
+
160162
+ //Luminol start - Async mob spawning
161-
+ from.asyncMobSpawnExecutor.forceTerminate(); //Just terminate and do nothing
162163
+ from.lastAsyncSpawnStateTask = null; //Discard the task currently processing
163164
+ //Luminol end
164165
}
165166

166167
@Override
167-
@@ -302,6 +311,15 @@ public final class RegionizedWorldData {
168+
@@ -302,6 +312,10 @@ public final class RegionizedWorldData {
168169
regionizedWorldData.wanderingTraderSpawnDelay = from.wanderingTraderSpawnDelay;
169170
regionizedWorldData.villageSiegeState = new VillageSiegeState(); // just re set it, as the spawn pos will be invalid
170171
}
171172
+
172173
+ //Luminol start - Async mob spawning
173174
+ from.lastAsyncSpawnStateTask = null; //Reset the task
174-
+ from.asyncMobSpawnExecutor.dropAllTasks(); //Reset tasks
175-
+
176-
+ if (!from.asyncMobSpawnExecutor.isRunning() && LuminolConfig.enableAsyncMobSpawning){
177-
+ from.asyncMobSpawnExecutor.startExecutor();
178-
+ }
179175
+ //Luminol end
180176
}
181177
};
182178

183-
@@ -398,6 +416,11 @@ public final class RegionizedWorldData {
179+
@@ -398,6 +412,22 @@ public final class RegionizedWorldData {
184180
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos;
185181
public final Long2IntOpenHashMap chunksBeingWorkedOn = new Long2IntOpenHashMap();
186182

187183
+ //Luminol start - Asnc mob spawning
188-
+ public final AsyncMobSpawnExecutor asyncMobSpawnExecutor = new AsyncMobSpawnExecutor();
189184
+ public volatile CompletableFuture<NaturalSpawner.SpawnState> lastAsyncSpawnStateTask = null;
185+
+ public static ThreadPoolExecutor ASYNC_MOB_SPAWNING_EXECUTOR;
186+
+ public static void initMobSpawningExecutor(){
187+
+ if (LuminolConfig.enableAsyncMobSpawning){
188+
+ ASYNC_MOB_SPAWNING_EXECUTOR = new ThreadPoolExecutor(
189+
+ 1,
190+
+ Integer.MAX_VALUE,
191+
+ 1,
192+
+ TimeUnit.MINUTES,
193+
+ new LinkedBlockingQueue<>()
194+
+ );
195+
+ }
196+
+ }
190197
+ //Luminol end
191198
+
192199
public static final class TempCollisionList<T> {
193200
final UnsafeList<T> list = new UnsafeList<>(64);
194201
boolean inUse;
195-
@@ -430,7 +453,7 @@ public final class RegionizedWorldData {
202+
@@ -430,7 +460,7 @@ public final class RegionizedWorldData {
196203

197204
// Mob spawning
198205
private final PooledLinkedHashSets<ServerPlayer> pooledHashSets = new PooledLinkedHashSets<>();
@@ -202,22 +209,31 @@ index 7ca275826609bcf96f103a8c50beaa47c3b4068b..045a83f944ebe3e5e969e4b414760413
202209
public int patrolSpawnerNextTick = 0;
203210
public int phantomSpawnerNextTick = 0;
204211
diff --git a/src/main/java/me/earthme/luminol/LuminolConfig.java b/src/main/java/me/earthme/luminol/LuminolConfig.java
205-
index e8cd180bab5c196db09ded74aea676b4412fc6e9..22ee6f520958fbc4301d82872faa4a8af4339a8e 100644
212+
index e8cd180bab5c196db09ded74aea676b4412fc6e9..534f54be1495b1a8f754bec0eb1aba8306c1d902 100644
206213
--- a/src/main/java/me/earthme/luminol/LuminolConfig.java
207214
+++ b/src/main/java/me/earthme/luminol/LuminolConfig.java
208-
@@ -62,6 +62,7 @@ public class LuminolConfig {
215+
@@ -2,6 +2,7 @@ package me.earthme.luminol;
216+
217+
import dev.kaiijumc.kaiiju.region.RegionFileFormat;
218+
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
219+
+import io.papermc.paper.threadedregions.RegionizedWorldData;
220+
import me.earthme.luminol.commands.TpsBarCommand;
221+
import me.earthme.luminol.functions.GlobalServerTpsBar;
222+
import net.minecraft.core.registries.BuiltInRegistries;
223+
@@ -62,6 +63,7 @@ public class LuminolConfig {
209224
public static boolean asyncPathProcessing = false;
210225
public static int asyncPathProcessingMaxThreads = 0;
211226
public static int asyncPathProcessingKeepalive = 60;
212227
+ public static boolean enableAsyncMobSpawning = false;
213228

214229
public static void init() throws IOException {
215230
PARENT_FOLDER.mkdir();
216-
@@ -188,6 +189,7 @@ public class LuminolConfig {
231+
@@ -188,6 +190,8 @@ public class LuminolConfig {
217232
asyncPathProcessingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1);
218233
if (!asyncPathProcessing)
219234
asyncPathProcessingMaxThreads = 0;
220235
+ enableAsyncMobSpawning = get("optimizations.enable_async_mob_spawning",enableAsyncMobSpawning);
236+
+ RegionizedWorldData.initMobSpawningExecutor();
221237
}
222238

223239
public static <T> T get(String key,T def){
@@ -299,10 +315,10 @@ index 0000000000000000000000000000000000000000..88d5b188ccfb17fe1ae4b08f32565f27
299315
+ }
300316
+}
301317
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
302-
index b9b1dfe04eda8498f0ceff0aee66489d2a02b814..a50e6249eec7a8211b4674f34acd5d7104d825dd 100644
318+
index b9b1dfe04eda8498f0ceff0aee66489d2a02b814..c470eafef884075b6e4d170adc2ced96a4beb517 100644
303319
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
304320
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
305-
@@ -11,13 +11,14 @@ import java.util.Collections;
321+
@@ -11,13 +11,15 @@ import java.util.Collections;
306322
import java.util.Iterator;
307323
import java.util.List;
308324
import java.util.Objects;
@@ -314,11 +330,12 @@ index b9b1dfe04eda8498f0ceff0aee66489d2a02b814..a50e6249eec7a8211b4674f34acd5d71
314330
import java.util.function.Supplier;
315331
import javax.annotation.Nullable;
316332
+
333+
+import io.papermc.paper.threadedregions.RegionizedWorldData;
317334
+import me.earthme.luminol.LuminolConfig;
318335
import net.minecraft.Util;
319336
import net.minecraft.core.BlockPos;
320337
import net.minecraft.core.SectionPos;
321-
@@ -487,32 +488,38 @@ public class ServerChunkCache extends ChunkSource {
338+
@@ -487,32 +489,38 @@ public class ServerChunkCache extends ChunkSource {
322339
this.level.timings.countNaturalMobs.startTiming(); // Paper - timings
323340
int l = this.distanceManager.getNaturalSpawnChunkCount();
324341
// Paper start - per player mob spawning
@@ -374,7 +391,7 @@ index b9b1dfe04eda8498f0ceff0aee66489d2a02b814..a50e6249eec7a8211b4674f34acd5d71
374391
gameprofilerfiller.popPush("filteringLoadedChunks");
375392
// Paper - optimise chunk tick iteration
376393
// Paper - optimise chunk tick iteration
377-
@@ -610,7 +617,12 @@ public class ServerChunkCache extends ChunkSource {
394+
@@ -610,7 +618,12 @@ public class ServerChunkCache extends ChunkSource {
378395
chunk1.incrementInhabitedTime(j);
379396
if (spawn && flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration
380397
++spawnChunkCount; // Folia - profiler
@@ -388,7 +405,7 @@ index b9b1dfe04eda8498f0ceff0aee66489d2a02b814..a50e6249eec7a8211b4674f34acd5d71
388405
}
389406

390407
if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration
391-
@@ -667,6 +679,36 @@ public class ServerChunkCache extends ChunkSource {
408+
@@ -667,6 +680,36 @@ public class ServerChunkCache extends ChunkSource {
392409
gameprofilerfiller.pop();
393410
gameprofilerfiller.pop();
394411
this.chunkMap.tick();
@@ -413,19 +430,19 @@ index b9b1dfe04eda8498f0ceff0aee66489d2a02b814..a50e6249eec7a8211b4674f34acd5d71
413430
+ }
414431
+
415432
+ if (regionizedWorldData.lastAsyncSpawnStateTask == null || regionizedWorldData.lastAsyncSpawnStateTask.isDone()){
416-
+ regionizedWorldData.lastAsyncSpawnStateTask = CompletableFuture.supplyAsync(() -> NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true),regionizedWorldData.asyncMobSpawnExecutor);
433+
+ regionizedWorldData.lastAsyncSpawnStateTask = CompletableFuture.supplyAsync(() -> NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, null, true),RegionizedWorldData.ASYNC_MOB_SPAWNING_EXECUTOR);
417434
+ }
418435
+ } else {
419436
+ if (regionizedWorldData.lastAsyncSpawnStateTask == null || regionizedWorldData.lastAsyncSpawnStateTask.isDone()){
420-
+ regionizedWorldData.lastAsyncSpawnStateTask = CompletableFuture.supplyAsync(() -> NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false),regionizedWorldData.asyncMobSpawnExecutor);
437+
+ regionizedWorldData.lastAsyncSpawnStateTask = CompletableFuture.supplyAsync(() -> NaturalSpawner.createState(l, regionizedWorldData.getLoadedEntities(), this::getFullChunk, !this.level.paperConfig().entities.spawning.perPlayerMobSpawns ? new LocalMobCapCalculator(this.chunkMap) : null, false), RegionizedWorldData.ASYNC_MOB_SPAWNING_EXECUTOR);
421438
+ }
422439
+ }
423440
+ }
424441
+ //Luminol end
425442
}
426443
}
427444

428-
@@ -809,7 +851,7 @@ public class ServerChunkCache extends ChunkSource {
445+
@@ -809,7 +852,7 @@ public class ServerChunkCache extends ChunkSource {
429446
@VisibleForDebug
430447
public NaturalSpawner.SpawnState getLastSpawnState() {
431448
io.papermc.paper.threadedregions.RegionizedWorldData worldData = this.level.getCurrentWorldData(); // Folia - region threading

0 commit comments

Comments
 (0)