From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: wangxyper Date: Sat, 14 Jan 2023 14:23:39 +0800 Subject: [PATCH] Hearse: Remove a lock in ServerChunkCache Original license: MIT Original project: https://github.com/NaturalCodeClub/HearseRewrite diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java index 85c03dc7c1e714fab281374a177cd4c54e97d939..e311724d2e723115bc9549a61e6206a8aed835d8 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -4,6 +4,9 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.util.Either; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArraySet; import it.unimi.dsi.fastutil.objects.ObjectSet; import net.minecraft.Util; @@ -57,8 +60,7 @@ public class ServerChunkCache extends ChunkSource { @VisibleForDebug private NaturalSpawner.SpawnState lastSpawnState; // Paper start - final com.destroystokyo.paper.util.concurrent.WeakSeqLock loadedChunkMapSeqLock = new com.destroystokyo.paper.util.concurrent.WeakSeqLock(); - final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap loadedChunkMap = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(8192, 0.5f); + private final Long2ObjectMap loadedChunkMap = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>(8192, 0.5f)); private final LevelChunk[] lastLoadedChunks = new LevelChunk[4 * 4]; @@ -70,12 +72,7 @@ public class ServerChunkCache extends ChunkSource { } public void addLoadedChunk(LevelChunk chunk) { - this.loadedChunkMapSeqLock.acquireWrite(); - try { - this.loadedChunkMap.put(chunk.coordinateKey, chunk); - } finally { - this.loadedChunkMapSeqLock.releaseWrite(); - } + this.loadedChunkMap.put(chunk.coordinateKey, chunk); // rewrite cache if we have to // we do this since we also cache null chunks @@ -85,13 +82,7 @@ public class ServerChunkCache extends ChunkSource { } public void removeLoadedChunk(LevelChunk chunk) { - this.loadedChunkMapSeqLock.acquireWrite(); - try { - this.loadedChunkMap.remove(chunk.coordinateKey); - } finally { - this.loadedChunkMapSeqLock.releaseWrite(); - } - + this.loadedChunkMap.remove(chunk.coordinateKey); // rewrite cache if we have to // we do this since we also cache null chunks int cacheKey = getChunkCacheKey(chunk.locX, chunk.locZ); @@ -360,22 +351,7 @@ public class ServerChunkCache extends ChunkSource { return this.getChunkAtIfLoadedMainThread(x, z); } - LevelChunk ret = null; - long readlock; - do { - readlock = this.loadedChunkMapSeqLock.acquireRead(); - try { - ret = this.loadedChunkMap.get(k); - } catch (Throwable thr) { - if (thr instanceof ThreadDeath) { - throw (ThreadDeath)thr; - } - // re-try, this means a CME occurred... - continue; - } - } while (!this.loadedChunkMapSeqLock.tryReleaseRead(readlock)); - - return ret; + return this.loadedChunkMap.get(k); } // Paper end // Paper start - async chunk io @@ -436,7 +412,7 @@ public class ServerChunkCache extends ChunkSource { // Paper end com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x1, z1); // Paper - sync load info //this.level.timings.syncChunkLoad.startTiming(); // Paper // Purpur - chunkproviderserver_b.managedBlock(completablefuture::isDone); + chunkproviderserver_b.managedBlock(completablefuture::isDone); io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - async chunk debug // Paper - rewrite chunk system //this.level.timings.syncChunkLoad.stopTiming(); // Paper // Purpur } // Paper @@ -495,6 +471,7 @@ public class ServerChunkCache extends ChunkSource { // Paper start - add isUrgent - old sig left in place for dirty nms plugins return getChunkFutureMainThread(chunkX, chunkZ, leastStatus, create, false); } + private CompletableFuture> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create, boolean isUrgent) { // Paper start - rewrite chunk system io.papermc.paper.util.TickThread.ensureTickThread(this.level, chunkX, chunkZ, "Scheduling chunk load off-main");