diff --git a/Spigot-Server-Patches/Async-Chunk-Loading-and-Generation.patch b/Spigot-Server-Patches/Async-Chunk-Loading-and-Generation.patch index ae476fc9e..2ca59ca1c 100644 --- a/Spigot-Server-Patches/Async-Chunk-Loading-and-Generation.patch +++ b/Spigot-Server-Patches/Async-Chunk-Loading-and-Generation.patch @@ -345,6 +345,18 @@ index 0000000000..0a9fd5d662 + }; + +} +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index 9162151e2a..15a327923f 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { + + for (k = 0; k < this.sections.length; ++k) { + this.sections[k] = protochunk.getSections()[k]; ++ if (this.sections[k] != null) this.sections[k].disableLocks(); // Paper - Async Chunks - disable locks used during world gen + } + + Iterator iterator = protochunk.s().iterator(); diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java index 5b57ea93c8..5d5834ba7f 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -503,6 +515,28 @@ index c233b7e903..edd0742527 100644 completion = new Supplier() { public NBTTagCompound get() { +diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java +index bdfc7d81ff..a5c4564d60 100644 +--- a/src/main/java/net/minecraft/server/ChunkSection.java ++++ b/src/main/java/net/minecraft/server/ChunkSection.java +@@ -0,0 +0,0 @@ public class ChunkSection { + this.skyLight = new NibbleArray(); + } + ++ // Paper start - Async Chunks - Lock during world gen ++ if (chunk instanceof ProtoChunk) { ++ this.blockIds.enableLocks(); ++ } else { ++ this.blockIds.disableLocks(); ++ } ++ } ++ void disableLocks() { ++ this.blockIds.disableLocks(); + } ++ // Paper end + + public IBlockData getType(int i, int j, int k) { + return this.blockIds.a(i, j, k); diff --git a/src/main/java/net/minecraft/server/ChunkTaskScheduler.java b/src/main/java/net/minecraft/server/ChunkTaskScheduler.java index 34019bd1b3..4ca977645f 100644 --- a/src/main/java/net/minecraft/server/ChunkTaskScheduler.java @@ -526,7 +560,7 @@ index 34019bd1b3..4ca977645f 100644 ProtoChunk protochunk; diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java -index 71a3636be6..b0170db9ca 100644 +index 71a3636be6..ff0fe25417 100644 --- a/src/main/java/net/minecraft/server/DataPaletteBlock.java +++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java @@ -0,0 +0,0 @@ package net.minecraft.server; @@ -543,10 +577,24 @@ index 71a3636be6..b0170db9ca 100644 private DataPalette h; private DataPalette getDataPalette() { return this.h; } // Paper - OBFHELPER private int i; private int getBitsPerObject() { return this.i; } // Paper - OBFHELPER - private final ReentrantLock j = new ReentrantLock(); -+ // Paper start - use read write locks -+ private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); ++ // Paper start - use read write locks only during generation, disable once back on main thread ++ private static final NoopLock NOOP_LOCK = new NoopLock(); ++ private java.util.concurrent.locks.Lock readLock = NOOP_LOCK; ++ private java.util.concurrent.locks.Lock writeLock = NOOP_LOCK; ++ ++ private static class NoopLock extends ReentrantReadWriteLock.WriteLock { ++ private NoopLock() { ++ super(new ReentrantReadWriteLock()); ++ } ++ ++ @Override ++ public final void lock() { ++ } ++ ++ @Override ++ public final void unlock() { - private void b() { +- private void b() { - if (this.j.isLocked() && !this.j.isHeldByCurrentThread()) { - String s = (String)Thread.getAllStackTraces().keySet().stream().filter(Objects::nonNull).map((thread) -> { - return thread.getName() + ": \n\tat " + (String)Arrays.stream(thread.getStackTrace()).map(Object::toString).collect(Collectors.joining("\n\tat ")); @@ -557,13 +605,24 @@ index 71a3636be6..b0170db9ca 100644 - throw new ReportedException(crashreport); - } else { - this.j.lock(); -- } -+ lock.writeLock().lock(); + } } -- + ++ synchronized void enableLocks() { ++ ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); ++ readLock = lock.readLock(); ++ writeLock = lock.writeLock(); ++ } ++ synchronized void disableLocks() { ++ readLock = NOOP_LOCK; ++ writeLock = NOOP_LOCK; ++ } ++ private void b() { ++ writeLock.lock(); ++ } private void c() { - this.j.unlock(); -+ lock.writeLock().unlock(); ++ writeLock.unlock(); } + // Paper end @@ -575,13 +634,13 @@ index 71a3636be6..b0170db9ca 100644 protected T a(int ix) { - T object = this.h.a(this.a.a(ix)); // Paper - decompile fix - return (T)(object == null ? this.g : object); -+ try { // Paper -+ lock.readLock().lock(); ++ try { // Paper start - read lock ++ readLock.lock(); + T object = this.h.a(this.a.a(ix)); // Paper - decompile fix + return (T)(object == null ? this.g : object); + } finally { -+ lock.readLock().unlock(); -+ } // Paper ++ readLock.unlock(); ++ } // Paper end } // Paper start - Anti-Xray - Support default methods diff --git a/Spigot-Server-Patches/Don-t-recheck-type-after-setting-a-block.patch b/Spigot-Server-Patches/Don-t-recheck-type-after-setting-a-block.patch index 93b5c250b..4e356e332 100644 --- a/Spigot-Server-Patches/Don-t-recheck-type-after-setting-a-block.patch +++ b/Spigot-Server-Patches/Don-t-recheck-type-after-setting-a-block.patch @@ -16,7 +16,7 @@ be having data corruption issues anyways. This provides a small boost to all setType calls. diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index e4bda70bb9..895eb60854 100644 +index 0b2d9a05f4..8da88e1c3a 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { diff --git a/Spigot-Server-Patches/Fix-Sending-Chunks-to-Client.patch b/Spigot-Server-Patches/Fix-Sending-Chunks-to-Client.patch index c3cdd3aec..0f0d9888c 100644 --- a/Spigot-Server-Patches/Fix-Sending-Chunks-to-Client.patch +++ b/Spigot-Server-Patches/Fix-Sending-Chunks-to-Client.patch @@ -14,7 +14,7 @@ This fix always sends chunks to the client, and simply updates the client anytime post processing is triggered with the new chunk data. diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 83df52f30..0b0a5424e 100644 +index 8da88e1c3a..64cec6d692 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess { @@ -41,7 +41,7 @@ index 83df52f30..0b0a5424e 100644 } diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java -index 04ad94e17..748d5f28e 100644 +index 04ad94e171..748d5f28e5 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java +++ b/src/main/java/net/minecraft/server/PlayerChunk.java @@ -0,0 +0,0 @@ public class PlayerChunk { diff --git a/Spigot-Server-Patches/Optimize-Light-Recalculations.patch b/Spigot-Server-Patches/Optimize-Light-Recalculations.patch index b34241b51..5aa274140 100644 --- a/Spigot-Server-Patches/Optimize-Light-Recalculations.patch +++ b/Spigot-Server-Patches/Optimize-Light-Recalculations.patch @@ -14,7 +14,7 @@ Also optimizes to not repeatedly look up the same chunk for light lookups. diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 9162151e2a..651bb23be9 100644 +index 15a327923f..0b2d9a05f4 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {