diff --git a/README.md b/README.md index ac44495d..9fc6b718 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,7 @@ - Allowing players use tripwire dupe. - Disabling the UseItemOnPacket Too Far check. - Update all dependencies to the latest. - - Parallel entity ticking(Half of async)(In alpha) - - Parallel world ticking + - Parallel entity ticking(Half of async)(In beta) - Some Purpur patches. - ... diff --git a/patches/server/0063-Hearse-Fix-some-NPE-errors.patch b/patches/server/0061-Hearse-Fix-some-NPE-errors.patch similarity index 100% rename from patches/server/0063-Hearse-Fix-some-NPE-errors.patch rename to patches/server/0061-Hearse-Fix-some-NPE-errors.patch diff --git a/patches/server/0061-Hearse-Parallel-world-ticking.patch b/patches/server/0061-Hearse-Parallel-world-ticking.patch deleted file mode 100644 index 5a776ea3..00000000 --- a/patches/server/0061-Hearse-Parallel-world-ticking.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: wangxyper -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 registries; -- private Map, ServerLevel> levels; -+ public Map, 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 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 explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions -+ public final Map explosionDensityCache = Maps.newConcurrentMap(); // Paper - Optimize explosions - public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here - - // Paper start - fix and optimise world upgrading diff --git a/patches/server/0064-Hearse-Move-player-ticking-to-main-thread-and-add-lo.patch b/patches/server/0062-Hearse-Move-player-ticking-to-main-thread-and-add-lo.patch similarity index 100% rename from patches/server/0064-Hearse-Move-player-ticking-to-main-thread-and-add-lo.patch rename to patches/server/0062-Hearse-Move-player-ticking-to-main-thread-and-add-lo.patch diff --git a/patches/server/0062-Hearse-Print-world-worker-thread-names-when-server-s.patch b/patches/server/0062-Hearse-Print-world-worker-thread-names-when-server-s.patch deleted file mode 100644 index 6a36fa67..00000000 --- a/patches/server/0062-Hearse-Print-world-worker-thread-names-when-server-s.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: wangxyper -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 createdThreads = ObjectLists.synchronize(new ObjectArrayList<>()); - - public DefaultWorkerFactory(String bound){ - poolId.getAndIncrement(); - this.bound = bound; - } - -+ public List 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; - } diff --git a/patches/server/0065-Hearse-Remove-some-lock-in-ChunkEntitySlices.patch b/patches/server/0063-Hearse-Remove-some-lock-in-ChunkEntitySlices.patch similarity index 100% rename from patches/server/0065-Hearse-Remove-some-lock-in-ChunkEntitySlices.patch rename to patches/server/0063-Hearse-Remove-some-lock-in-ChunkEntitySlices.patch diff --git a/patches/server/0066-Hearse-Fix-a-dead-lock.patch b/patches/server/0064-Hearse-Fix-a-dead-lock.patch similarity index 100% rename from patches/server/0066-Hearse-Fix-a-dead-lock.patch rename to patches/server/0064-Hearse-Fix-a-dead-lock.patch diff --git a/patches/server/0067-Hearse-Fix-a-concurrent-problem.patch b/patches/server/0065-Hearse-Fix-a-concurrent-problem.patch similarity index 100% rename from patches/server/0067-Hearse-Fix-a-concurrent-problem.patch rename to patches/server/0065-Hearse-Fix-a-concurrent-problem.patch diff --git a/patches/server/0068-Hearse-Remove-a-NPE-fix.patch b/patches/server/0066-Hearse-Remove-a-NPE-fix.patch similarity index 100% rename from patches/server/0068-Hearse-Remove-a-NPE-fix.patch rename to patches/server/0066-Hearse-Remove-a-NPE-fix.patch diff --git a/patches/server/0069-Hearse-Add-new-command.patch b/patches/server/0067-Hearse-Add-new-command.patch similarity index 100% rename from patches/server/0069-Hearse-Add-new-command.patch rename to patches/server/0067-Hearse-Add-new-command.patch diff --git a/patches/server/0070-Hearse-Fix-a-NoSuchElementError-in-Delayed8-and-Dela.patch b/patches/server/0068-Hearse-Fix-a-NoSuchElementError-in-Delayed8-and-Dela.patch similarity index 100% rename from patches/server/0070-Hearse-Fix-a-NoSuchElementError-in-Delayed8-and-Dela.patch rename to patches/server/0068-Hearse-Fix-a-NoSuchElementError-in-Delayed8-and-Dela.patch diff --git a/patches/server/0071-Hearse-Optimized-some-locks-in-ChunkEntitySlices.patch b/patches/server/0069-Hearse-Optimized-some-locks-in-ChunkEntitySlices.patch similarity index 100% rename from patches/server/0071-Hearse-Optimized-some-locks-in-ChunkEntitySlices.patch rename to patches/server/0069-Hearse-Optimized-some-locks-in-ChunkEntitySlices.patch diff --git a/patches/server/0072-Hearse-Remove-a-lock-in-ServerChunkCache.patch b/patches/server/0070-Hearse-Remove-a-lock-in-ServerChunkCache.patch similarity index 100% rename from patches/server/0072-Hearse-Remove-a-lock-in-ServerChunkCache.patch rename to patches/server/0070-Hearse-Remove-a-lock-in-ServerChunkCache.patch