mirror of
https://github.com/PaperMC/Paper.git
synced 2025-02-03 21:37:28 +01:00
Disable use of Locks on main thread for DataPaletteBlock
This should greatly improve performance by using a No Op lock while on the main thread. Vanilla always had a write lock on write operations, but we added a Read Lock during Async Chunks to make concurrent writes non fatal for Async Chunks. This means we added on a bunch of over head to all chunk read operations. This corrects that, as well as disabling the write lock while on main thread. It is a general rule that you do not touch a chunk async once it is loaded into the world, as we never had locks on the chunk before 1.13 even. So once we are on main, we don't expect concurrent access to begin with, so we don't need the write locks either.
This commit is contained in:
parent
6b6c3587bc
commit
4899a1eb93
4 changed files with 75 additions and 16 deletions
|
@ -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<NBTTagCompound>() {
|
||||
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<T> h; private DataPalette<T> 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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue