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 e45b853e60
commit 38f0f0b71a
No known key found for this signature in database
GPG key ID: 401ADFC9891FAAFE
4 changed files with 86 additions and 27 deletions

View file

@ -1,4 +1,4 @@
From 446a8037bfb38116cc712bf89d52dde7cd5aff68 Mon Sep 17 00:00:00 2001
From 523a76f0b9a204e83620100df735b2228c22306e Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 21 Jul 2018 16:55:04 -0400
Subject: [PATCH] Async Chunk Loading and Generation
@ -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
@@ -184,6 +184,7 @@ 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
@@ -24,7 +24,17 @@ 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
@@ -3,7 +3,7 @@ package net.minecraft.server;
@ -538,15 +572,29 @@ index 71a3636be6..b0170db9ca 100644
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -20,25 +20,16 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
@@ -20,25 +20,42 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
protected DataBits a; protected DataBits getDataBits() { return this.a; } // Paper - OBFHELPER
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,31 +605,42 @@ 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
public DataPaletteBlock(DataPalette<T> datapalette, RegistryBlockID<T> registryblockid, Function<NBTTagCompound, T> function, Function<T, NBTTagCompound> function1, T object) {
// Paper start - Anti-Xray - Support default constructor
@@ -147,8 +138,13 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
@@ -147,8 +164,13 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
}
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

@ -1,4 +1,4 @@
From f8d45609bd1247f999df8ac62ca914e8b18e0b28 Mon Sep 17 00:00:00 2001
From 1b776a800b336105e8b519498c9ad387a58035b0 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 28 Sep 2018 20:46:29 -0400
Subject: [PATCH] Optimize Light Recalculations
@ -14,10 +14,10 @@ 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
@@ -347,7 +347,7 @@ public class Chunk implements IChunkAccess {
@@ -348,7 +348,7 @@ public class Chunk implements IChunkAccess {
private void a(int i, int j, int k, int l) {
if (l > k && this.areNeighborsLoaded(1)) { // Paper
for (int i1 = k; i1 < l; ++i1) {
@ -26,7 +26,7 @@ index 9162151e2a..651bb23be9 100644
}
this.x = true;
@@ -578,7 +578,7 @@ public class Chunk implements IChunkAccess {
@@ -579,7 +579,7 @@ public class Chunk implements IChunkAccess {
} else {
if (flag1) {
this.initLighting();

View file

@ -1,4 +1,4 @@
From 588da1da60dac3624336295f970c26987135e8f6 Mon Sep 17 00:00:00 2001
From ab7e26676e388e98f45d9edb6bc48c3fc2d2de7d Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 28 Sep 2018 22:27:33 -0400
Subject: [PATCH] Don't recheck type after setting a block
@ -16,10 +16,10 @@ 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
@@ -573,7 +573,7 @@ public class Chunk implements IChunkAccess {
@@ -574,7 +574,7 @@ public class Chunk implements IChunkAccess {
this.world.n(blockposition);
}

View file

@ -1,4 +1,4 @@
From 5ae13b5d368068c630d57a8d6c4801b673b31ffa Mon Sep 17 00:00:00 2001
From 0270355d40dd0fcd9b6d326f6d0084d07d689e49 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 29 Sep 2018 01:18:16 -0400
Subject: [PATCH] Fix Sending Chunks to Client
@ -14,10 +14,10 @@ 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
@@ -1212,7 +1212,7 @@ public class Chunk implements IChunkAccess {
@@ -1213,7 +1213,7 @@ public class Chunk implements IChunkAccess {
}
public boolean isReady() {
@ -26,7 +26,7 @@ index 83df52f30..0b0a5424e 100644
}
public boolean v() {
@@ -1478,6 +1478,13 @@ public class Chunk implements IChunkAccess {
@@ -1479,6 +1479,13 @@ public class Chunk implements IChunkAccess {
this.h.clear();
this.a(ChunkStatus.POSTPROCESSED);
this.m.a(this);
@ -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
@@ -23,7 +23,7 @@ public class PlayerChunk {