Skip to content
This repository has been archived by the owner on May 1, 2023. It is now read-only.

Commit

Permalink
feat: upstream + tracker fixes
Browse files Browse the repository at this point in the history
thank you kev626 from pufferfish core for outlining the tracker fix!!
  • Loading branch information
peaches94 committed Oct 19, 2022
1 parent 3efc156 commit b2aa817
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 54 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ org.gradle.vfs.watch=false
group=host.bloom.petal
version=1.19.2-R0.1-SNAPSHOT
mcVersion=1.19.2
purpurRef=0008a68c1be431a9253cfd23ac778ffbc4d78cc4
purpurRef=cf6b7c345980e35d47bfc1382c5aa34c21eebe61
26 changes: 13 additions & 13 deletions patches/server/0001-conf-brand-server-to-petal.patch
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Subject: [PATCH] conf: brand server to petal


diff --git a/build.gradle.kts b/build.gradle.kts
index 441a18132eb60e1af8b624ab7cf3de61669ced1f..27b3535f53c1de721b71e04c80688e1907230178 100644
index 2ee34f92e8a89b90448bbf710fdc0d5d6350e919..d7cd4c85a8775f979f62d5da7220a1be321743a6 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -9,7 +9,7 @@ plugins {
Expand All @@ -17,7 +17,7 @@ index 441a18132eb60e1af8b624ab7cf3de61669ced1f..27b3535f53c1de721b71e04c80688e19
// Pufferfish start
implementation("io.papermc.paper:paper-mojangapi:1.19.2-R0.1-SNAPSHOT") {
exclude("io.papermc.paper", "paper-api")
@@ -87,7 +87,7 @@ tasks.jar {
@@ -86,7 +86,7 @@ tasks.jar {
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",
"Implementation-Title" to "CraftBukkit",
Expand Down Expand Up @@ -84,10 +84,10 @@ index fba5dbdb7bcbb55400ef18342c9b54612972a718..3f9aa4292ff45c6b6af0ddfeecb645f8
switch (distance) {
case -1:
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index d7c77908ba7f0a0c00c06744d1ee0c1ad3ee0d7c..8527b1d2c559ce9c4608725dd455a000c75d0333 100644
index 13c9cddf7ac0af16676050e3bcdf22b7475a0387..abc5a4a67270db2b801d02fe870e73b448fac9a7 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -916,7 +916,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -926,7 +926,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
shutdownThread = Thread.currentThread();
org.spigotmc.WatchdogThread.doStop(); // Paper
if (!isSameThread()) {
Expand All @@ -96,7 +96,7 @@ index d7c77908ba7f0a0c00c06744d1ee0c1ad3ee0d7c..8527b1d2c559ce9c4608725dd455a000
while (this.getRunningThread().isAlive()) {
this.getRunningThread().stop();
try {
@@ -1702,7 +1702,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1683,7 +1683,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

@DontObfuscate
public String getServerModName() {
Expand All @@ -113,10 +113,10 @@ index d7c77908ba7f0a0c00c06744d1ee0c1ad3ee0d7c..8527b1d2c559ce9c4608725dd455a000

public SystemReport fillSystemReport(SystemReport details) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 3fffeff2f7e12c021ac4d1e6754583f58a03f12f..7176b75dc2a574240e679d0164ec77c610ecba51 100644
index f9508a26b2e764e752da3d2c9f43a9d7de19dd27..bad90335cfed68b2abdfd52003155270e284f5c0 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -248,7 +248,7 @@ import javax.annotation.Nullable; // Paper
@@ -249,7 +249,7 @@ import javax.annotation.Nullable; // Paper
import javax.annotation.Nonnull; // Paper

public final class CraftServer implements Server {
Expand All @@ -139,10 +139,10 @@ index fb87620c742ff7912f5e8ccd2a7930dd605576d9..8c0215954360adf6c51bd71994273e8b

if (stream != null) {
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
index 4a88fbee3566ba54b615745a2e4801691f494557..d89aecd421b83d539d29fd5e87c1bf9a992ab2dc 100644
index a810bfd3b8d6bd4d8f2ef8797e4281ae4fe8a67f..f8190c7d4c7b03ea05b1abbb139507b4f19c474e 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -155,14 +155,14 @@ public class WatchdogThread extends Thread
@@ -155,14 +155,14 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
if (isLongTimeout) {
// Paper end
log.log( Level.SEVERE, "------------------------------" );
Expand All @@ -160,7 +160,7 @@ index 4a88fbee3566ba54b615745a2e4801691f494557..d89aecd421b83d539d29fd5e87c1bf9a
//
if ( net.minecraft.world.level.Level.lastPhysicsProblem != null )
{
@@ -185,12 +185,12 @@ public class WatchdogThread extends Thread
@@ -185,12 +185,12 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
// Paper end
} else
{
Expand All @@ -172,10 +172,10 @@ index 4a88fbee3566ba54b615745a2e4801691f494557..d89aecd421b83d539d29fd5e87c1bf9a
log.log( Level.SEVERE, "------------------------------" );
- log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Purpur!):" ); // Paper // Purpur
+ log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to petal!):" ); // Paper // Purpur // petal
com.destroystokyo.paper.io.chunk.ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper
io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system
this.dumpTickingInfo(); // Paper - log detailed tick information
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( server.serverThread.getId(), Integer.MAX_VALUE ), log );
@@ -206,7 +206,7 @@ public class WatchdogThread extends Thread
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
@@ -206,7 +206,7 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
WatchdogThread.dumpThread( thread, log );
}
} else {
Expand Down
22 changes: 11 additions & 11 deletions patches/server/0002-feat-async-path-processing.patch
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ index f0248d839255763005ba333b0bfcf691407fb69b..f86adf5a8f5f2e720697956fdb0c7fd3

@Override
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
index d4bb3b8ab9a8ba01cf9d27cf1417cb820c713057..3175b31bd40ec563a996891f08dba5b8fbe88543 100644
index c06057cf9609e001f4512c247f355ded0ff2e8ce..de6628600a2ff61a3ec201d9d5ede6f0ca398f23 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
@@ -150,6 +150,9 @@ public abstract class PathNavigation {
Expand Down Expand Up @@ -819,15 +819,15 @@ index d4bb3b8ab9a8ba01cf9d27cf1417cb820c713057..3175b31bd40ec563a996891f08dba5b8
Vec3 vec3 = this.getTempMobPos();
this.maxDistanceToWaypoint = this.mob.getBbWidth() > 0.75F ? this.mob.getBbWidth() / 2.0F : 0.75F - this.mob.getBbWidth() / 2.0F;
Vec3i vec3i = this.path.getNextNodePos();
@@ -439,7 +454,7 @@ public abstract class PathNavigation {
// Paper start
public boolean isViableForPathRecalculationChecking() {
return !this.needsPathRecalculation() &&
- (this.path != null && !this.path.isDone() && this.path.getNodeCount() != 0);
+ (this.path != null && this.path.isProcessed() && !this.path.isDone() && this.path.getNodeCount() != 0);
}
// Paper end
}
@@ -419,7 +434,7 @@ public abstract class PathNavigation {
public boolean shouldRecomputePath(BlockPos pos) {
if (this.hasDelayedRecomputation) {
return false;
- } else if (this.path != null && !this.path.isDone() && this.path.getNodeCount() != 0) {
+ } else if (this.path != null && this.path.isProcessed() && !this.path.isDone() && this.path.getNodeCount() != 0) { // petal
Node node = this.path.getEndNode();
Vec3 vec3 = new Vec3(((double)node.x + this.mob.getX()) / 2.0D, ((double)node.y + this.mob.getY()) / 2.0D, ((double)node.z + this.mob.getZ()) / 2.0D);
return pos.closerToCenterThan(vec3, (double)(this.path.getNodeCount() - this.path.getNextNodeIndex()));
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
index 8db20db72cd51046213625fac46c35854c59ec5d..11b386697279333ffd5f3abc9e1dbc9c19711764 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
Expand Down Expand Up @@ -869,7 +869,7 @@ index 8db20db72cd51046213625fac46c35854c59ec5d..11b386697279333ffd5f3abc9e1dbc9c
}
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
index 6e33790792e8d0b727fce7dd3bf8a848ca5180a3..d29c9121dc3cb1780c7d25e18f220daf8c25c6e1 100644
index 3241815b0a5584a005457657660d2bb426b0fcdb..3dee1536034753b0d457b65a2944b398b4e748e1 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
@@ -1146,7 +1146,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
Expand Down
74 changes: 52 additions & 22 deletions patches/server/0003-feat-multithreaded-tracker.patch
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@ Date: Sat, 2 Jul 2022 00:35:56 -0500
Subject: [PATCH] feat: multithreaded tracker

Co-authored-by: Paul Sauve <[email protected]>
Co-authored-by: Kevin Raneri <[email protected]>

based off the airplane multithreaded tracker this patch properly handles
concurrent accesses everywhere, as well as being much simpler to maintain

some things are too unsafe to run off the main thread so we don't attempt to do
that. this multithreaded tracker remains accurate, non-breaking and fast

we also learned from pufferfish core that changes have to be sent ordered
now we do that in an optimized way

diff --git a/src/main/java/host/bloom/tracker/MultithreadedTracker.java b/src/main/java/host/bloom/tracker/MultithreadedTracker.java
new file mode 100644
index 0000000000000000000000000000000000000000..31a9a1dbb68cdbc5dc8a83542ddc7e0467ee8fd3
index 0000000000000000000000000000000000000000..d27b7224ed2bcc63386dc46c33bfb8b272d91f92
--- /dev/null
+++ b/src/main/java/host/bloom/tracker/MultithreadedTracker.java
@@ -0,0 +1,128 @@
@@ -0,0 +1,154 @@
+package host.bloom.tracker;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
Expand All @@ -34,6 +38,11 @@ index 0000000000000000000000000000000000000000..31a9a1dbb68cdbc5dc8a83542ddc7e04
+
+public class MultithreadedTracker {
+
+ private enum TrackerStage {
+ UPDATE_PLAYERS,
+ SEND_CHANGES
+ }
+
+ private static final int parallelism = Math.max(4, Runtime.getRuntime().availableProcessors());
+ private static final Executor trackerExecutor = Executors.newFixedThreadPool(parallelism, new ThreadFactoryBuilder()
+ .setNameFormat("petal-tracker-%d")
Expand All @@ -58,17 +67,18 @@ index 0000000000000000000000000000000000000000..31a9a1dbb68cdbc5dc8a83542ddc7e04
+ return;
+ }
+
+ // start with updating players
+ try {
+ this.taskIndex.set(iterator);
+ this.finishedTasks.set(0);
+
+ for (int i = 0; i < parallelism; i++) {
+ trackerExecutor.execute(this::run);
+ trackerExecutor.execute(this::runUpdatePlayers);
+ }
+
+ while (this.taskIndex.get() < this.entityTickingChunks.getListSize()) {
+ this.runMainThreadTasks();
+ this.handleTasks(5); // assist
+ this.handleChunkUpdates(5); // assist
+ }
+
+ while (this.finishedTasks.get() != parallelism) {
Expand All @@ -79,6 +89,25 @@ index 0000000000000000000000000000000000000000..31a9a1dbb68cdbc5dc8a83542ddc7e04
+ } finally {
+ this.entityTickingChunks.finishRawIterator();
+ }
+
+ // then send changes
+ iterator = this.entityTickingChunks.createRawIterator();
+
+ if (iterator == -1) {
+ return;
+ }
+
+ try {
+ do {
+ LevelChunk chunk = this.entityTickingChunks.rawGet(iterator);
+
+ if (chunk != null) {
+ this.updateChunkEntities(chunk, TrackerStage.SEND_CHANGES);
+ }
+ } while (++iterator < this.entityTickingChunks.getListSize());
+ } finally {
+ this.entityTickingChunks.finishRawIterator();
+ }
+ }
+
+ private void runMainThreadTasks() {
Expand All @@ -92,22 +121,22 @@ index 0000000000000000000000000000000000000000..31a9a1dbb68cdbc5dc8a83542ddc7e04
+ }
+ }
+
+ private void run() {
+ private void runUpdatePlayers() {
+ try {
+ while (handleTasks(10));
+ while (handleChunkUpdates(10));
+ } finally {
+ this.finishedTasks.incrementAndGet();
+ }
+ }
+
+ private boolean handleTasks(int tasks) {
+ private boolean handleChunkUpdates(int tasks) {
+ int index;
+ while ((index = this.taskIndex.getAndAdd(tasks)) < this.entityTickingChunks.getListSize()) {
+ for (int i = index; i < index + tasks && i < this.entityTickingChunks.getListSize(); i++) {
+ LevelChunk chunk = this.entityTickingChunks.rawGet(i);
+ if (chunk != null) {
+ try {
+ this.processChunk(chunk);
+ this.updateChunkEntities(chunk, TrackerStage.UPDATE_PLAYERS);
+ } catch (Throwable throwable) {
+ MinecraftServer.LOGGER.warn("Ticking tracker failed", throwable);
+ }
Expand All @@ -121,8 +150,8 @@ index 0000000000000000000000000000000000000000..31a9a1dbb68cdbc5dc8a83542ddc7e04
+ return false;
+ }
+
+ private void processChunk(LevelChunk chunk) {
+ final ChunkEntitySlices entitySlices = chunk.level.entityManager.entitySliceManager.getChunk(chunk.locX, chunk.locZ);
+ private void updateChunkEntities(LevelChunk chunk, TrackerStage trackerStage) {
+ final ChunkEntitySlices entitySlices = chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ);
+ if (entitySlices == null) {
+ return;
+ }
Expand All @@ -135,10 +164,11 @@ index 0000000000000000000000000000000000000000..31a9a1dbb68cdbc5dc8a83542ddc7e04
+ if (entity != null) {
+ ChunkMap.TrackedEntity entityTracker = chunkMap.entityMap.get(entity.getId());
+ if (entityTracker != null) {
+ entityTracker.updatePlayers(entityTracker.entity.getPlayersInTrackRange());
+
+ // run this on the main thread but queue it up here so we can run it while processing tracking at the same time
+ this.mainThreadTasks.offer(entityTracker.serverEntity::sendChanges);
+ if (trackerStage == TrackerStage.SEND_CHANGES) {
+ entityTracker.serverEntity.sendChanges();
+ } else if (trackerStage == TrackerStage.UPDATE_PLAYERS) {
+ entityTracker.updatePlayers(entityTracker.entity.getPlayersInTrackRange());
+ }
+ }
+ }
+ }
Expand All @@ -159,10 +189,10 @@ index 0fd814f1d65c111266a2b20f86561839a4cef755..169ac3ad1b1e8e3e1874ada2471e4782
protected final double maxFragFactor;

diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
index 47b5f75d9f27cf3ab947fd1f69cbd609fb9f2749..85882eeb86d7b74db0219aa65783946d8083885d 100644
index f597d65d56964297eeeed6c7e77703764178fee0..665c377e2d0d342f4dcc89c4cbdfcc9e4b96e95c 100644
--- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
@@ -27,7 +27,7 @@ public final class ChunkEntitySlices {
@@ -35,7 +35,7 @@ public final class ChunkEntitySlices {
protected final EntityCollectionBySection allEntities;
protected final EntityCollectionBySection hardCollidingEntities;
protected final Reference2ObjectOpenHashMap<Class<? extends Entity>, EntityCollectionBySection> entitiesByClass;
Expand All @@ -172,10 +202,10 @@ index 47b5f75d9f27cf3ab947fd1f69cbd609fb9f2749..85882eeb86d7b74db0219aa65783946d
public ChunkHolder.FullChunkStatus status;

diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 4fa383ff6ef3a9cc59b73ea4f52ae02e90140d2a..5293b7afb82b8250e07bc1d99cd837570e68c731 100644
index 3203b953709ca7cb9172f5912a922131ad7ec9eb..b39a01b903eafa15a2fc758bc74fa9b0f9b5fd5b 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -2077,8 +2077,27 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1237,8 +1237,27 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
entity.tracker = null; // Paper - We're no longer tracked
}

Expand Down Expand Up @@ -203,7 +233,7 @@ index 4fa383ff6ef3a9cc59b73ea4f52ae02e90140d2a..5293b7afb82b8250e07bc1d99cd83757
//this.level.timings.tracker1.startTiming(); // Purpur
try {
for (TrackedEntity tracker : this.entityMap.values()) {
@@ -2349,11 +2368,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1462,11 +1481,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider

public class TrackedEntity {

Expand All @@ -218,7 +248,7 @@ index 4fa383ff6ef3a9cc59b73ea4f52ae02e90140d2a..5293b7afb82b8250e07bc1d99cd83757

public TrackedEntity(Entity entity, int i, int j, boolean flag) {
this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit
@@ -2365,7 +2384,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1478,7 +1497,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper start - use distance map to optimise tracker
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> lastTrackerCandidates;

Expand All @@ -227,7 +257,7 @@ index 4fa383ff6ef3a9cc59b73ea4f52ae02e90140d2a..5293b7afb82b8250e07bc1d99cd83757
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> oldTrackerCandidates = this.lastTrackerCandidates;
this.lastTrackerCandidates = newTrackerCandidates;

@@ -2437,7 +2456,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1550,7 +1569,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}

public void removePlayer(ServerPlayer player) {
Expand All @@ -236,7 +266,7 @@ index 4fa383ff6ef3a9cc59b73ea4f52ae02e90140d2a..5293b7afb82b8250e07bc1d99cd83757
if (this.seenBy.remove(player.connection)) {
this.serverEntity.removePairing(player);
}
@@ -2445,7 +2464,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1558,7 +1577,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}

public void updatePlayer(ServerPlayer player) {
Expand Down
Loading

0 comments on commit b2aa817

Please sign in to comment.