Compare commits

...

3 Commits

Author SHA1 Message Date
Spottedleaf
23ed0843b0 Update ScheduledTaskThreadPool
1. Adjust insertion last task process time to be the current time.
   This makes fresh inserts to be scheduled fairly with current
   inserts.
2. Always attempt to watch global first task
   This should try to prevent multiple scheduler threads from
   waiting on the same task. If the global first task is our task,
   then we can avoid retrying for the next task.
3. Correctly set runner state to TASKS when parsing intermediate
   tasks. This will prevent the runner from being interrupted
   by notifyTasks.
2025-03-21 08:53:19 -07:00
Spottedleaf
1934a00bdc Add new tick region scheduler
The old region scheduler had a few problems:
1. Inability to process intermediate tasks (chunk/packets) leading
   to higher than Paper/Vanilla latencies for task processing
2. Thread swapping: scheduled tasks had no thread preference, which
   lead to them swapping threads which may not be cache efficient

The new scheduler solves both of these issues. The new scheduler
can process intermediate tasks, and combined with the new packet
scheduler this allows packets to be processed at low latency
provided that the scheduler threads are idle or waiting.

The new scheduler will only move a scheduled tick/task to another
scheduling thread provided that its scheduled start is missed by
a specified time (for now, 2ms). This should ensure that thread
swapping only occurs to meet scheduling deadlines.
2025-03-20 13:02:57 -07:00
Spottedleaf
bc157c78bc Update Paper 2025-03-20 12:56:40 -07:00
7 changed files with 2255 additions and 31 deletions

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Add TPS From Region
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index a371da9d1d9d1b6cb266db58b9f74a09dc858d2c..41be5d8085d1640ba440ab23bc5ca9ba4b4ba804 100644
index db47fe6560e1b0c737889698cf52c5c3fb06185f..8fa129f4ddac786fb14bb42fc2a88a9e50020537 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -2979,6 +2979,42 @@ public final class Bukkit {
@@ -2982,6 +2982,42 @@ public final class Bukkit {
return server.isGlobalTickThread();
}
// Paper end - Folia region threading API
@ -52,10 +52,10 @@ index a371da9d1d9d1b6cb266db58b9f74a09dc858d2c..41be5d8085d1640ba440ab23bc5ca9ba
/**
* @deprecated All methods on this class have been deprecated, see the individual methods for replacements.
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index d7ebfcfc6a41b7e94a041f7faf3c2d8090fab3c4..012b4b11dcf04c89af1e4c1417d82d676eb5f767 100644
index 2eb72a31cc36a41694654da15be5a1f4983aa1bd..4830b0e31c970cbd336f4a5296284f5e9c4a94d8 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -2698,4 +2698,34 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
@@ -2696,4 +2696,34 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/
void allowPausing(@NotNull org.bukkit.plugin.Plugin plugin, boolean value);
// Paper end - API to check if the server is sleeping

View File

@ -12205,7 +12205,7 @@ index d3c50acc5ca30b608825d4baff4b7e09a9e0f586..464bd9e968610ef9144f7dff1eead3db
// Paper end - lag compensation
}
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 57d432dc9e8d8e9a3e088e7c40b35178c30fe786..f5615c7f7127edda460db9158d6bd4ddad9193f7 100644
index 3de65c4025be91d938a350c884975cb6edc234d3..310ec59ca44f27403c3e1448441d0dec033a3967 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -180,7 +180,7 @@ import org.slf4j.Logger;
@ -12217,7 +12217,7 @@ index 57d432dc9e8d8e9a3e088e7c40b35178c30fe786..f5615c7f7127edda460db9158d6bd4dd
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
private static final int FLY_STAT_RECORDING_SPEED = 25;
@@ -443,8 +443,149 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -450,8 +450,149 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.maxHealthCache = this.getMaxHealth();
}
@ -12367,7 +12367,7 @@ index 57d432dc9e8d8e9a3e088e7c40b35178c30fe786..f5615c7f7127edda460db9158d6bd4dd
AABB aabb = this.getDimensions(Pose.STANDING).makeBoundingBox(Vec3.ZERO);
BlockPos blockPos = pos;
if (level.dimensionType().hasSkyLight() && level.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit
@@ -533,7 +674,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -540,7 +681,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.getBukkitEntity().readExtraData(compound); // CraftBukkit
if (this.isSleeping()) {
@ -12376,7 +12376,7 @@ index 57d432dc9e8d8e9a3e088e7c40b35178c30fe786..f5615c7f7127edda460db9158d6bd4dd
}
// CraftBukkit start
@@ -709,10 +850,17 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -716,10 +857,17 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
ServerLevel level = this.level().getServer().getLevel(optional.get());
if (level != null) {
Entity entity = EntityType.loadEntityRecursive(
@ -12396,7 +12396,7 @@ index 57d432dc9e8d8e9a3e088e7c40b35178c30fe786..f5615c7f7127edda460db9158d6bd4dd
} else {
LOGGER.warn("Failed to spawn player ender pearl in level ({}), skipping", optional.get());
}
@@ -817,12 +965,23 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -824,12 +972,23 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
Entity camera = this.getCamera();
if (camera != this) {
@ -12421,7 +12421,7 @@ index 57d432dc9e8d8e9a3e088e7c40b35178c30fe786..f5615c7f7127edda460db9158d6bd4dd
} else {
this.setCamera(this);
}
@@ -1357,9 +1516,332 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -1364,9 +1523,332 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
}
}
@ -12754,7 +12754,7 @@ index 57d432dc9e8d8e9a3e088e7c40b35178c30fe786..f5615c7f7127edda460db9158d6bd4dd
if (this.isSleeping()) return null; // CraftBukkit - SPIGOT-3154
if (this.isRemoved()) {
return null;
@@ -2397,7 +2879,30 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -2404,7 +2886,30 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
return (Entity)(this.camera == null ? this : this.camera);
}
@ -12785,7 +12785,7 @@ index 57d432dc9e8d8e9a3e088e7c40b35178c30fe786..f5615c7f7127edda460db9158d6bd4dd
Entity camera = this.getCamera();
this.camera = (Entity)(entityToSpectate == null ? this : entityToSpectate);
if (camera != this.camera) {
@@ -2416,16 +2921,19 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -2423,16 +2928,19 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
}
}
// Paper end - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity
@ -12812,7 +12812,7 @@ index 57d432dc9e8d8e9a3e088e7c40b35178c30fe786..f5615c7f7127edda460db9158d6bd4dd
}
}
@@ -2896,11 +3404,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -2903,11 +3411,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
}
public void registerEnderPearl(ThrownEnderpearl enderPearl) {
@ -12826,7 +12826,7 @@ index 57d432dc9e8d8e9a3e088e7c40b35178c30fe786..f5615c7f7127edda460db9158d6bd4dd
}
public Set<ThrownEnderpearl> getEnderPearls() {
@@ -3054,7 +3562,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -3061,7 +3569,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.experienceLevel = this.newLevel;
this.totalExperience = this.newTotalExp;
this.experienceProgress = 0;
@ -13121,7 +13121,7 @@ index bd07e6a5aa1883786d789ea71711a0c0c0a95c26..09469ad131622158fe5579216fc41642
}
// Spigot end
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 1205307b7d2336fa6c5395a65be6643228c49d72..a2fe9286d432909ba0cb3731a166514af768dc37 100644
index b4a284a0617167fd12e9d9414b17f86c169ba563..3977d5b52c4473ed04019f8e93d7dbf084070a97 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -292,10 +292,10 @@ public class ServerGamePacketListenerImpl
@ -13621,7 +13621,7 @@ index 7dbcd9d96f052bb10127ad2b061154c23cc9ffd4..20d895ed04cd2263560f91ef38dda6aa
date = defaultValue;
}
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 5a4960fdbd97d830ac79845697eea9372c48a13b..7b13a9e7d38efe7786023747f55ebf5a2ba80688 100644
index c9dbe659374e3ce140316116e05110567e44b810..f2cf984f053b7a60255eaa245777abb0e1557c54 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -110,10 +110,10 @@ public abstract class PlayerList {
@ -14011,7 +14011,7 @@ index 5a4960fdbd97d830ac79845697eea9372c48a13b..7b13a9e7d38efe7786023747f55ebf5a
this.save(player);
if (interval != -1 && ++numSaved >= io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.maxPerTick()) {
break;
@@ -1194,6 +1280,20 @@ public abstract class PlayerList {
@@ -1199,6 +1285,20 @@ public abstract class PlayerList {
}
public void removeAll(boolean isRestarting) {
@ -14032,7 +14032,7 @@ index 5a4960fdbd97d830ac79845697eea9372c48a13b..7b13a9e7d38efe7786023747f55ebf5a
// Paper end
// CraftBukkit start - disconnect safely
for (ServerPlayer player : this.players) {
@@ -1203,7 +1303,7 @@ public abstract class PlayerList {
@@ -1208,7 +1308,7 @@ public abstract class PlayerList {
// CraftBukkit end
// Paper start - Configurable player collision; Remove collideRule team if it exists

View File

@ -7,10 +7,10 @@ This allows the player to be re-positioned before logging into
the world without causing thread checks to trip on Folia.
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index f5615c7f7127edda460db9158d6bd4ddad9193f7..423534a1ff02bd0d0f9baacfe2428f45c7d9acb9 100644
index 310ec59ca44f27403c3e1448441d0dec033a3967..dbf9231b1f01576906b90a3ddf0bf2cbbeb4590a 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -775,8 +775,18 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -782,8 +782,18 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
public void loadAndSpawnParentVehicle(Optional<CompoundTag> tag) {
if (tag.isPresent() && tag.get().contains("RootVehicle", 10) && this.level() instanceof ServerLevel serverLevel) {
CompoundTag compound = tag.get().getCompound("RootVehicle");

File diff suppressed because it is too large Load Diff

View File

@ -413,10 +413,10 @@ index bd68139ae635f2ad7ec8e7a21e0056a139c4c62e..48a43341b17247355a531164019d5cc9
}
diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
index 42777adb028fe282c1619aeb5431c442ad5df0d0..de88c3d9d3523a7bd3f3dcbfc62d72658192521d 100644
index e3a7e6937122413bff911fe1188e3bb0297f6ffa..7f4d1637ae8b7730013cf0901cf7882a5a238e63 100644
--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
@@ -398,4 +398,17 @@ public class GlobalConfiguration extends ConfigurationPart {
@@ -402,4 +402,17 @@ public class GlobalConfiguration extends ConfigurationPart {
}
}
}
@ -4026,10 +4026,10 @@ index 2638c341bc02f201f7ab17fdebcdbdf3a7ec05bf..074b2919be2b5544b0a46e6cd32f6c57
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 0e0abc233f6425a6303672d87429bcdfaf04f842..c9afcd46f6a1b74b82ed68f1df6188369cf53a73 100644
index 5050f446e75f0ec17daf994ed74cbcd3155664c1..71cb264e399d098f9e40c71258f1412aa0dbafc5 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -673,7 +673,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -675,7 +675,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void kickPlayer(String message) {
@ -4038,7 +4038,7 @@ index 0e0abc233f6425a6303672d87429bcdfaf04f842..c9afcd46f6a1b74b82ed68f1df618836
this.getHandle().transferCookieConnection.kickPlayer(CraftChatMessage.fromStringOrEmpty(message, true), org.bukkit.event.player.PlayerKickEvent.Cause.PLUGIN); // Paper - kick event cause
}
@@ -691,7 +691,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -693,7 +693,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void kick(net.kyori.adventure.text.Component message, org.bukkit.event.player.PlayerKickEvent.Cause cause) {
@ -4047,7 +4047,7 @@ index 0e0abc233f6425a6303672d87429bcdfaf04f842..c9afcd46f6a1b74b82ed68f1df618836
final ServerGamePacketListenerImpl connection = this.getHandle().connection;
if (connection != null) {
connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message, cause);
@@ -1411,6 +1411,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -1413,6 +1413,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public boolean teleport(Location location, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) {
@ -4059,7 +4059,7 @@ index 0e0abc233f6425a6303672d87429bcdfaf04f842..c9afcd46f6a1b74b82ed68f1df618836
Set<io.papermc.paper.entity.TeleportFlag.Relative> relativeArguments;
Set<io.papermc.paper.entity.TeleportFlag> allFlags;
if (flags.length == 0) {
@@ -2075,7 +2080,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -2077,7 +2082,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
private void unregisterEntity(Entity other) {
// Paper end
ChunkMap tracker = ((ServerLevel) this.getHandle().level()).getChunkSource().chunkMap;
@ -4068,7 +4068,7 @@ index 0e0abc233f6425a6303672d87429bcdfaf04f842..c9afcd46f6a1b74b82ed68f1df618836
if (entry != null) {
entry.removePlayer(this.getHandle());
}
@@ -2172,7 +2177,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -2174,7 +2179,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
if (original != null) otherPlayer.setUUID(original); // Paper - uuid override
}
@ -4077,7 +4077,7 @@ index 0e0abc233f6425a6303672d87429bcdfaf04f842..c9afcd46f6a1b74b82ed68f1df618836
if (entry != null && !entry.seenBy.contains(this.getHandle().connection)) {
entry.updatePlayer(this.getHandle());
}
@@ -2321,9 +2326,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -2323,9 +2328,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
return this;
}
@ -4095,7 +4095,7 @@ index 0e0abc233f6425a6303672d87429bcdfaf04f842..c9afcd46f6a1b74b82ed68f1df618836
}
public void setHandle(final ServerPlayer entity) {
@@ -3352,7 +3364,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -3354,7 +3366,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
{
if ( CraftPlayer.this.getHealth() <= 0 && CraftPlayer.this.isOnline() )
{

View File

@ -0,0 +1,71 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 20 Mar 2025 11:01:42 -0700
Subject: [PATCH] fixup! Region Threading Base
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 6c2d9c9621f665412f1a8ccc41083fb0e3a07ed5..935ac76cec67ea661a392ff02396aa7aefd56268 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -3125,7 +3125,7 @@ public final class CraftServer implements Server {
@Override
public double[] getTPS() {
// Folia start - region threading
- ca.spottedleaf.concurrentutil.scheduler.SchedulerThreadPool.SchedulableTick task = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentTickingTask();
+ io.papermc.paper.threadedregions.ScheduledTaskThreadPool.SchedulableTick task = io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentTickingTask();
if (task == null) {
// might be on the shutdown thread, try retrieving the current region
if (io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegion() != null) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 71cb264e399d098f9e40c71258f1412aa0dbafc5..c53de765b624071cb4cd3fa69b5df4de5b95bf3b 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -229,6 +229,47 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
private boolean simplifyContainerDesyncCheck = GlobalConfiguration.get().unsupportedSettings.simplifyRemoteItemMatching;
private long lastSaveTime; // Paper - getLastPlayed replacement API
+ // Folia start - region threading
+ private final ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue<Runnable> packetQueue = new ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue<>();
+ // used only to notify tasks for packets
+ private volatile io.papermc.paper.threadedregions.RegionizedWorldData lastRegion;
+
+ public void stopAcceptingPackets() {
+ this.packetQueue.preventAdds();
+ }
+
+ public void updateRegion(final io.papermc.paper.threadedregions.RegionizedWorldData region) {
+ this.lastRegion = region;
+ if (region != null && this.hasPackets()) {
+ region.regionData.setHasPackets();
+ }
+ }
+
+ public boolean hasPackets() {
+ return !this.packetQueue.isEmpty();
+ }
+
+ public boolean executeOnePacket() {
+ final Runnable run = this.packetQueue.poll();
+ if (run != null) {
+ run.run();
+ return true;
+ }
+ return false;
+ }
+
+ public void addPacket(final Runnable runnable) {
+ if (!this.packetQueue.add(runnable)) {
+ return;
+ }
+
+ final io.papermc.paper.threadedregions.RegionizedWorldData region = this.lastRegion;
+ if (region != null) {
+ region.regionData.setHasPackets();
+ }
+ }
+ // Folia end - region threading
+
public CraftPlayer(CraftServer server, ServerPlayer entity) {
super(server, entity);

View File

@ -2,7 +2,7 @@ group=dev.folia
version=1.21.4-R0.1-SNAPSHOT
mcVersion=1.21.4
paperRef=1a7288aa05cfb0a168850a7cc879f55235fe5934
paperRef=bb1beda67bfd94632815acc8ac5d68f5a8e3e410
org.gradle.configuration-cache=true
org.gradle.caching=true