1
0
Fork 0
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:
Aikar 2018-10-02 22:29:31 -04:00
parent 6b6c3587bc
commit 4899a1eb93
4 changed files with 75 additions and 16 deletions

View file

@ -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

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {