RegionizedTaskQueue queue TTL optimization

This commit is contained in:
2026-07-29 23:13:20 +08:00
parent 80b61f6757
commit dcaaa5f623
56 changed files with 151 additions and 8 deletions
@@ -0,0 +1,143 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NanaChiyo0721 <nanachiyo0721@163.com>
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<Long> 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<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> currentRegion
+ = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegion();
+ if (currentRegion == null) {
+ return;
+ }
+
+ final ReferenceCountData[] toRemoveTicket = new ReferenceCountData[1];
+
+ for (ConcurrentChainedLong2ReferenceHashTable.TableEntry<ReferenceCountData> 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<TickTa
foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.PASSENGER_DESYNC_CHECK);
}
// Folia end - fix passenger desync
+ region.world.taskQueueRegionData.tickQueueReferenceTTL(); // Shiroha - RegionizedTaskQueue queue TTL optimization
}
// Folia end - region threading
//this.tickCount++; // Folia - region threading
@@ -5,10 +5,10 @@ Subject: [PATCH] Add config for server mod name
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 3e62b4beb0e5ada82f83b0ebec35ca21a072a2e2..6025675b7004c9700ddc26638761f76d64ecc026 100644 index 63fecdde56650fb056fa8de352abdf927b0549f8..3ecedf303384c172a5e2a19c9e6ac0c3a43cef74 100644
--- a/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -2070,7 +2070,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -2071,7 +2071,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} }
public String getServerModName() { public String getServerModName() {
@@ -69,10 +69,10 @@ index df9a8fba86b61d2d2f82e40e0f317cab84faa2ff..7cbf93b183eaeb156467044ccdb2923e
// this is copy on write to allow packet processing to iterate safely // this is copy on write to allow packet processing to iterate safely
private final CopyOnWriteArrayList<ServerPlayer> localPlayers = new CopyOnWriteArrayList<>(); private final CopyOnWriteArrayList<ServerPlayer> localPlayers = new CopyOnWriteArrayList<>();
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java 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 --- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -1932,6 +1932,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1933,6 +1933,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
//net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = level.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers // Folia - region threading //net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = level.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers // Folia - region threading
profiler.push(() -> level + " " + level.dimension().identifier()); profiler.push(() -> level + " " + level.dimension().identifier());
profiler.push("tick"); profiler.push("tick");
@@ -82,7 +82,7 @@ index 6025675b7004c9700ddc26638761f76d64ecc026..5be3e493f1638cc0befe5530c58ea154
try { try {
foliaProfiler.startTimer(level.tickTimerId); try { // Folia - profiler foliaProfiler.startTimer(level.tickTimerId); try { // Folia - profiler
@@ -1946,6 +1949,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1947,6 +1950,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
profiler.pop(); profiler.pop();
profiler.pop(); profiler.pop();
regionizedWorldData.explosionDensityCache.clear(); // Paper - Optimize explosions // Folia - region threading regionizedWorldData.explosionDensityCache.clear(); // Paper - Optimize explosions // Folia - region threading
@@ -17,10 +17,10 @@ index 52dcbcf64c3a510d4a4524b7d0ee226d9a73511d..051d601e7e809518e8d82ae4ae325905
} }
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 5be3e493f1638cc0befe5530c58ea15467a3a7ac..15e7d8f1fbc950f79486704f2133a7b10e303a8a 100644 index ee7fce1e4e9b94b1f9c956c376fff0abee51b0ca..87099cabe804741e6dc278bccdfa79b045e201fb 100644
--- a/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -1741,7 +1741,46 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1742,7 +1742,46 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Folia end - region threading // Folia end - region threading
//this.tickCount++; // Folia - region threading //this.tickCount++; // Folia - region threading
//this.tickRateManager.tick(); // Folia - region threading //this.tickRateManager.tick(); // Folia - region threading
@@ -8,7 +8,7 @@ A part of Leaf(https://github.com/Winds-Studio/Leaf/blob/edb0504069139beaa6f39ef
License: https://github.com/Winds-Studio/Leaf/blob/edb0504069139beaa6f39efa4702370c2576b3fc/LICENSE.md License: https://github.com/Winds-Studio/Leaf/blob/edb0504069139beaa6f39efa4702370c2576b3fc/LICENSE.md
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 15e7d8f1fbc950f79486704f2133a7b10e303a8a..95ae9d9882b27fa1e7df13002e793f27a8d86c09 100644 index 87099cabe804741e6dc278bccdfa79b045e201fb..c9834a20b5c281c27922b4db1fd5bf43c93c4afb 100644
--- a/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -217,7 +217,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -217,7 +217,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa