diff --git a/shiroha-server/minecraft-patches/features/0027-RegionizedTaskQueue-queue-TTL-optimization.patch b/shiroha-server/minecraft-patches/features/0027-RegionizedTaskQueue-queue-TTL-optimization.patch new file mode 100644 index 0000000..cce80f3 --- /dev/null +++ b/shiroha-server/minecraft-patches/features/0027-RegionizedTaskQueue-queue-TTL-optimization.patch @@ -0,0 +1,143 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NanaChiyo0721 +Date: Wed, 29 Jul 2026 18:39:56 +0800 +Subject: [PATCH] RegionizedTaskQueue queue TTL optimization + + +diff --git a/io/papermc/paper/threadedregions/RegionizedTaskQueue.java b/io/papermc/paper/threadedregions/RegionizedTaskQueue.java +index 037697e6364c73057b1fbac354bd78d8bf35bc7b..0e88bc2776615f8e3e1e6a05c5ffb8f791d49917 100644 +--- a/io/papermc/paper/threadedregions/RegionizedTaskQueue.java ++++ b/io/papermc/paper/threadedregions/RegionizedTaskQueue.java +@@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicLong; + public final class RegionizedTaskQueue { + + private static final TicketType TASK_QUEUE_TICKET = ChunkSystemTicketType.create("task_queue_ticket", Long::compareTo); ++ private static final long QUEUE_MAX_TTL_TICKS = 5L; // Shiroha - RegionizedTaskQueue queue TTL optimization + + public PrioritisedExecutor.PrioritisedTask createChunkTask(final ServerLevel world, final int chunkX, final int chunkZ, + final Runnable run) { +@@ -155,6 +156,58 @@ public final class RegionizedTaskQueue { + } + } + ++ // Shiroha start - RegionizedTaskQueue queue TTL optimization ++ public void tickQueueReferenceTTL() { ++ final ThreadedRegionizer.ThreadedRegion currentRegion ++ = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegion(); ++ if (currentRegion == null) { ++ return; ++ } ++ ++ final ReferenceCountData[] toRemoveTicket = new ReferenceCountData[1]; ++ ++ for (ConcurrentChainedLong2ReferenceHashTable.TableEntry counterEntry : this.referenceCounters.entrySet()) { ++ final long coord = counterEntry.getKey(); ++ final ReferenceCountData counterData = counterEntry.getValue(); ++ ++ // only tick for our region ++ if (currentRegion == this.world.regioniser.getRegionAtUnsynchronised(CoordinateUtils.getChunkX(coord), CoordinateUtils.getChunkZ(coord))) { ++ long curr = counterData.referenceTTL.get(); ++ // successfully decreased ttl ++ if (curr == (curr = counterData.referenceTTL.compareAndExchange(curr, curr - 1))) { ++ if (counterData.referenceCount.get() != 0L) { ++ // still has reference, pump back ++ counterData.referenceTTL.set(QUEUE_MAX_TTL_TICKS); ++ continue; ++ } ++ ++ // dead ++ if (curr <= 0) { ++ // parsed from decrementReference ++ this.referenceCounters.computeIfPresent(coord, (final long keyInMap, final ReferenceCountData valueInMap) -> { ++ // might be increased again ++ if (valueInMap.referenceCount.get() != 0L) { ++ valueInMap.referenceTTL.set(QUEUE_MAX_TTL_TICKS); // still has reference, pump back ++ return valueInMap; // directly, the ttl was already charged in add logic ++ } ++ ++ // note: valueInMap may not be referenceCountData ++ toRemoveTicket[0] = valueInMap; ++ ++ return null; ++ }); ++ ++ if (toRemoveTicket[0] != null) { ++ this.removeTicket(coord, toRemoveTicket[0].id); ++ toRemoveTicket[0] = null; ++ } ++ } ++ } ++ } ++ } ++ } ++ // Shiroha end - RegionizedTaskQueue queue TTL optimization ++ + private void decrementReference(final ReferenceCountData referenceCountData, final long coord) { + if (!referenceCountData.decreaseReferenceCount()) { + return; +@@ -212,9 +265,10 @@ public final class RegionizedTaskQueue { + private final long id = ID_GENERATOR.getAndIncrement(); + + public final AtomicLong referenceCount = new AtomicLong(1L); ++ public final AtomicLong referenceTTL = new AtomicLong(QUEUE_MAX_TTL_TICKS); // Shiroha - RegionizedTaskQueue queue TTL optimization + public volatile boolean addedTicket; + +- // returns false if reference count is 0, otherwise increments ref count ++ // returns false if reference count or ttl is 0, otherwise increments ref count // Shiroha - RegionizedTaskQueue queue TTL optimization + public boolean addCount() { + int failures = 0; + for (long curr = this.referenceCount.get();;) { +@@ -227,6 +281,27 @@ public final class RegionizedTaskQueue { + } + + if (curr == (curr = this.referenceCount.compareAndExchange(curr, curr + 1L))) { ++ // Shiroha start - RegionizedTaskQueue queue TTL optimization ++ // now force charge back the ttl to max ++ int ttlFailures = 0; ++ for (long currTTL = this.referenceTTL.get();;) { ++ for (int i = 0; i < ttlFailures; i++) { ++ Thread.onSpinWait(); ++ } ++ ++ // add failed, rollback (ttl reached) ++ if (currTTL <= 0) { ++ this.referenceCount.decrementAndGet(); // revert the addition ++ return false; ++ } ++ ++ if (currTTL == (currTTL = this.referenceTTL.compareAndExchange(currTTL, QUEUE_MAX_TTL_TICKS))) { ++ break; ++ } ++ ++ ++ttlFailures; ++ } ++ // Shiroha end - RegionizedTaskQueue queue TTL optimization + return true; + } + +@@ -234,11 +309,11 @@ public final class RegionizedTaskQueue { + } + } + +- // returns true if new reference count is 0 ++ // returns true if new reference count and ttl is 0 // Shiroha - RegionizedTaskQueue queue TTL optimization + public boolean decreaseReferenceCount() { + final long res = this.referenceCount.decrementAndGet(); + if (res >= 0L) { +- return res == 0L; ++ return res == 0L && this.referenceTTL.get() <= 0L; // Shiroha - RegionizedTaskQueue queue TTL optimization + } else { + throw new IllegalStateException("Negative reference count"); + } +diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java +index 3e62b4beb0e5ada82f83b0ebec35ca21a072a2e2..63fecdde56650fb056fa8de352abdf927b0549f8 100644 +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -1737,6 +1737,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop localPlayers = new CopyOnWriteArrayList<>(); diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 6025675b7004c9700ddc26638761f76d64ecc026..5be3e493f1638cc0befe5530c58ea15467a3a7ac 100644 +index 3ecedf303384c172a5e2a19c9e6ac0c3a43cef74..ee7fce1e4e9b94b1f9c956c376fff0abee51b0ca 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1932,6 +1932,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop level + " " + level.dimension().identifier()); profiler.push("tick"); @@ -82,7 +82,7 @@ index 6025675b7004c9700ddc26638761f76d64ecc026..5be3e493f1638cc0befe5530c58ea154 try { foliaProfiler.startTimer(level.tickTimerId); try { // Folia - profiler -@@ -1946,6 +1949,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop