Skip to content

Commit

Permalink
Update EntityScheduler optimization patch to match Paper PR
Browse files Browse the repository at this point in the history
  • Loading branch information
MrPowerGamerBR committed Dec 1, 2023
1 parent 909dd2c commit ad57a12
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ To avoid the hefty ArrayDeque's size() call, we check if we *really* need to exe
Most entities won't have any scheduled tasks, so this is a nice performance bonus. These optimizations, however, wouldn't work in a Folia environment, but because in SparklyPaper executeTick is always executed on the main thread, it ain't an issue for us (yay).

diff --git a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
index 62484ebf4550b05182f693a3180bbac5d5fd906d..4c7aa86bd115c0a6dd6fc8fe20be5c7c48215ca2 100644
index 62484ebf4550b05182f693a3180bbac5d5fd906d..67800e426445060a8343e27a7452b8d7ed27ac5f 100644
--- a/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
+++ b/src/main/java/io/papermc/paper/threadedregions/EntityScheduler.java
@@ -36,6 +36,7 @@ public final class EntityScheduler {
Expand All @@ -32,65 +32,78 @@ index 62484ebf4550b05182f693a3180bbac5d5fd906d..4c7aa86bd115c0a6dd6fc8fe20be5c7c
this.entity = Validate.notNull(entity);
}

@@ -66,6 +68,7 @@ public final class EntityScheduler {
@@ -61,14 +63,16 @@ public final class EntityScheduler {
* @throws IllegalStateException If the scheduler is already retired.
*/
public void retire() {
+ final Entity thisEntity = this.entity.getHandleRaw(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
synchronized (this.stateLock) {
if (this.tickCount == RETIRED_TICK_COUNT) {
throw new IllegalStateException("Already retired");
}
this.tickCount = RETIRED_TICK_COUNT;
+ this.server.entitiesWithScheduledTasks.remove(entity); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
+ this.server.entitiesWithScheduledTasks.remove(thisEntity); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
}

final Entity thisEntity = this.entity.getHandleRaw();
@@ -124,6 +127,7 @@ public final class EntityScheduler {
- final Entity thisEntity = this.entity.getHandleRaw();
+ // final Entity thisEntity = this.entity.getHandleRaw(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (moved up)

// correctly handle and order retiring while running executeTick
for (int i = 0, len = this.currentlyExecuting.size(); i < len; ++i) {
@@ -124,6 +128,7 @@ public final class EntityScheduler {
if (this.tickCount == RETIRED_TICK_COUNT) {
return false;
}
+ this.server.entitiesWithScheduledTasks.add(entity); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
+ this.server.entitiesWithScheduledTasks.add(this.entity.getHandleRaw()); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
this.oneTimeDelayed.computeIfAbsent(this.tickCount + Math.max(1L, delay), (final long keyInMap) -> {
return new ArrayList<>();
}).add(task);
@@ -143,6 +147,13 @@ public final class EntityScheduler {
@@ -143,6 +148,13 @@ public final class EntityScheduler {
TickThread.ensureTickThread(thisEntity, "May not tick entity scheduler asynchronously");
final List<ScheduledTask> toRun;
synchronized (this.stateLock) {
+ // SparklyPaper start - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
+ // Do we *really* have scheduled tasks tho?
+ if (this.currentlyExecuting.isEmpty() && this.oneTimeDelayed.isEmpty()) { // Check if we have any pending tasks and, if not, skip!
+ this.server.entitiesWithScheduledTasks.remove(entity); // We don't! Bye bye!!
+ this.server.entitiesWithScheduledTasks.remove(thisEntity); // We don't! Bye bye!!
+ return;
+ }
+ // SparklyPaper end
if (this.tickCount == RETIRED_TICK_COUNT) {
throw new IllegalStateException("Ticking retired scheduler");
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 25367df06a8a6e8b0b3a56652a5fb1c70a15632d..e01297d1269e55f4a4f6c43273d194972529645c 100644
index 25367df06a8a6e8b0b3a56652a5fb1c70a15632d..d83b2f3c03c2e22a3e7c97dc4e4b156d1b321738 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -308,6 +308,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper start - lag compensation
public static final long SERVER_INIT = System.nanoTime();
// Paper end - lag compensation
+ public final Set<org.bukkit.craftbukkit.entity.CraftEntity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
+ public final Set<Entity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)

public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
AtomicReference<S> atomicreference = new AtomicReference();
@@ -1471,6 +1472,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1471,6 +1472,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper
// Paper start - Folia scheduler API
((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) Bukkit.getGlobalRegionScheduler()).tick();
+ // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
+ for (final org.bukkit.craftbukkit.entity.CraftEntity craftEntity : entitiesWithScheduledTasks) {
+ Entity entity = craftEntity.getHandleRaw();
+ for (final Entity entity : entitiesWithScheduledTasks) {
+ if (entity.isRemoved()) {
+ continue;
+ }
+ craftEntity.taskScheduler.executeTick();
+
+ final org.bukkit.craftbukkit.entity.CraftEntity bukkit = entity.getBukkitEntityRaw();
+ if (bukkit != null) {
+ bukkit.taskScheduler.executeTick();
+ }
+ }
+ /*
getAllLevels().forEach(level -> {
for (final Entity entity : level.getEntityLookup().getAllCopy()) {
if (entity.isRemoved()) {
@@ -1482,6 +1492,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1482,6 +1495,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}
});
Expand Down
4 changes: 2 additions & 2 deletions patches/server/0012-Spooky-month-optimizations.patch
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ Caches when Bat's spooky season starts and ends, and when Skeleton and Zombies h
Avoids unnecessary date checks, even tho that this shouldn't really improve performance that much... unless you have a lot of bats/zombies/skeletons spawning.

diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index e01297d1269e55f4a4f6c43273d194972529645c..250f13e8cef10f6b416f35c668f31512f5679d71 100644
index d83b2f3c03c2e22a3e7c97dc4e4b156d1b321738..cebda87d198edc844f5629a5cd4c71cd6dd75caf 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -309,6 +309,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public static final long SERVER_INIT = System.nanoTime();
// Paper end - lag compensation
public final Set<org.bukkit.craftbukkit.entity.CraftEntity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
public final Set<Entity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
+ public net.sparklypower.sparklypaper.HalloweenManager halloweenManager = new net.sparklypower.sparklypaper.HalloweenManager(); // SparklyPaper - Spooky month optimizations

public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
Expand Down
4 changes: 2 additions & 2 deletions patches/server/0018-Track-how-much-MSPT-each-world-used.patch
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ index 8b5293b0c696ef21d0101493ffa41b60bf0bc86b..601198a33adb29316b0617d5390d1620
}

diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 250f13e8cef10f6b416f35c668f31512f5679d71..52b86e899f0c897fb4deca36936073ade3db8265 100644
index cebda87d198edc844f5629a5cd4c71cd6dd75caf..53284b2b0d0a2546e8c045a960a1db9b8d06e3f7 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1558,7 +1558,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1561,7 +1561,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

try {
worldserver.timings.doTick.startTiming(); // Spigot
Expand Down
6 changes: 3 additions & 3 deletions patches/server/0019-Parallel-world-ticking.patch
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ index 6f2adf2334e35e8a617a4ced0c1af2abf32bbd8d..a5ea9df0a021ed820c0c1ccb612caebd
}

diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 52b86e899f0c897fb4deca36936073ade3db8265..dfc975c45abbc016e2212eb37883a798cbb4a515 100644
index 53284b2b0d0a2546e8c045a960a1db9b8d06e3f7..a29af1d5005ce1a52693ce9acc6686e0a537fd7d 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -160,6 +160,7 @@ import net.minecraft.world.level.storage.PrimaryLevelData;
Expand All @@ -570,15 +570,15 @@ index 52b86e899f0c897fb4deca36936073ade3db8265..dfc975c45abbc016e2212eb37883a798
// CraftBukkit start
@@ -310,6 +311,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper end - lag compensation
public final Set<org.bukkit.craftbukkit.entity.CraftEntity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
public final Set<Entity> entitiesWithScheduledTasks = java.util.concurrent.ConcurrentHashMap.newKeySet(); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run (concurrent because plugins may schedule tasks async)
public net.sparklypower.sparklypaper.HalloweenManager halloweenManager = new net.sparklypower.sparklypaper.HalloweenManager(); // SparklyPaper - Spooky month optimizations
+ // SparklyPaper - parallel world ticking
+ public java.util.concurrent.Semaphore serverLevelTickingSemaphore = null;
+ // SparklyPaper end

public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
AtomicReference<S> atomicreference = new AtomicReference();
@@ -1536,63 +1540,124 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1539,63 +1543,124 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

this.isIteratingOverLevels = true; // Paper
Iterator iterator = this.getAllLevels().iterator(); // Paper - move down
Expand Down

0 comments on commit ad57a12

Please sign in to comment.