mirror of
https://hub.spigotmc.org/stash/scm/spigot/spigot.git
synced 2025-09-18 21:33:01 +00:00
Remove DataWatcher Locking
The lock in DataWatcher is used to prevent concurrent modifications, however any modifications to this map only occur on initialization of an Entity in its constructor. Every other access is through a readlock, which allows the threads to pass if there is no thread holding the writelock. Since the writelock is only obtained in the constructor of the Entity, the further readlocks are actually useless. This patch also changes the entries map to be fastutil int2objectopenhashmap for performance.
This commit is contained in:
parent
5e4e7f32bc
commit
9a643a6af5
1 changed files with 158 additions and 0 deletions
158
CraftBukkit-Patches/0108-Remove-DataWatcher-Locking.patch
Normal file
158
CraftBukkit-Patches/0108-Remove-DataWatcher-Locking.patch
Normal file
|
@ -0,0 +1,158 @@
|
|||
From a08d1c75772d20269395a02b6b3ee57a314180e0 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Tue, 9 Jul 2019 02:18:54 -0700
|
||||
Subject: [PATCH] Remove DataWatcher Locking
|
||||
|
||||
The lock in DataWatcher is used to prevent concurrent modifications,
|
||||
however any modifications to this map only occur on initialization of
|
||||
an Entity in its constructor.
|
||||
|
||||
Every other access is through a readlock, which allows the threads to
|
||||
pass if there is no thread holding the writelock.
|
||||
|
||||
Since the writelock is only obtained in the constructor of the Entity,
|
||||
the further readlocks are actually useless.
|
||||
|
||||
This patch also changes the entries map to be fastutil
|
||||
int2objectopenhashmap for performance.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/DataWatcher.java b/src/main/java/net/minecraft/server/DataWatcher.java
|
||||
index 79a240cd1..996bc9951 100644
|
||||
--- a/src/main/java/net/minecraft/server/DataWatcher.java
|
||||
+++ b/src/main/java/net/minecraft/server/DataWatcher.java
|
||||
@@ -21,8 +21,8 @@ public class DataWatcher {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final Map<Class<? extends Entity>, Integer> b = Maps.newHashMap();
|
||||
private final Entity c;
|
||||
- private final Map<Integer, DataWatcher.Item<?>> d = Maps.newHashMap();
|
||||
- private final ReadWriteLock e = new ReentrantReadWriteLock();
|
||||
+ private final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<DataWatcher.Item<?>> d = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); // Spigot - use better map // PAIL
|
||||
+ // private final ReadWriteLock e = new ReentrantReadWriteLock(); // Spigot - not required // PAIL
|
||||
private boolean f = true;
|
||||
private boolean g;
|
||||
|
||||
@@ -70,7 +70,9 @@ public class DataWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
+ boolean registrationLocked; // Spigot
|
||||
public <T> void register(DataWatcherObject<T> datawatcherobject, T t0) {
|
||||
+ if (this.registrationLocked) throw new IllegalStateException("Registering datawatcher object after entity initialization"); // Spigot
|
||||
int i = datawatcherobject.a();
|
||||
|
||||
if (i > 254) {
|
||||
@@ -87,13 +89,15 @@ public class DataWatcher {
|
||||
private <T> void registerObject(DataWatcherObject<T> datawatcherobject, T t0) {
|
||||
DataWatcher.Item<T> datawatcher_item = new DataWatcher.Item<>(datawatcherobject, t0);
|
||||
|
||||
- this.e.writeLock().lock();
|
||||
+ // this.e.writeLock().lock(); // Spigot - not required
|
||||
this.d.put(datawatcherobject.a(), datawatcher_item);
|
||||
this.f = false;
|
||||
- this.e.writeLock().unlock();
|
||||
+ // this.e.writeLock().unlock(); // Spigot - not required
|
||||
}
|
||||
|
||||
private <T> DataWatcher.Item<T> b(DataWatcherObject<T> datawatcherobject) {
|
||||
+ // Spigot start
|
||||
+ /*
|
||||
this.e.readLock().lock();
|
||||
|
||||
DataWatcher.Item datawatcher_item;
|
||||
@@ -111,6 +115,9 @@ public class DataWatcher {
|
||||
}
|
||||
|
||||
return datawatcher_item;
|
||||
+ */
|
||||
+ return (DataWatcher.Item) this.d.get(datawatcherobject.a());
|
||||
+ // Spigot end
|
||||
}
|
||||
|
||||
public <T> T get(DataWatcherObject<T> datawatcherobject) {
|
||||
@@ -157,7 +164,7 @@ public class DataWatcher {
|
||||
List<DataWatcher.Item<?>> list = null;
|
||||
|
||||
if (this.g) {
|
||||
- this.e.readLock().lock();
|
||||
+ // this.e.readLock().lock(); // Spigot - not required
|
||||
Iterator iterator = this.d.values().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -173,7 +180,7 @@ public class DataWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
- this.e.readLock().unlock();
|
||||
+ // this.e.readLock().unlock(); // Spigot - not required
|
||||
}
|
||||
|
||||
this.g = false;
|
||||
@@ -181,7 +188,7 @@ public class DataWatcher {
|
||||
}
|
||||
|
||||
public void a(PacketDataSerializer packetdataserializer) throws IOException {
|
||||
- this.e.readLock().lock();
|
||||
+ // this.e.readLock().lock(); // Spigot - not required
|
||||
Iterator iterator = this.d.values().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -190,7 +197,7 @@ public class DataWatcher {
|
||||
a(packetdataserializer, datawatcher_item);
|
||||
}
|
||||
|
||||
- this.e.readLock().unlock();
|
||||
+ // this.e.readLock().unlock(); // Spigot - not required
|
||||
packetdataserializer.writeByte(255);
|
||||
}
|
||||
|
||||
@@ -198,7 +205,7 @@ public class DataWatcher {
|
||||
public List<DataWatcher.Item<?>> c() {
|
||||
List<DataWatcher.Item<?>> list = null;
|
||||
|
||||
- this.e.readLock().lock();
|
||||
+ // this.e.readLock().lock(); // Spigot - not required
|
||||
|
||||
DataWatcher.Item datawatcher_item;
|
||||
|
||||
@@ -209,7 +216,7 @@ public class DataWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
- this.e.readLock().unlock();
|
||||
+ // this.e.readLock().unlock(); // Spigot - not required
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -260,7 +267,7 @@ public class DataWatcher {
|
||||
|
||||
public void e() {
|
||||
this.g = false;
|
||||
- this.e.readLock().lock();
|
||||
+ // this.e.readLock().lock(); // Spigot - not required
|
||||
Iterator iterator = this.d.values().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -269,7 +276,7 @@ public class DataWatcher {
|
||||
datawatcher_item.a(false);
|
||||
}
|
||||
|
||||
- this.e.readLock().unlock();
|
||||
+ // this.e.readLock().unlock(); // Spigot - not required
|
||||
}
|
||||
|
||||
public static class Item<T> {
|
||||
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
||||
index f949ace59..6cf4ebeb8 100644
|
||||
--- a/src/main/java/net/minecraft/server/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/server/Entity.java
|
||||
@@ -216,6 +216,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener {
|
||||
this.datawatcher.register(Entity.aC, false);
|
||||
this.datawatcher.register(Entity.POSE, EntityPose.STANDING);
|
||||
this.initDatawatcher();
|
||||
+ this.datawatcher.registrationLocked = true; // Spigot
|
||||
this.headHeight = this.getHeadHeight(EntityPose.STANDING, this.size);
|
||||
}
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
Loading…
Add table
Reference in a new issue