mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-25 18:09:17 +00:00
Remove parallel world ticking
This commit is contained in:
@@ -1,223 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: wangxyper <wangxyper@163.com>
|
||||
Date: Thu, 12 Jan 2023 13:04:01 +0800
|
||||
Subject: [PATCH] Hearse: Parallel world ticking
|
||||
|
||||
Original license: MIT
|
||||
Original project: https://github.com/NaturalCodeClub/HearseRewrite
|
||||
|
||||
diff --git a/src/main/java/co/earthme/hearse/concurrent/threadfactory/DefaultWorkerFactory.java b/src/main/java/co/earthme/hearse/concurrent/threadfactory/DefaultWorkerFactory.java
|
||||
index 443ac5267245c20830692b37802afd6ebdf8813b..c26511c26bd02320a55a01168f342b4b051ffdfd 100644
|
||||
--- a/src/main/java/co/earthme/hearse/concurrent/threadfactory/DefaultWorkerFactory.java
|
||||
+++ b/src/main/java/co/earthme/hearse/concurrent/threadfactory/DefaultWorkerFactory.java
|
||||
@@ -8,14 +8,16 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
public class DefaultWorkerFactory implements WorkerThreadFactory {
|
||||
private static final AtomicInteger poolId = new AtomicInteger();
|
||||
private final AtomicInteger threadId = new AtomicInteger();
|
||||
+ private final String bound;
|
||||
|
||||
- public DefaultWorkerFactory(){
|
||||
+ public DefaultWorkerFactory(String bound){
|
||||
poolId.getAndIncrement();
|
||||
+ this.bound = bound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkerThread getNewThread(Runnable task) {
|
||||
- final WorkerThread workerThread = new WorkerThread(task,"pool-"+poolId.get()+"-worker-"+threadId.getAndIncrement());
|
||||
+ final WorkerThread workerThread = new WorkerThread(task,"pool-"+poolId.get()+"-worker-"+threadId.getAndIncrement()+"-bound-"+this.bound);
|
||||
if (workerThread.isDaemon()){
|
||||
workerThread.setDaemon(false);
|
||||
}
|
||||
diff --git a/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java b/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
|
||||
index fd7912df03ae39347206fe8db2efa7a8a0e516c8..9d26ff7d07f1e972f1720f5b2d0e66d4c9c3f1e5 100644
|
||||
--- a/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
|
||||
+++ b/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
|
||||
@@ -18,7 +18,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
public class ServerEntityTickHook {
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
private static volatile boolean firstTick = false;
|
||||
- private static final WorkerThreadFactory defFactory = new DefaultWorkerFactory();
|
||||
+ private static final WorkerThreadFactory defFactory = new DefaultWorkerFactory("entity");
|
||||
private static final AtomicInteger threadId = new AtomicInteger();
|
||||
private static WorkerThreadPoolExecutor worker;
|
||||
private static boolean asyncEntityEnabled;
|
||||
diff --git a/src/main/java/co/earthme/hearse/server/ServerLevelTickHook.java b/src/main/java/co/earthme/hearse/server/ServerLevelTickHook.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5670fdae5d16cbbdf605df048ae253208e49a82c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/co/earthme/hearse/server/ServerLevelTickHook.java
|
||||
@@ -0,0 +1,70 @@
|
||||
+package co.earthme.hearse.server;
|
||||
+
|
||||
+import co.earthme.hearse.Hearse;
|
||||
+import co.earthme.hearse.HearseConfig;
|
||||
+import co.earthme.hearse.concurrent.WorkerThreadPoolExecutor;
|
||||
+import co.earthme.hearse.concurrent.threadfactory.DefaultWorkerFactory;
|
||||
+import net.minecraft.CrashReport;
|
||||
+import net.minecraft.ReportedException;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+
|
||||
+import java.util.concurrent.LinkedBlockingQueue;
|
||||
+import java.util.concurrent.TimeUnit;
|
||||
+import java.util.concurrent.atomic.AtomicInteger;
|
||||
+import java.util.concurrent.locks.LockSupport;
|
||||
+import java.util.function.BooleanSupplier;
|
||||
+
|
||||
+public class ServerLevelTickHook {
|
||||
+ private static final DefaultWorkerFactory workerFactory = new DefaultWorkerFactory("world");
|
||||
+ private static WorkerThreadPoolExecutor worker;
|
||||
+ private static boolean enabledParaWorld;
|
||||
+ private static volatile boolean inited = false;
|
||||
+ private static final AtomicInteger activeTaskCount = new AtomicInteger();
|
||||
+
|
||||
+ public static void initWorker(){
|
||||
+ enabledParaWorld = HearseConfig.getBoolean("optimizations.enableparallelworldtick",true);
|
||||
+ if (enabledParaWorld){
|
||||
+ worker = new WorkerThreadPoolExecutor(
|
||||
+ MinecraftServer.getServer().levels.size(),
|
||||
+ MinecraftServer.getServer().levels.size(),
|
||||
+ 0,
|
||||
+ TimeUnit.MILLISECONDS,
|
||||
+ new LinkedBlockingQueue<>(),
|
||||
+ workerFactory
|
||||
+ );
|
||||
+ worker.prestartAllCoreThreads();
|
||||
+ Hearse.getWorkerManager().addWorker("world",worker);
|
||||
+ }
|
||||
+ inited = true;
|
||||
+ }
|
||||
+
|
||||
+ public static boolean isInited(){
|
||||
+ return inited;
|
||||
+ }
|
||||
+
|
||||
+ public static void callWorldTick(ServerLevel worldserver, BooleanSupplier shouldKeepTicking){
|
||||
+ activeTaskCount.getAndIncrement();
|
||||
+ worker.execute(()->{
|
||||
+ try {
|
||||
+ try {
|
||||
+ worldserver.tick(shouldKeepTicking);
|
||||
+ for (final io.papermc.paper.chunk.SingleThreadChunkRegionManager regionManager : worldserver.getChunkSource().chunkMap.regionManagers) {
|
||||
+ regionManager.recalculateRegions();
|
||||
+ }
|
||||
+ } catch (Throwable throwable) {
|
||||
+ throwable.printStackTrace();
|
||||
+ }
|
||||
+ worldserver.explosionDensityCache.clear();
|
||||
+ }finally {
|
||||
+ activeTaskCount.getAndDecrement();
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ public static void awaitWorldTicKTasks(){
|
||||
+ while (activeTaskCount.get() > 0){
|
||||
+ LockSupport.parkNanos("Await world ticking",1000000);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index fe47aff8654283aa6a17a36226aa9fc7f18f9886..57bae261ee1d6db734b38dd5f67dbce98c41fc1c 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -3,6 +3,7 @@ package net.minecraft.server;
|
||||
import co.earthme.hearse.Hearse;
|
||||
import co.earthme.hearse.HearseConfig;
|
||||
import co.earthme.hearse.server.ServerEntityTickHook;
|
||||
+import co.earthme.hearse.server.ServerLevelTickHook;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -223,7 +224,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
private String localIp;
|
||||
private int port;
|
||||
private final LayeredRegistryAccess<RegistryLayer> registries;
|
||||
- private Map<ResourceKey<Level>, ServerLevel> levels;
|
||||
+ public Map<ResourceKey<Level>, ServerLevel> levels;
|
||||
private PlayerList playerList;
|
||||
private volatile boolean running;
|
||||
private volatile boolean isRestarting = false; // Paper - flag to signify we're attempting to restart
|
||||
@@ -1121,6 +1122,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
Arrays.fill( recentTps, 20 );
|
||||
long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
|
||||
lastTick = start - TICK_TIME; // Paper
|
||||
+ ServerLevelTickHook.initWorker(); //Hearse
|
||||
while (this.running) {
|
||||
// Paper start - rewrite chunk system
|
||||
// guarantee that nothing can stop the server from halting if it can at least still tick
|
||||
@@ -1515,11 +1517,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
//MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot // Paper // Purpur
|
||||
|
||||
this.isIteratingOverLevels = true; // Paper
|
||||
- Iterator iterator = this.getAllLevels().iterator(); // Paper - move down
|
||||
- while (iterator.hasNext()) {
|
||||
- ServerLevel worldserver = (ServerLevel) iterator.next();
|
||||
- worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
|
||||
- worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
|
||||
+ for (ServerLevel worldserver : this.getAllLevels()) {
|
||||
+ worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
|
||||
+ worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
|
||||
net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
|
||||
|
||||
/*this.profiler.push(() -> { // Purpur
|
||||
@@ -1534,35 +1534,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// CraftBukkit end */
|
||||
|
||||
//this.profiler.push("tick"); // Purpur
|
||||
-
|
||||
- try {
|
||||
- //worldserver.timings.doTick.startTiming(); // Spigot // Purpur
|
||||
- worldserver.tick(shouldKeepTicking);
|
||||
- // Paper start
|
||||
- for (final io.papermc.paper.chunk.SingleThreadChunkRegionManager regionManager : worldserver.getChunkSource().chunkMap.regionManagers) {
|
||||
- regionManager.recalculateRegions();
|
||||
- }
|
||||
- // Paper end
|
||||
- //worldserver.timings.doTick.stopTiming(); // Spigot // Purpur
|
||||
- } catch (Throwable throwable) {
|
||||
- // Spigot Start
|
||||
- CrashReport crashreport;
|
||||
- try {
|
||||
- crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
|
||||
- } catch (Throwable t) {
|
||||
- if (throwable instanceof ThreadDeath) { throw (ThreadDeath)throwable; } // Paper
|
||||
- throw new RuntimeException("Error generating crash report", t);
|
||||
- }
|
||||
- // Spigot End
|
||||
-
|
||||
- worldserver.fillReportDetails(crashreport);
|
||||
- throw new ReportedException(crashreport);
|
||||
- }
|
||||
-
|
||||
- //this.profiler.pop(); // Purpur
|
||||
- //this.profiler.pop(); // Purpur
|
||||
- worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
|
||||
+ ServerLevelTickHook.callWorldTick(worldserver,shouldKeepTicking);
|
||||
}
|
||||
+ ServerLevelTickHook.awaitWorldTicKTasks();
|
||||
this.isIteratingOverLevels = false; // Paper
|
||||
|
||||
//this.profiler.popPush("connection"); // Purpur
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index de78c5bdde53b4adfed9fda4d473560849bdb5aa..4a75c2895f4f5e3229be3c7b177445611a1e70b6 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -7,6 +7,7 @@ import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
||||
import com.destroystokyo.paper.exception.ServerInternalException;
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.collect.Lists;
|
||||
+import com.google.common.collect.Maps;
|
||||
import com.mojang.serialization.Codec;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
@@ -179,7 +180,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
private org.spigotmc.TickLimiter entityLimiter;
|
||||
private org.spigotmc.TickLimiter tileLimiter;
|
||||
private int tileTickPosition;
|
||||
- public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
|
||||
+ public final Map<Explosion.CacheKey, Float> explosionDensityCache = Maps.newConcurrentMap(); // Paper - Optimize explosions
|
||||
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
|
||||
|
||||
// Paper start - fix and optimise world upgrading
|
||||
@@ -8,7 +8,7 @@ Original license: MIT
|
||||
Original project: https://github.com/NaturalCodeClub/HearseRewrite
|
||||
|
||||
diff --git a/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java b/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
|
||||
index 9d26ff7d07f1e972f1720f5b2d0e66d4c9c3f1e5..86f8afd54c0cbb449403c3f43e6880ade13cfecc 100644
|
||||
index fd7912df03ae39347206fe8db2efa7a8a0e516c8..85f92f20718ae21bffd687e00614588c771cc940 100644
|
||||
--- a/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
|
||||
+++ b/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
|
||||
@@ -8,6 +8,7 @@ import co.earthme.hearse.concurrent.threadfactory.DefaultWorkerFactory;
|
||||
@@ -1,102 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: wangxyper <wangxyper@163.com>
|
||||
Date: Thu, 12 Jan 2023 13:58:20 +0800
|
||||
Subject: [PATCH] Hearse: Print world worker thread names when server started
|
||||
|
||||
Original license: MIT
|
||||
Original project: https://github.com/NaturalCodeClub/HearseRewrite
|
||||
|
||||
diff --git a/src/main/java/co/earthme/hearse/concurrent/threadfactory/DefaultWorkerFactory.java b/src/main/java/co/earthme/hearse/concurrent/threadfactory/DefaultWorkerFactory.java
|
||||
index c26511c26bd02320a55a01168f342b4b051ffdfd..03a29509821a17faac2dc8ab810a2693b03bfbc6 100644
|
||||
--- a/src/main/java/co/earthme/hearse/concurrent/threadfactory/DefaultWorkerFactory.java
|
||||
+++ b/src/main/java/co/earthme/hearse/concurrent/threadfactory/DefaultWorkerFactory.java
|
||||
@@ -2,25 +2,38 @@ package co.earthme.hearse.concurrent.threadfactory;
|
||||
|
||||
import co.earthme.hearse.concurrent.WorkerThread;
|
||||
import co.earthme.hearse.concurrent.WorkerThreadFactory;
|
||||
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
+import it.unimi.dsi.fastutil.objects.ObjectLists;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
+
|
||||
+import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class DefaultWorkerFactory implements WorkerThreadFactory {
|
||||
private static final AtomicInteger poolId = new AtomicInteger();
|
||||
private final AtomicInteger threadId = new AtomicInteger();
|
||||
private final String bound;
|
||||
+ private final List<Thread> createdThreads = ObjectLists.synchronize(new ObjectArrayList<>());
|
||||
|
||||
public DefaultWorkerFactory(String bound){
|
||||
poolId.getAndIncrement();
|
||||
this.bound = bound;
|
||||
}
|
||||
|
||||
+ public List<Thread> getCreatedThreads() {
|
||||
+ return this.createdThreads;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public WorkerThread getNewThread(Runnable task) {
|
||||
- final WorkerThread workerThread = new WorkerThread(task,"pool-"+poolId.get()+"-worker-"+threadId.getAndIncrement()+"-bound-"+this.bound);
|
||||
- if (workerThread.isDaemon()){
|
||||
- workerThread.setDaemon(false);
|
||||
- }
|
||||
+ final WorkerThread workerThread = new WorkerThread(()->{
|
||||
+ try {
|
||||
+ task.run();
|
||||
+ }finally {
|
||||
+ this.createdThreads.remove(Thread.currentThread());
|
||||
+ }
|
||||
+ },"pool-"+poolId.get()+"-worker-"+threadId.getAndIncrement()+"-bound-"+this.bound);
|
||||
+ this.createdThreads.add(workerThread);
|
||||
workerThread.setDaemon(true);
|
||||
workerThread.setPriority(Thread.NORM_PRIORITY - 2);
|
||||
workerThread.setContextClassLoader(MinecraftServer.class.getClassLoader());
|
||||
diff --git a/src/main/java/co/earthme/hearse/server/ServerLevelTickHook.java b/src/main/java/co/earthme/hearse/server/ServerLevelTickHook.java
|
||||
index 5670fdae5d16cbbdf605df048ae253208e49a82c..8085eb700d8e5c20ebb5bfeceb78198c6e973019 100644
|
||||
--- a/src/main/java/co/earthme/hearse/server/ServerLevelTickHook.java
|
||||
+++ b/src/main/java/co/earthme/hearse/server/ServerLevelTickHook.java
|
||||
@@ -2,12 +2,15 @@ package co.earthme.hearse.server;
|
||||
|
||||
import co.earthme.hearse.Hearse;
|
||||
import co.earthme.hearse.HearseConfig;
|
||||
+import co.earthme.hearse.concurrent.WorkerThread;
|
||||
import co.earthme.hearse.concurrent.WorkerThreadPoolExecutor;
|
||||
import co.earthme.hearse.concurrent.threadfactory.DefaultWorkerFactory;
|
||||
import net.minecraft.CrashReport;
|
||||
import net.minecraft.ReportedException;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
+import org.apache.logging.log4j.LogManager;
|
||||
+import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -21,6 +24,7 @@ public class ServerLevelTickHook {
|
||||
private static boolean enabledParaWorld;
|
||||
private static volatile boolean inited = false;
|
||||
private static final AtomicInteger activeTaskCount = new AtomicInteger();
|
||||
+ private static final Logger logger = LogManager.getLogger();
|
||||
|
||||
public static void initWorker(){
|
||||
enabledParaWorld = HearseConfig.getBoolean("optimizations.enableparallelworldtick",true);
|
||||
@@ -28,13 +32,17 @@ public class ServerLevelTickHook {
|
||||
worker = new WorkerThreadPoolExecutor(
|
||||
MinecraftServer.getServer().levels.size(),
|
||||
MinecraftServer.getServer().levels.size(),
|
||||
- 0,
|
||||
+ Long.MAX_VALUE,
|
||||
TimeUnit.MILLISECONDS,
|
||||
new LinkedBlockingQueue<>(),
|
||||
workerFactory
|
||||
);
|
||||
+ worker.allowCoreThreadTimeOut(true);
|
||||
worker.prestartAllCoreThreads();
|
||||
Hearse.getWorkerManager().addWorker("world",worker);
|
||||
+ for (Thread worker : workerFactory.getCreatedThreads()){
|
||||
+ logger.warn("World worker name:{}.This can help you to slove the lag problems when you using parallel world ticking",worker.getName());
|
||||
+ }
|
||||
}
|
||||
inited = true;
|
||||
}
|
||||
Reference in New Issue
Block a user