9
0
mirror of https://github.com/Dreeam-qwq/Gale.git synced 2025-12-27 10:39:12 +00:00

Notify ServerChunkCache of completed chunk worker tasks to trigger chunk manager mid tick

This commit is contained in:
Martijn Muijsers
2023-02-06 18:41:44 +01:00
parent 2c62764cce
commit c8675f646c
7 changed files with 189 additions and 106 deletions

View File

@@ -557,7 +557,7 @@ index 0c4c62674b4c7e8e3921c7eb3ef726759ac75075..40f20806cc06106b4aa8e708467dcea9
WorldLoader.InitConfig worldloader_c = Main.loadOrCreateConfig(dedicatedserversettings.getProperties(), convertable_conversionsession, flag, resourcepackrepository);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a135c63f23c 100644
index eb951c9fda85d9620d3038a3db22d578db45e878..fe2892e20dcb0b76d30b81bca7a13e29a1c45723 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -40,10 +40,8 @@ import java.util.Optional;
@@ -591,7 +591,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.village.VillageSiege;
@@ -161,7 +148,15 @@ import net.minecraft.world.level.storage.loot.PredicateManager;
@@ -161,7 +148,16 @@ import net.minecraft.world.level.storage.loot.PredicateManager;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import org.apache.commons.lang3.Validate;
@@ -600,6 +600,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
+import org.galemc.gale.executor.annotation.thread.OriginalServerThreadOnly;
+import org.galemc.gale.executor.queue.BaseTaskQueues;
+import org.galemc.gale.executor.queue.ScheduledServerThreadTaskQueues;
+import org.galemc.gale.executor.thread.BaseThread;
+import org.galemc.gale.executor.thread.OriginalServerThread;
+import org.galemc.gale.executor.thread.SignalReason;
+import org.galemc.gale.executor.thread.pool.BaseThreadActivation;
@@ -607,7 +608,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
import org.slf4j.Logger;
// CraftBukkit start
@@ -181,23 +176,26 @@ import net.minecraft.world.level.levelgen.PatrolSpawner;
@@ -181,23 +177,26 @@ import net.minecraft.world.level.levelgen.PatrolSpawner;
import net.minecraft.world.level.levelgen.PhantomSpawner;
import net.minecraft.world.level.levelgen.WorldDimensions;
import net.minecraft.world.level.levelgen.presets.WorldPresets;
@@ -642,7 +643,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
public static final String VANILLA_BRAND = "vanilla";
private static final float AVERAGE_TICK_TIME_SMOOTHING = 0.8F;
private static final int TICK_STATS_SPAN = 100;
@@ -226,6 +224,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -226,6 +225,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private int port;
private final LayeredRegistryAccess<RegistryLayer> registries;
private Map<ResourceKey<Level>, ServerLevel> levels;
@@ -653,7 +654,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
private PlayerList playerList;
private volatile boolean running;
private volatile boolean isRestarting = false; // Paper - flag to signify we're attempting to restart
@@ -255,10 +257,114 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -255,10 +258,114 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private long lastOverloadWarning;
protected final Services services;
private long lastServerStatus;
@@ -772,7 +773,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
private final PackRepository packRepository;
private final ServerScoreboard scoreboard;
@Nullable
@@ -287,7 +393,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -287,7 +394,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
public int autosavePeriod;
public Commands vanillaCommandDispatcher;
@@ -781,7 +782,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
// CraftBukkit end
// Spigot start
public static final int TPS = 20;
@@ -303,9 +409,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -303,9 +410,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public volatile boolean abnormalExit = false; // Paper
public boolean isIteratingOverLevels = false; // Paper
@@ -793,7 +794,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
((MinecraftServer) atomicreference.get()).runServer();
}, "Server thread");
@@ -324,16 +430,19 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -324,16 +431,19 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
return s0;
}
@@ -816,7 +817,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
this.scoreboard = new ServerScoreboard(this);
this.customBossEvents = new CustomBossEvents();
this.frameTimer = new FrameTimer();
@@ -359,7 +468,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -359,7 +469,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
HolderGetter<Block> holdergetter = this.registries.compositeAccess().registryOrThrow(Registries.BLOCK).asLookup().filterFeatures(this.worldData.enabledFeatures());
this.structureTemplateManager = new StructureTemplateManager(worldstem.resourceManager(), convertable_conversionsession, datafixer, holdergetter);
@@ -828,7 +829,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
this.executor = Util.backgroundExecutor();
}
// CraftBukkit start
@@ -599,7 +711,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -599,7 +712,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}
this.forceDifficulty();
@@ -837,7 +838,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
this.prepareLevels(worldserver.getChunkSource().chunkMap.progressListener, worldserver);
//worldserver.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API // Paper - rewrite chunk system, not required to "tick" anything
this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(worldserver.getWorld()));
@@ -758,7 +870,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -758,7 +871,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
//ChunkProviderServer chunkproviderserver = worldserver.getChunkProvider(); // Paper - move up
chunkproviderserver.getLightEngine().setTaskPerBatch(500);
@@ -846,7 +847,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
// Paper start - configurable spawn reason
int radiusBlocks = worldserver.paperConfig().spawn.keepSpawnLoadedRange * 16;
int radiusChunks = radiusBlocks / 16 + ((radiusBlocks & 15) != 0 ? 1 : 0);
@@ -802,6 +914,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -802,6 +915,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
worldserver.setSpawnSettings(worldserver.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && ((DedicatedServer) this).settings.getProperties().spawnMonsters, this.isSpawningAnimals()); // Paper - per level difficulty (from setDifficulty(ServerLevel, Difficulty, boolean))
this.forceTicks = false;
@@ -858,7 +859,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
// CraftBukkit end
}
@@ -828,8 +945,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -828,8 +946,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper end - rewrite chunk system - add close param
boolean flag3 = false;
@@ -873,7 +874,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
if (!suppressLogs) {
MinecraftServer.LOGGER.info("Saving chunks for level '{}'/{}", worldserver, worldserver.dimension().location());
@@ -853,14 +974,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -853,14 +975,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
*/
// CraftBukkit end
if (flush) {
@@ -888,7 +889,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
MinecraftServer.LOGGER.info("ThreadedAnvilChunkStorage: All dimensions are saved");
}
@@ -887,7 +1000,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -887,7 +1001,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
// CraftBukkit start
@@ -897,7 +898,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
public volatile boolean hasFullyShutdown = false; // Paper
private boolean hasLoggedStop = false; // Paper
private final Object stopLock = new Object();
@@ -916,8 +1029,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -916,8 +1030,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
*/
MinecraftServer.LOGGER.info("Stopping main thread (Ignore any thread death message you see! - DO NOT REPORT THREAD DEATH TO PAPER - If you think this is a Gale bug, please report it at https://github.com/GaleMC/Gale/issues )");
// Gale end - branding changes
@@ -910,7 +911,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
try {
Thread.sleep(1);
} catch (InterruptedException e) {}
@@ -948,12 +1063,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -948,12 +1064,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
MinecraftServer.LOGGER.info("Saving worlds");
@@ -924,7 +925,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
if (worldserver != null) {
worldserver.noSave = false;
}
@@ -1017,7 +1127,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1017,7 +1128,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.running = false;
if (waitForShutdown) {
try {
@@ -933,7 +934,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
} catch (InterruptedException interruptedexception) {
MinecraftServer.LOGGER.error("Error while shutting down", interruptedexception);
}
@@ -1091,6 +1201,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1091,6 +1202,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public static long lastTickOversleepTime;
// Gale end - YAPFA - last tick time
@@ -941,7 +942,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
protected void runServer() {
try {
long serverStartTime = Util.getNanos(); // Paper
@@ -1098,7 +1209,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1098,7 +1210,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
throw new IllegalStateException("Failed to initialize server");
}
@@ -950,7 +951,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
this.status.setDescription(Component.literal(this.motd));
this.status.setVersion(new ServerStatus.Version(SharedConstants.getCurrentVersion().getName(), SharedConstants.getCurrentVersion().getProtocolVersion()));
this.status.setEnforcesSecureChat(this.enforceSecureProfile());
@@ -1135,7 +1246,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1135,7 +1247,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
if (this.server.getWarnOnOverload()) // CraftBukkit
MinecraftServer.LOGGER.warn("Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind", i, j);
@@ -959,7 +960,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
this.lastOverloadWarning = this.nextTickTime;
}
@@ -1159,12 +1270,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1159,12 +1271,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
//MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit // Paper - don't overwrite current tick time
lastTick = curTime;
@@ -974,7 +975,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
this.waitUntilNextTick();
this.isReady = true;
JvmProfiler.INSTANCE.onServerTick(this.averageTickTime);
@@ -1245,7 +1355,46 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1245,7 +1356,46 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
return crashreport;
}
@@ -1022,7 +1023,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
// Paper start
if (this.forceTicks) {
return true;
@@ -1253,13 +1402,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1253,13 +1403,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper end
// CraftBukkit start
if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken
@@ -1039,7 +1040,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
}
private boolean canSleepForTickNoOversleep() {
@@ -1268,7 +1417,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1268,7 +1418,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper end
private void executeModerately() {
@@ -1048,7 +1049,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
java.util.concurrent.locks.LockSupport.parkNanos("executing tasks", 1000L);
}
// CraftBukkit end
@@ -1276,61 +1425,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1276,61 +1426,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
protected void waitUntilNextTick() {
//this.executeAll(); // Paper - move this into the tick method for timings
long tickOversleepStart = System.nanoTime(); // Gale - YAPFA - last tick time
@@ -1118,7 +1119,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
private void updateStatusIcon(ServerStatus metadata) {
Optional<File> optional = Optional.of(this.getFile("server-icon.png")).filter(File::isFile);
@@ -1378,14 +1486,19 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1378,14 +1487,19 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper start - move oversleep into full server tick
isOversleep = true;MinecraftTimings.serverOversleep.startTiming();
@@ -1138,7 +1139,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
this.tickChildren(shouldKeepTicking);
if (i - this.lastServerStatus >= 5000000000L) {
this.lastServerStatus = i;
@@ -1420,7 +1533,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1420,7 +1534,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
if (playerSaveInterval > 0) {
this.playerList.saveAll(playerSaveInterval);
}
@@ -1147,7 +1148,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
if (level.paperConfig().chunks.autoSaveInterval.value() > 0) {
level.saveIncrementally(fullSave);
}
@@ -1432,7 +1545,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1432,7 +1546,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
io.papermc.paper.util.CachedLists.reset(); // Paper
// Paper start - move executeAll() into full server tick timing
try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) {
@@ -1156,7 +1157,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
}
// Paper end
// Paper start
@@ -1476,7 +1589,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1476,7 +1590,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot // Paper
// Send time updates to everyone, it will get the right time from the world the player is in.
// Paper start - optimize time updates
@@ -1165,7 +1166,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
final boolean doDaylight = world.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT);
final long dayTime = world.getDayTime();
long worldTime = world.getGameTime();
@@ -1496,9 +1609,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1496,9 +1610,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot // Paper
this.isIteratingOverLevels = true; // Paper
@@ -1176,7 +1177,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
@@ -1569,7 +1680,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1569,7 +1681,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
public boolean isShutdown() {
@@ -1185,7 +1186,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
}
public File getFile(String path) {
@@ -1577,7 +1688,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1577,7 +1689,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
public final ServerLevel overworld() {
@@ -1199,7 +1200,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
}
@Nullable
@@ -1591,6 +1707,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1591,6 +1708,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
Map<ResourceKey<Level>, ServerLevel> newLevels = Maps.newLinkedHashMap(oldLevels);
newLevels.put(level.dimension(), level);
this.levels = Collections.unmodifiableMap(newLevels);
@@ -1213,7 +1214,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
}
public void removeLevel(ServerLevel level) {
@@ -1598,6 +1721,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1598,6 +1722,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
Map<ResourceKey<Level>, ServerLevel> newLevels = Maps.newLinkedHashMap(oldLevels);
newLevels.remove(level.dimension());
this.levels = Collections.unmodifiableMap(newLevels);
@@ -1228,7 +1229,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
}
// CraftBukkit end
@@ -1605,8 +1736,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1605,8 +1737,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
return this.levels.keySet();
}
@@ -1244,7 +1245,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
}
public String getServerVersion() {
@@ -1726,10 +1863,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1726,10 +1864,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
private void updateMobSpawningFlags() {
@@ -1256,7 +1257,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
worldserver.setSpawnSettings(worldserver.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && ((DedicatedServer) this).settings.getProperties().spawnMonsters, this.isSpawningAnimals()); // Paper - per level difficulty (from setDifficulty(ServerLevel, Difficulty, boolean))
}
@@ -1928,25 +2062,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1928,25 +2063,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
return 29999984;
}
@@ -1282,7 +1283,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
public int getCompressionThreshold() {
return 256;
}
@@ -2013,7 +2128,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2013,7 +2129,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
net.minecraft.world.item.alchemy.PotionBrewing.reload(); // Paper
new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper
// Paper start
@@ -1291,7 +1292,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
return;
}
// this.getPlayerList().saveAll(); // Paper - we don't need to save everything, just advancements
@@ -2246,7 +2361,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2246,7 +2362,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
BufferedWriter bufferedwriter = Files.newBufferedWriter(path);
try {
@@ -1300,7 +1301,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
bufferedwriter.write(String.format(Locale.ROOT, "average_tick_time: %f\n", this.getAverageTickTime()));
bufferedwriter.write(String.format(Locale.ROOT, "tick_times: %s\n", Arrays.toString(this.tickTimes)));
bufferedwriter.write(String.format(Locale.ROOT, "queue: %s\n", Util.backgroundExecutor()));
@@ -2432,7 +2547,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2432,7 +2548,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
// CraftBukkit start
@@ -1308,7 +1309,7 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
public boolean isSameThread() {
return io.papermc.paper.util.TickThread.isTickThread(); // Paper - rewrite chunk system
}
@@ -2570,7 +2684,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2570,7 +2685,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// give all worlds a fair chance at by targetting them all.
// if we execute too many tasks, that's fine - we have logic to correctly handle overuse of allocated time.
boolean executed = false;
@@ -1317,6 +1318,19 @@ index eb951c9fda85d9620d3038a3db22d578db45e878..ac12cabaf15bc3520ff74d09faa48a13
long currTime = System.nanoTime();
if (currTime - world.lastMidTickExecuteFailure <= TASK_EXECUTION_FAILURE_BACKOFF) {
continue;
@@ -2587,6 +2702,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
public final void executeMidTickTasks() {
+ // Gale start - base thread pool
+ // Don't run mid tick tasks while we are yielding
+ if (BaseThread.currentBaseThread().yieldDepth > 0) {
+ return;
+ }
+ // Gale end - base thread pool
org.spigotmc.AsyncCatcher.catchOp("mid tick chunk task execution");
long startTime = System.nanoTime();
if ((startTime - lastMidTickExecute) <= CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME || (startTime - lastMidTickExecuteFailure) <= TASK_EXECUTION_FAILURE_BACKOFF) {
diff --git a/src/main/java/net/minecraft/server/commands/TimeCommand.java b/src/main/java/net/minecraft/server/commands/TimeCommand.java
index f0a7a8df3caa2ea765bb0a87cfede71d0995d276..16f3475b059d2b6b85d2b342e84ab32de8e86ac0 100644
--- a/src/main/java/net/minecraft/server/commands/TimeCommand.java
@@ -2342,14 +2356,16 @@ index 0000000000000000000000000000000000000000..84aa4f8e3f823cedc8cf958663fa2168
+}
diff --git a/src/main/java/org/galemc/gale/executor/TaskSpan.java b/src/main/java/org/galemc/gale/executor/TaskSpan.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d5bb1ba545200f954c886a2afb9d8ee2a3cc4d1
index 0000000000000000000000000000000000000000..99dcb582bf6557c54d9e1477434710ba92b2d87a
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/TaskSpan.java
@@ -0,0 +1,62 @@
@@ -0,0 +1,70 @@
+// Gale - base thread pool
+
+package org.galemc.gale.executor;
+
+import java.util.Arrays;
+
+/**
+ * An enum for the behaviour of a task, in terms of its potential to yield
+ * and its expected time cost to finish.
@@ -2407,6 +2423,12 @@ index 0000000000000000000000000000000000000000..1d5bb1ba545200f954c886a2afb9d8ee
+ */
+ public static final int length = VALUES.length;
+
+ /**
+ * Equal to {@link #VALUES} for which {@link #isNotYielding} is true.
+ */
+ public static final TaskSpan[] NON_YIELDING_VALUES = Arrays.stream(VALUES).filter(span -> span.isNotYielding).toList().toArray(new TaskSpan[length - 1]);
+
+
+}
diff --git a/src/main/java/org/galemc/gale/executor/annotation/PotentiallyBlocking.java b/src/main/java/org/galemc/gale/executor/annotation/PotentiallyBlocking.java
index a4dc0ebe48fdd352387f06be42ff46fc11ee5822..d324c303245bcbedaaaab573803d73caff941901 100644
@@ -3035,10 +3057,10 @@ index 0000000000000000000000000000000000000000..552e82a33c59261b06911b479400a7b1
+}
diff --git a/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java b/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java
new file mode 100644
index 0000000000000000000000000000000000000000..2eb121798b2feb2a5ce5ebb60316660dbff87de3
index 0000000000000000000000000000000000000000..657c3663ed54043e7e4e6660d34903ef746fd8e7
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java
@@ -0,0 +1,130 @@
@@ -0,0 +1,133 @@
+// Gale - base thread pool
+
+package org.galemc.gale.executor.queue;
@@ -3122,6 +3144,9 @@ index 0000000000000000000000000000000000000000..2eb121798b2feb2a5ce5ebb60316660d
+ if (MinecraftServer.isInSpareTimeAndHaveNoMoreTimeAndNotAlreadyBlocking || !MinecraftServer.isConstructed) {
+ return null;
+ }
+ if (this.span.isYielding && !currentThread.canStartYieldingTasks) {
+ return null;
+ }
+ ServerLevel[] levels = MinecraftServer.SERVER.getAllLevelsArray();
+ int startIndex = this.levelIterationIndex = Math.min(this.levelIterationIndex, levels.length - 1);
+ // Paper - force execution of all worlds, do not just bias the first
@@ -3204,10 +3229,10 @@ index 0000000000000000000000000000000000000000..690979cb9b7ec3dedbd7d0c45d0c183a
+}
diff --git a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4a0b3085cb22f25246010c43919129283a3b872
index 0000000000000000000000000000000000000000..7e24854f1e727e5e40108c68933466d0845bdca1
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
@@ -0,0 +1,125 @@
@@ -0,0 +1,127 @@
+// Gale - base thread pool
+
+package org.galemc.gale.executor.queue;
@@ -3218,6 +3243,7 @@ index 0000000000000000000000000000000000000000..e4a0b3085cb22f25246010c439191292
+import net.minecraft.world.entity.Entity;
+import org.galemc.gale.executor.TaskSpan;
+import org.galemc.gale.executor.thread.AssistThread;
+import org.galemc.gale.executor.thread.BaseThread;
+import org.galemc.gale.executor.thread.ServerThread;
+
+import java.util.Arrays;
@@ -3257,12 +3283,13 @@ index 0000000000000000000000000000000000000000..e4a0b3085cb22f25246010c439191292
+ * subject (like an entity or chunk) with tasks that will be run on whichever ticking thread is the
+ * ticking thread for that subject at the time of polling.
+ * <br>
+ * Note that a {@link ServerThread} can only yield to {@link TaskSpan#TINY} tasks
+ * Note that a {@link ServerThread} can only yield to {@link TaskSpan#TINY} tasks in other tiers
+ * (since there are no higher tiers, and threads can only yield to lower tiers when
+ * the task yielded to is{@link TaskSpan#TINY}.
+ * the task yielded to is{@link TaskSpan#TINY}, or other non-yielding tasks in its own tier (since it
+ * has a {@link BaseThread#maximumYieldDepth} of 1).
+ * Yielding to other tasks in this same tier is somewhat risky, since this means that the tasks that were
+ * yielded to must assume that although they are running on the server thread, they may be running at
+ * some unknown point in execution of the main thread. Therefore, scheduling any {@link TaskSpan#TINY} tasks to
+ * some unknown point in execution of the main thread. Therefore, scheduling any non-yielding tasks to
+ * a queue in this tier must be done with the utmost care that the task cannot disrupt, or be disrupted by,
+ * the surrounding code that yields to it.
+ */
@@ -5596,10 +5623,10 @@ index 0000000000000000000000000000000000000000..77fe10e51b00115da520cfc211bf84ba
+}
diff --git a/src/main/java/org/galemc/gale/executor/thread/pool/BaseThreadActivation.java b/src/main/java/org/galemc/gale/executor/thread/pool/BaseThreadActivation.java
new file mode 100644
index 0000000000000000000000000000000000000000..a22b63a15fcc737494454c0d91c35eef5bb21d9e
index 0000000000000000000000000000000000000000..5554f23c4cca4e9f0be036e11c9e2c69ad6293ce
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/thread/pool/BaseThreadActivation.java
@@ -0,0 +1,552 @@
@@ -0,0 +1,593 @@
+// Gale - base thread pool
+
+package org.galemc.gale.executor.thread.pool;
@@ -5611,6 +5638,7 @@ index 0000000000000000000000000000000000000000..a22b63a15fcc737494454c0d91c35eef
+import org.galemc.gale.executor.lock.YieldingLock;
+import org.galemc.gale.executor.queue.BaseTaskQueueTier;
+import org.galemc.gale.executor.thread.BaseThread;
+import org.galemc.gale.executor.thread.ServerThread;
+import org.galemc.gale.executor.thread.SignalReason;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
@@ -5851,6 +5879,54 @@ index 0000000000000000000000000000000000000000..a22b63a15fcc737494454c0d91c35eef
+ }
+
+ /**
+ * Determines whether it could be useful to activate the given thread.
+ * This does not into account whether tasks {@linkplain #thereMayBeTasks may exist} at all,
+ * except for the checking on non-yielding {@link BaseTaskQueueTier#SERVER} tasks for the purpose explained below.
+ * <br>
+ * We only activate threads that can start yielding tasks
+ * (it seems wasteful to take the effort to activate threads that can not),
+ * or threads that are waiting for a lock that is not currently locked.
+ * <br>
+ * Note that for the server thread, if it cannot start yielding tasks,
+ * there is never an alternative thread that can, so we also allow it,
+ * as a special case, to be activated purely based on the existence of non-yielding tasks.
+ * <br>
+ * This method must only be called from {@link #update}.
+ *
+ * @param thread The thread to consider.
+ * @param lockWaitingFor The pre-computed value of {@link BaseThread#lockWaitingFor}.
+ * @param isServerThread Whether the given thread is a {@link ServerThread}.
+ * @return Whether it could be useful to activate the given thread.
+ */
+ private static boolean couldBeUsefullyActivatedForTasksOrLock(BaseThread thread, @Nullable YieldingLock lockWaitingFor, boolean isServerThread) {
+ if (!thread.isWaitingAndNeedsSignal()) {
+ // There is no point in activating the thread because it is not waiting
+ return false;
+ }
+ if (lockWaitingFor != null && !lockWaitingFor.isLocked()) {
+ // Activating the thread would be useful because there is a lock that can be acquired
+ return true;
+ }
+ if (thread.canStartYieldingTasks) {
+ // Activating the thread would be useful because it can start yielding tasks
+ return true;
+ }
+ if (isServerThread) {
+ // The server thread can be activated whenever there are any non-yielding tasks
+ for (TaskSpan span : TaskSpan.NON_YIELDING_VALUES) {
+ if (thereMayBeTasks[BaseTaskQueueTier.SERVER.ordinal][span.ordinal].get() > 0) {
+ return true;
+ }
+ }
+ }
+ /*
+ There is no point in activating this thread (for anything that the thread could do,
+ it would be better to activate a different or newly instantiated thread).
+ */
+ return false;
+ }
+
+ /**
+ * Activates threads as necessary, and computes whether threads must de-activate themselves when they can.
+ * <br>
+ * This method is called from {@link #callForUpdate()} if necessary.
@@ -6063,17 +6139,9 @@ index 0000000000000000000000000000000000000000..a22b63a15fcc737494454c0d91c35eef
+ for (int threadI = tryThreadsStart; threadI < tryThreadsEnd; threadI++) {
+ BaseThread thread = threads[threadI];
+ if (thread != null) {
+ /*
+ Note that we only activate threads that can start yielding tasks
+ (it seems wasteful to take the effort to activate threads that can not).
+ or threads that are waiting for a lock that is not currently locked.
+ Note that for the server thread, if it cannot start yielding tasks,
+ there is never an alternative thread that can, so we also allow it,
+ as a special case.
+ */
+ @Nullable YieldingLock lockWaitingFor = thread.lockWaitingFor;
+ if (thread.isWaitingAndNeedsSignal() && (tierI == 0 || (lockWaitingFor != null && !lockWaitingFor.isLocked()) || thread.canStartYieldingTasks)) {
+ /*
+ if (couldBeUsefullyActivatedForTasksOrLock(thread, lockWaitingFor, tierI == 0)) {
+ /*
+ Tasks of a certain tier may yield to tasks of the same or a higher
+ tier, and they may also yield to tiny tasks of a lower tier.
+ We do not want to wake up a thread just for tiny tasks
@@ -6122,7 +6190,7 @@ index 0000000000000000000000000000000000000000..a22b63a15fcc737494454c0d91c35eef
+ // Check if the thread still seems valid and attempt to activate it
+ BaseThread thread = threads[threadIToUpdate];
+ @Nullable YieldingLock lockWaitingFor = thread.lockWaitingFor;
+ if (thread.isWaitingAndNeedsSignal() && (tierI == 0 || (lockWaitingFor != null && !lockWaitingFor.isLocked()) || thread.canStartYieldingTasks)) {
+ if (couldBeUsefullyActivatedForTasksOrLock(thread, lockWaitingFor, tierI == 0)) {
+ // Wake up the thread
+ if (thread.signal(thereAreTasks ? SignalReason.TASK : SignalReason.YIELDING_LOCK)) {
+ // Do another update

View File

@@ -27,10 +27,10 @@ index 4b8da38db72d7ebc2d498ec3d711d3b30911096c..80f9e70d5c4330e079feccc9a4b1b595
1, 1, 0L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index ac12cabaf15bc3520ff74d09faa48a135c63f23c..0019e5eefc4b638526a75dd3706a54033dd9b811 100644
index fe2892e20dcb0b76d30b81bca7a13e29a1c45723..313d45dae086ac7c1bd0dd71540020c18a9e5d86 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1080,9 +1080,6 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
@@ -1081,9 +1081,6 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
MinecraftServer.LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), ioexception1);
}
// Spigot start
@@ -40,7 +40,7 @@ index ac12cabaf15bc3520ff74d09faa48a135c63f23c..0019e5eefc4b638526a75dd3706a5403
if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
MinecraftServer.LOGGER.info("Saving usercache.json");
this.getProfileCache().save(false); // Paper
@@ -1092,6 +1089,12 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
@@ -1093,6 +1090,12 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
LOGGER.info("Flushing Chunk IO");
io.papermc.paper.chunk.system.io.RegionFileIOThread.close(true); // Paper // Paper - rewrite chunk system
LOGGER.info("Closing Thread Pool");
@@ -54,10 +54,10 @@ index ac12cabaf15bc3520ff74d09faa48a135c63f23c..0019e5eefc4b638526a75dd3706a5403
LOGGER.info("Closing Server");
try {
diff --git a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
index e4a0b3085cb22f25246010c43919129283a3b872..52c413990fd8aaca72e371c3bc8f1f145a172abc 100644
index 7e24854f1e727e5e40108c68933466d0845bdca1..fb185e7f6344f21ed861e56c137ce470e891e766 100644
--- a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
+++ b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
@@ -73,7 +73,9 @@ public enum BaseTaskQueueTier {
@@ -75,7 +75,9 @@ public enum BaseTaskQueueTier {
* asynchronously with respect to the {@link ServerThread} and the ticking of the server.
* Execution of
*/

View File

@@ -77,10 +77,10 @@ index 80f9e70d5c4330e079feccc9a4b1b5957c79ef45..e4955e8d04735b74007aae0bf3230281
public static final long INVALID_CHUNK_KEY = getCoordinateKey(Integer.MAX_VALUE, Integer.MAX_VALUE);
diff --git a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
index 52c413990fd8aaca72e371c3bc8f1f145a172abc..85f467b3cedef57b6b51f04eb34316d43e192d87 100644
index fb185e7f6344f21ed861e56c137ce470e891e766..f4adcdcad96b2748c60aecb8f5c25370ee6e8f5b 100644
--- a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
+++ b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
@@ -74,6 +74,8 @@ public enum BaseTaskQueueTier {
@@ -76,6 +76,8 @@ public enum BaseTaskQueueTier {
* Execution of
*/
ASYNC(new AbstractTaskQueue[]{

View File

@@ -7,7 +7,7 @@ License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html)
Gale - https://galemc.org
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 83a57b9bc59063ed8299f98bc33e14b57f2ea0de..2a0cbe5146eb444a8cb7ab4960904143af4456a7 100644
index 83a57b9bc59063ed8299f98bc33e14b57f2ea0de..f1aaf1cae3335f7c7340104cfd6dbc3dd62f6ab3 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -11,7 +11,6 @@ import java.util.Collections;
@@ -44,16 +44,26 @@ index 83a57b9bc59063ed8299f98bc33e14b57f2ea0de..2a0cbe5146eb444a8cb7ab4960904143
} else {
completablefuture = CompletableFuture.supplyAsync(() -> {
return this.getChunkFutureMainThread(chunkX, chunkZ, leastStatus, create);
@@ -973,6 +973,8 @@ public class ServerChunkCache extends ChunkSource {
@@ -973,6 +973,18 @@ public class ServerChunkCache extends ChunkSource {
public final class MainThreadExecutor extends BlockableEventLoop<Runnable> {
+ private @Nullable YieldingLock yieldingLockToNotifyOnNewTasks = null; // Gale - base thread pool
+ // Gale start - base thread pool
+ private static volatile boolean chunkWorkerTasksWereCompletedSinceLastDoChunkCacheTasksInYield;
+ public static @Nullable YieldingLock yieldingLockToNotifyForNewChunkCacheTasks;
+
+ public static void notifyOfCompletedChunkWorkerTasks() {
+ if (yieldingLockToNotifyForNewChunkCacheTasks != null) {
+ chunkWorkerTasksWereCompletedSinceLastDoChunkCacheTasksInYield = true;
+ yieldingLockToNotifyForNewChunkCacheTasks.unlock();
+ }
+ }
+ // Gale end - base thread pool
+
MainThreadExecutor(Level world) {
super("Chunk source main thread executor for " + world.dimension().location());
}
@@ -1002,6 +1004,39 @@ public class ServerChunkCache extends ChunkSource {
@@ -1002,6 +1014,40 @@ public class ServerChunkCache extends ChunkSource {
super.doRunTask(task);
}
@@ -63,8 +73,8 @@ index 83a57b9bc59063ed8299f98bc33e14b57f2ea0de..2a0cbe5146eb444a8cb7ab4960904143
+ super.tell(runnable);
+ MinecraftServer.nextTimeAssumeWeMayHaveDelayedTasks = true;
+ BaseTaskQueues.allLevelsScheduledChunkCache.newTaskWasAdded();
+ if (this.yieldingLockToNotifyOnNewTasks != null) {
+ this.yieldingLockToNotifyOnNewTasks.unlock();
+ if (yieldingLockToNotifyForNewChunkCacheTasks != null) {
+ yieldingLockToNotifyForNewChunkCacheTasks.unlock();
+ }
+ }
+
@@ -79,10 +89,11 @@ index 83a57b9bc59063ed8299f98bc33e14b57f2ea0de..2a0cbe5146eb444a8cb7ab4960904143
+ var currentThread = AbstractYieldingThread.currentYieldingThread();
+ while (!future.isDone()) {
+ if (!this.pollTask()) {
+ currentThread.yieldUntilFuture(this::hasPendingTasks, future, autoCompletingLock -> this.yieldingLockToNotifyOnNewTasks = autoCompletingLock);
+ currentThread.yieldUntilFuture(() -> this.hasPendingTasks() || chunkWorkerTasksWereCompletedSinceLastDoChunkCacheTasksInYield, future, autoCompletingLock -> yieldingLockToNotifyForNewChunkCacheTasks = autoCompletingLock);
+ chunkWorkerTasksWereCompletedSinceLastDoChunkCacheTasksInYield = false;
+ }
+ }
+ this.yieldingLockToNotifyOnNewTasks = null;
+ yieldingLockToNotifyForNewChunkCacheTasks = null;
+ } finally {
+ --this.blockingCount;
+ }
@@ -121,7 +132,7 @@ index 949feba1264bcafb8dc2dcecd0a566fea80a2ba0..9eae3862abb5f1d7755a8e777fd4bf9a
}
diff --git a/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledChunkCacheTaskQueue.java b/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledChunkCacheTaskQueue.java
new file mode 100644
index 0000000000000000000000000000000000000000..60a3b6e935fcea6cf27c31e2b967bf3758283274
index 0000000000000000000000000000000000000000..fe2e06a827555d81a30697f8b08667692a3eeade
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledChunkCacheTaskQueue.java
@@ -0,0 +1,52 @@
@@ -154,7 +165,7 @@ index 0000000000000000000000000000000000000000..60a3b6e935fcea6cf27c31e2b967bf37
+public final class AllLevelsScheduledChunkCacheTaskQueue extends AllLevelsScheduledTaskQueue {
+
+ AllLevelsScheduledChunkCacheTaskQueue() {
+ super(TaskSpan.FREE, false); // TODO Gale could be TINY maybe? Should check the type of tasks scheduled
+ super(TaskSpan.YIELDING, false);
+ }
+
+ @Override
@@ -178,7 +189,7 @@ index 0000000000000000000000000000000000000000..60a3b6e935fcea6cf27c31e2b967bf37
+
+}
diff --git a/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java b/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java
index 2eb121798b2feb2a5ce5ebb60316660dbff87de3..c9ded5f30e5465c8e15719ac785797cf476474f1 100644
index 657c3663ed54043e7e4e6660d34903ef746fd8e7..c2acd36b3101042f39afe1436836078dcce2100d 100644
--- a/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java
+++ b/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java
@@ -12,7 +12,8 @@ import org.galemc.gale.executor.thread.pool.BaseThreadActivation;
@@ -192,10 +203,10 @@ index 2eb121798b2feb2a5ce5ebb60316660dbff87de3..c9ded5f30e5465c8e15719ac785797cf
* All tasks provided by this queue must be yield-free.
*
diff --git a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
index 85f467b3cedef57b6b51f04eb34316d43e192d87..152d3c9805365ff157e484e644b982febdcb6693 100644
index f4adcdcad96b2748c60aecb8f5c25370ee6e8f5b..8465ce8de44d823aac4784fbc5183b9fc49b2825 100644
--- a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
+++ b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
@@ -59,7 +59,8 @@ public enum BaseTaskQueueTier {
@@ -61,7 +61,8 @@ public enum BaseTaskQueueTier {
SERVER(new AbstractTaskQueue[]{
BaseTaskQueues.deferredToServerThread,
BaseTaskQueues.serverThreadTick,

View File

@@ -83,7 +83,7 @@ index 84cc9397237fa0c17aa1012dfb5683c90eb6d3b8..f5c15d40094c2ddc6220b0595597d121
final ReentrantLock schedulingLock = new ReentrantLock();
public final ChunkHolderManager chunkHolderManager;
diff --git a/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java b/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java
index c9ded5f30e5465c8e15719ac785797cf476474f1..2d5a6d60d87b34d03d2d8bbda6d92fddec86924a 100644
index c2acd36b3101042f39afe1436836078dcce2100d..36b844cfe3a3877496931ec739f6d5af84f32748 100644
--- a/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java
+++ b/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTaskQueue.java
@@ -13,7 +13,7 @@ import org.jetbrains.annotations.Nullable;
@@ -97,7 +97,7 @@ index c9ded5f30e5465c8e15719ac785797cf476474f1..2d5a6d60d87b34d03d2d8bbda6d92fdd
*
diff --git a/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTickThreadChunkTaskQueue.java b/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTickThreadChunkTaskQueue.java
new file mode 100644
index 0000000000000000000000000000000000000000..117797c4ac2a81218e9f3e977467b62a18e8136f
index 0000000000000000000000000000000000000000..0e893e7fca1ae3831c3de3a8966e086616e1003c
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/queue/AllLevelsScheduledTickThreadChunkTaskQueue.java
@@ -0,0 +1,54 @@
@@ -132,7 +132,7 @@ index 0000000000000000000000000000000000000000..117797c4ac2a81218e9f3e977467b62a
+public final class AllLevelsScheduledTickThreadChunkTaskQueue extends AllLevelsScheduledTaskQueue {
+
+ AllLevelsScheduledTickThreadChunkTaskQueue() {
+ super(TaskSpan.FREE, true); // TODO Gale could be TINY maybe? But probably not? Should check the type of tasks scheduled
+ super(TaskSpan.YIELDING, true);
+ }
+
+ @Override
@@ -156,10 +156,10 @@ index 0000000000000000000000000000000000000000..117797c4ac2a81218e9f3e977467b62a
+
+}
diff --git a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
index 152d3c9805365ff157e484e644b982febdcb6693..303bdcf41c7836c35bbe0fe00e0d14b5472df072 100644
index 8465ce8de44d823aac4784fbc5183b9fc49b2825..0035d638667c6e0707ecf3e3c040f0123f8e68d5 100644
--- a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
+++ b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
@@ -60,7 +60,8 @@ public enum BaseTaskQueueTier {
@@ -62,7 +62,8 @@ public enum BaseTaskQueueTier {
BaseTaskQueues.deferredToServerThread,
BaseTaskQueues.serverThreadTick,
BaseTaskQueues.anyTickScheduledServerThread,

View File

@@ -480,10 +480,10 @@ index f5c15d40094c2ddc6220b0595597d12103fcf425..79ef41d2bb30beee2355d1de3dc99c9e
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 0019e5eefc4b638526a75dd3706a54033dd9b811..7ed820d2483bf6741a355b062f062a04866ba938 100644
index 313d45dae086ac7c1bd0dd71540020c18a9e5d86..c14b593bd450d244209d17b637fe7c03a1f746f4 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1069,6 +1069,10 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
@@ -1070,6 +1070,10 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
}
}
@@ -507,10 +507,10 @@ index abdec5529763b77126494ae0c2be9b48de900bc1..35233587de14cf52da30324df89d9ec7
* This class is a copy of {@link PrioritisedQueueExecutorThread}, with the notable difference
* that it does not extend {@link Thread}, but may be instantiated on its own, as an agent representing
diff --git a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
index 303bdcf41c7836c35bbe0fe00e0d14b5472df072..e9b9d016309e8fac445b223b4412c479a5aca0e8 100644
index 0035d638667c6e0707ecf3e3c040f0123f8e68d5..afd25cb20200baea7c62cf6b3081e19e4188997a 100644
--- a/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
+++ b/src/main/java/org/galemc/gale/executor/queue/BaseTaskQueueTier.java
@@ -73,7 +73,6 @@ public enum BaseTaskQueueTier {
@@ -75,7 +75,6 @@ public enum BaseTaskQueueTier {
/**
* A tier for queues that contain general tasks that must be performed at some point in time,
* asynchronously with respect to the {@link ServerThread} and the ticking of the server.
@@ -518,7 +518,7 @@ index 303bdcf41c7836c35bbe0fe00e0d14b5472df072..e9b9d016309e8fac445b223b4412c479
*/
ASYNC(new AbstractTaskQueue[]{
// The cleaner queue has high priority because it releases resources back to a pool, thereby saving memory
@@ -84,7 +83,9 @@ public enum BaseTaskQueueTier {
@@ -86,7 +85,9 @@ public enum BaseTaskQueueTier {
* A tier for queues that contain tasks with the same considerations as {@link #ASYNC},
* but with a low priority.
*/
@@ -545,16 +545,17 @@ index ed3ccf2e64539363a7be2d507c68c40b5913f75c..a12250e5aaed02995b7bf09a8018a93f
}
diff --git a/src/main/java/org/galemc/gale/executor/queue/ChunkWorkerTaskQueue.java b/src/main/java/org/galemc/gale/executor/queue/ChunkWorkerTaskQueue.java
new file mode 100644
index 0000000000000000000000000000000000000000..6f78603c87517bb681ae473d0c72b75e23db6689
index 0000000000000000000000000000000000000000..221f9e6f10c56c92e00fc8f41e09a977a7ed9e76
--- /dev/null
+++ b/src/main/java/org/galemc/gale/executor/queue/ChunkWorkerTaskQueue.java
@@ -0,0 +1,102 @@
@@ -0,0 +1,106 @@
+// Gale - base thread pool - chunk worker task queue
+
+package org.galemc.gale.executor.queue;
+
+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedQueueExecutorThread;
+import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler;
+import net.minecraft.server.level.ServerChunkCache;
+import org.galemc.gale.executor.TaskSpan;
+import org.galemc.gale.executor.annotation.YieldFree;
+import org.galemc.gale.executor.annotation.thread.AnyThreadSafe;
@@ -620,8 +621,11 @@ index 0000000000000000000000000000000000000000..6f78603c87517bb681ae473d0c72b75e
+ return () -> {
+ var workerAgent = currentThread.getChunkWorkerAgent();
+ ChunkTaskScheduler.workerThreads.activeThreads.add(workerAgent);
+ workerAgent.pollTasks();
+ boolean performedTasks = workerAgent.pollTasks();
+ ChunkTaskScheduler.workerThreads.activeThreads.remove(workerAgent);
+ if (performedTasks) {
+ ServerChunkCache.MainThreadExecutor.notifyOfCompletedChunkWorkerTasks();
+ }
+ };
+ }
+

View File

@@ -7,18 +7,18 @@ License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html)
Gale - https://galemc.org
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 7ed820d2483bf6741a355b062f062a04866ba938..575f8ba79cf3547b837abb5957fed0aa29e1d0cf 100644
index c14b593bd450d244209d17b637fe7c03a1f746f4..88f65137337cd5dcec80c09b80595270fec17eb3 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -154,7 +154,6 @@ import org.galemc.gale.executor.annotation.thread.OriginalServerThreadOnly;
import org.galemc.gale.executor.queue.BaseTaskQueues;
@@ -155,7 +155,6 @@ import org.galemc.gale.executor.queue.BaseTaskQueues;
import org.galemc.gale.executor.queue.ScheduledServerThreadTaskQueues;
import org.galemc.gale.executor.thread.BaseThread;
import org.galemc.gale.executor.thread.OriginalServerThread;
-import org.galemc.gale.executor.thread.SignalReason;
import org.galemc.gale.executor.thread.pool.BaseThreadActivation;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
@@ -1576,15 +1575,53 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
@@ -1577,15 +1576,53 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTimingFullServerTick(); // Paper // Gale - final timings calls
}
@@ -73,7 +73,7 @@ index 7ed820d2483bf6741a355b062f062a04866ba938..575f8ba79cf3547b837abb5957fed0aa
// CraftBukkit start
// Run tasks that are waiting on processing
MinecraftTimings.processQueueTimer.startTiming(); // Spigot
@@ -1592,11 +1629,14 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
@@ -1593,11 +1630,14 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
this.processQueue.remove().run();
}
MinecraftTimings.processQueueTimer.stopTiming(); // Spigot
@@ -89,7 +89,7 @@ index 7ed820d2483bf6741a355b062f062a04866ba938..575f8ba79cf3547b837abb5957fed0aa
final boolean doDaylight = world.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT);
final long dayTime = world.getDayTime();
long worldTime = world.getGameTime();
@@ -1611,15 +1651,23 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
@@ -1612,15 +1652,23 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
new ClientboundSetTimePacket(worldTime, playerTime, doDaylight);
entityplayer.connection.send(packet); // Add support for per player time
}
@@ -115,7 +115,7 @@ index 7ed820d2483bf6741a355b062f062a04866ba938..575f8ba79cf3547b837abb5957fed0aa
/* Drop global time updates
if (this.tickCount % 20 == 0) {
@@ -1629,16 +1677,28 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
@@ -1630,16 +1678,28 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
}
// CraftBukkit end */
@@ -149,7 +149,7 @@ index 7ed820d2483bf6741a355b062f062a04866ba938..575f8ba79cf3547b837abb5957fed0aa
// Spigot Start
CrashReport crashreport;
try {
@@ -1651,22 +1711,47 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
@@ -1652,22 +1712,47 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
worldserver.fillReportDetails(crashreport);
throw new ReportedException(crashreport);
@@ -200,7 +200,7 @@ index 7ed820d2483bf6741a355b062f062a04866ba938..575f8ba79cf3547b837abb5957fed0aa
for (int i = 0; i < this.tickables.size(); ++i) {
((Runnable) this.tickables.get(i)).run();
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 2a0cbe5146eb444a8cb7ab4960904143af4456a7..aa49a3d3827128c7d4c7b424211f80abd7e2ff80 100644
index f1aaf1cae3335f7c7340104cfd6dbc3dd62f6ab3..1d50e234955ae22f7ba32006757af3e78310ab8b 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -630,23 +630,99 @@ public class ServerChunkCache extends ChunkSource {