9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-24 17:39:15 +00:00

Updated Upstream (Hearse)

This commit is contained in:
Dreeam
2023-01-14 01:47:15 -05:00
parent 880a25166a
commit e7a25cec0d
6 changed files with 644 additions and 42 deletions

View File

@@ -7,27 +7,6 @@ Subject: [PATCH] Hearse: Move player ticking to main thread and add lock in
Original license: MIT
Original project: https://github.com/NaturalCodeClub/HearseRewrite
diff --git a/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java b/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
index 9d26ff7d07f1e972f1720f5b2d0e66d4c9c3f1e5..86f8afd54c0cbb449403c3f43e6880ade13cfecc 100644
--- a/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
+++ b/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
@@ -8,6 +8,7 @@ import co.earthme.hearse.concurrent.threadfactory.DefaultWorkerFactory;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.player.Player;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.concurrent.LinkedBlockingQueue;
@@ -87,7 +88,7 @@ public class ServerEntityTickHook {
}
}
};
- if (!asyncEntityEnabled){
+ if (!asyncEntityEnabled || entity instanceof Player){
task.run();
return;
}
diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
index ae22ca9ea5fd3d78d8c5bf9f1ab96f1129fddc11..1012b8d1d192a946b0982c88c12a0fc0e6051972 100644
--- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java

View File

@@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: wangxyper <wangxyper@163.com>
Date: Fri, 13 Jan 2023 15:25:47 +0800
Subject: [PATCH] Hearse: Change something
Original license: MIT
Original project: https://github.com/NaturalCodeClub/HearseRewrite
diff --git a/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java b/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
index 86f8afd54c0cbb449403c3f43e6880ade13cfecc..c0e7a9cf79ddf00827daba0aa9c7a32fa76b0c7c 100644
--- a/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
+++ b/src/main/java/co/earthme/hearse/server/ServerEntityTickHook.java
@@ -88,7 +88,7 @@ public class ServerEntityTickHook {
}
}
};
- if (!asyncEntityEnabled || entity instanceof Player){
+ if (!asyncEntityEnabled){
task.run();
return;
}

View File

@@ -0,0 +1,225 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: wangxyper <wangxyper@163.com>
Date: Sat, 14 Jan 2023 09:27:14 +0800
Subject: [PATCH] Hearse: Fix a NoSuchElementError in Delayed8 and Delayed26
distance propagators
Original license: MIT
Original project: https://github.com/NaturalCodeClub/HearseRewrite
diff --git a/src/main/java/io/papermc/paper/util/misc/Delayed26WayDistancePropagator3D.java b/src/main/java/io/papermc/paper/util/misc/Delayed26WayDistancePropagator3D.java
index 762f09c8f374fbccc9f5be985401ad334e1655a0..e831738a2988746fe4e065f6ded811a8bdf5dabe 100644
--- a/src/main/java/io/papermc/paper/util/misc/Delayed26WayDistancePropagator3D.java
+++ b/src/main/java/io/papermc/paper/util/misc/Delayed26WayDistancePropagator3D.java
@@ -94,24 +94,42 @@ public final class Delayed26WayDistancePropagator3D {
protected final void addToIncreaseWorkQueue(final long coordinate, final byte level) {
final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[level];
- queue.queuedCoordinates.add(coordinate);
- queue.queuedLevels.add(level);
+
+ final long id = queue.lock.writeLock();
+ try {
+ queue.queuedCoordinates.add(coordinate);
+ queue.queuedLevels.add(level);
+ }finally {
+ queue.lock.unlockWrite(id);
+ }
this.levelIncreaseWorkQueueBitset |= (1L << level);
}
protected final void addToIncreaseWorkQueue(final long coordinate, final byte index, final byte level) {
final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[index];
- queue.queuedCoordinates.add(coordinate);
- queue.queuedLevels.add(level);
+
+ final long id = queue.lock.writeLock();
+ try {
+ queue.queuedCoordinates.add(coordinate);
+ queue.queuedLevels.add(level);
+ }finally {
+ queue.lock.unlockWrite(id);
+ }
this.levelIncreaseWorkQueueBitset |= (1L << index);
}
protected final void addToRemoveWorkQueue(final long coordinate, final byte level) {
final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelRemoveWorkQueues[level];
- queue.queuedCoordinates.add(coordinate);
- queue.queuedLevels.add(level);
+
+ final long id = queue.lock.writeLock();
+ try {
+ queue.queuedCoordinates.add(coordinate);
+ queue.queuedLevels.add(level);
+ }finally {
+ queue.lock.unlockWrite(id);
+ }
this.levelRemoveWorkQueueBitset |= (1L << level);
}
@@ -163,9 +181,20 @@ public final class Delayed26WayDistancePropagator3D {
this.levelIncreaseWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset)) {
final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[queueIndex];
- while (!queue.queuedLevels.isEmpty()) {
- final long coordinate = queue.queuedCoordinates.removeFirst();
- byte level = queue.queuedLevels.removeFirst();
+ while (true) {
+
+ long coordinate;
+ byte level;
+ final long id = queue.lock.writeLock();
+ try {
+ if (queue.queuedLevels.isEmpty()){
+ break;
+ }
+ coordinate = queue.queuedCoordinates.removeFirst();
+ level = queue.queuedLevels.removeFirst();
+ }finally {
+ queue.lock.unlockWrite(id);
+ }
final boolean neighbourCheck = level < 0;
@@ -232,9 +261,19 @@ public final class Delayed26WayDistancePropagator3D {
this.levelRemoveWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset)) {
final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelRemoveWorkQueues[queueIndex];
- while (!queue.queuedLevels.isEmpty()) {
- final long coordinate = queue.queuedCoordinates.removeFirst();
- final byte level = queue.queuedLevels.removeFirst();
+ while (true) {
+ long coordinate;
+ byte level;
+ final long id = queue.lock.writeLock();
+ try {
+ if (queue.queuedLevels.isEmpty()){
+ break;
+ }
+ coordinate = queue.queuedCoordinates.removeFirst();
+ level = queue.queuedLevels.removeFirst();
+ }finally {
+ queue.lock.unlockWrite(id);
+ }
final byte currentLevel = this.levels.removeIfGreaterOrEqual(coordinate, level);
if (currentLevel == 0) {
diff --git a/src/main/java/io/papermc/paper/util/misc/Delayed8WayDistancePropagator2D.java b/src/main/java/io/papermc/paper/util/misc/Delayed8WayDistancePropagator2D.java
index 8c5a51b5992eccf3627f326e164288b5f6bbcff6..0fa95d81bafc7fe5c1bede7a0608b54795a78fa0 100644
--- a/src/main/java/io/papermc/paper/util/misc/Delayed8WayDistancePropagator2D.java
+++ b/src/main/java/io/papermc/paper/util/misc/Delayed8WayDistancePropagator2D.java
@@ -8,6 +8,7 @@ import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet;
import java.util.Deque;
import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.locks.StampedLock;
public final class Delayed8WayDistancePropagator2D {
@@ -357,24 +358,42 @@ public final class Delayed8WayDistancePropagator2D {
protected final void addToIncreaseWorkQueue(final long coordinate, final byte level) {
final WorkQueue queue = this.levelIncreaseWorkQueues[level];
- queue.queuedCoordinates.add(coordinate);
- queue.queuedLevels.add(level);
+
+ final long id = queue.lock.writeLock();
+ try {
+ queue.queuedCoordinates.add(coordinate);
+ queue.queuedLevels.add(level);
+ }finally {
+ queue.lock.unlockWrite(id);
+ }
this.levelIncreaseWorkQueueBitset |= (1L << level);
}
protected final void addToIncreaseWorkQueue(final long coordinate, final byte index, final byte level) {
final WorkQueue queue = this.levelIncreaseWorkQueues[index];
- queue.queuedCoordinates.add(coordinate);
- queue.queuedLevels.add(level);
+
+ final long id = queue.lock.writeLock();
+ try {
+ queue.queuedCoordinates.add(coordinate);
+ queue.queuedLevels.add(level);
+ }finally {
+ queue.lock.unlockWrite(id);
+ }
this.levelIncreaseWorkQueueBitset |= (1L << index);
}
protected final void addToRemoveWorkQueue(final long coordinate, final byte level) {
final WorkQueue queue = this.levelRemoveWorkQueues[level];
- queue.queuedCoordinates.add(coordinate);
- queue.queuedLevels.add(level);
+
+ final long id = queue.lock.writeLock();
+ try {
+ queue.queuedCoordinates.add(coordinate);
+ queue.queuedLevels.add(level);
+ }finally {
+ queue.lock.unlockWrite(id);
+ }
this.levelRemoveWorkQueueBitset |= (1L << level);
}
@@ -426,9 +445,19 @@ public final class Delayed8WayDistancePropagator2D {
this.levelIncreaseWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset)) {
final WorkQueue queue = this.levelIncreaseWorkQueues[queueIndex];
- while (!queue.queuedLevels.isEmpty()) {
- final long coordinate = queue.queuedCoordinates.removeFirst();
- byte level = queue.queuedLevels.removeFirst();
+ while (true) {
+ byte level;
+ long coordinate;
+ final long id = queue.lock.writeLock();
+ try {
+ if (queue.queuedLevels.isEmpty()){
+ break;
+ }
+ coordinate = queue.queuedCoordinates.removeFirst();
+ level = queue.queuedLevels.removeFirst();
+ }finally {
+ queue.lock.unlockWrite(id);
+ }
final boolean neighbourCheck = level < 0;
@@ -492,9 +521,20 @@ public final class Delayed8WayDistancePropagator2D {
this.levelRemoveWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset)) {
final WorkQueue queue = this.levelRemoveWorkQueues[queueIndex];
- while (!queue.queuedLevels.isEmpty()) {
- final long coordinate = queue.queuedCoordinates.removeFirst();
- final byte level = queue.queuedLevels.removeFirst();
+ while (true) {
+ long coordinate;
+ byte level;
+
+ final long id = queue.lock.writeLock();
+ try {
+ if (queue.queuedLevels.isEmpty()){
+ break;
+ }
+ coordinate = queue.queuedCoordinates.removeFirst();
+ level = queue.queuedLevels.removeFirst();
+ }finally {
+ queue.lock.unlockWrite(id);
+ }
final byte currentLevel = this.levels.removeIfGreaterOrEqual(coordinate, level);
if (currentLevel == 0) {
@@ -681,6 +721,7 @@ public final class Delayed8WayDistancePropagator2D {
protected static final class WorkQueue {
public final Deque<Long> queuedCoordinates = new ConcurrentLinkedDeque<>();
public final Deque<Byte> queuedLevels = new ConcurrentLinkedDeque<>();
+ public final StampedLock lock = new StampedLock();
}
}

View File

@@ -0,0 +1,317 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: wangxyper <wangxyper@163.com>
Date: Sat, 14 Jan 2023 10:14:54 +0800
Subject: [PATCH] Hearse: Optimized some locks in ChunkEntitySlices
Original license: MIT
Original project: https://github.com/NaturalCodeClub/HearseRewrite
diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
index 122699937606f5e00e356f5c1ea12db0563508a3..b12c02962e9dad92ae79d762887c65db10765488 100644
--- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
@@ -66,50 +66,67 @@ public final class ChunkEntitySlices {
this.status = status;
}
+ private org.bukkit.entity.Entity[] getChunkEntitiesUnsafe(){
+ List<org.bukkit.entity.Entity> ret = new java.util.ArrayList<>();
+ final Entity[] entities = this.entities.getRawData();
+ for (int i = 0, size = Math.min(entities.length, this.entities.size()); i < size; ++i) {
+ final Entity entity = entities[i];
+ if (entity == null) {
+ continue;
+ }
+ final org.bukkit.entity.Entity bukkit = entity.getBukkitEntity();
+ if (bukkit != null && bukkit.isValid()) {
+ ret.add(bukkit);
+ }
+ }
+ return ret.toArray(new org.bukkit.entity.Entity[0]);
+ }
+
// Paper start - optimise CraftChunk#getEntities
public org.bukkit.entity.Entity[] getChunkEntities() {
- final long id = this.accessLock.readLock();
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)) {
+ return this.getChunkEntitiesUnsafe();
+ }
+
+ id = this.accessLock.readLock();
try {
- List<org.bukkit.entity.Entity> ret = new java.util.ArrayList<>();
- final Entity[] entities = this.entities.getRawData();
- for (int i = 0, size = Math.min(entities.length, this.entities.size()); i < size; ++i) {
- final Entity entity = entities[i];
- if (entity == null) {
- continue;
- }
- final org.bukkit.entity.Entity bukkit = entity.getBukkitEntity();
- if (bukkit != null && bukkit.isValid()) {
- ret.add(bukkit);
- }
- }
- return ret.toArray(new org.bukkit.entity.Entity[0]);
+ return this.getChunkEntitiesUnsafe();
} finally {
this.accessLock.unlockRead(id);
}
}
- public CompoundTag save() {
- final long id = this.accessLock.readLock();
- try {
- final int len = this.entities.size();
- if (len == 0) {
- return null;
- }
+ private CompoundTag saveUnsafe(){
+ final int len = this.entities.size();
+ if (len == 0) {
+ return null;
+ }
- final Entity[] rawData = this.entities.getRawData();
- final List<Entity> collectedEntities = new ArrayList<>(len);
- for (int i = 0; i < len; ++i) {
- final Entity entity = rawData[i];
- if (entity.shouldBeSaved()) {
- collectedEntities.add(entity);
- }
+ final Entity[] rawData = this.entities.getRawData();
+ final List<Entity> collectedEntities = new ArrayList<>(len);
+ for (int i = 0; i < len; ++i) {
+ final Entity entity = rawData[i];
+ if (entity.shouldBeSaved()) {
+ collectedEntities.add(entity);
}
+ }
- if (collectedEntities.isEmpty()) {
- return null;
- }
+ if (collectedEntities.isEmpty()) {
+ return null;
+ }
+
+ return EntityStorage.saveEntityChunk(collectedEntities, new ChunkPos(this.chunkX, this.chunkZ), this.world);
+ }
- return EntityStorage.saveEntityChunk(collectedEntities, new ChunkPos(this.chunkX, this.chunkZ), this.world);
+ public CompoundTag save() {
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
+ return this.saveUnsafe();
+ }
+ id = this.accessLock.readLock();
+ try {
+ return this.saveUnsafe();
} finally {
this.accessLock.unlockRead(id);
}
@@ -119,12 +136,18 @@ public final class ChunkEntitySlices {
public boolean unload() {
Entity[] collectedEntities;
int len;
- long id = this.accessLock.readLock();
- try {
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
len = this.entities.size();
collectedEntities = Arrays.copyOf(this.entities.getRawData(), len);
- } finally {
- this.accessLock.unlockRead(id);
+ }else {
+ id = this.accessLock.readLock();
+ try {
+ len = this.entities.size();
+ collectedEntities = Arrays.copyOf(this.entities.getRawData(), len);
+ } finally {
+ this.accessLock.unlockRead(id);
+ }
}
for (int i = 0; i < len; ++i) {
final Entity entity = collectedEntities[i];
@@ -160,7 +183,12 @@ public final class ChunkEntitySlices {
}
public void callEntitiesLoadEvent() {
- final long id = this.accessLock.readLock();
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
+ CraftEventFactory.callEntitiesLoadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities());
+ return;
+ }
+ id = this.accessLock.readLock();
try {
CraftEventFactory.callEntitiesLoadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities());
} finally {
@@ -169,7 +197,12 @@ public final class ChunkEntitySlices {
}
public void callEntitiesUnloadEvent() {
- final long id = this.accessLock.readLock();
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
+ CraftEventFactory.callEntitiesUnloadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities());
+ return;
+ }
+ id = this.accessLock.readLock();
try {
CraftEventFactory.callEntitiesUnloadEvent(this.world, new ChunkPos(this.chunkX, this.chunkZ), this.getAllEntities());
} finally {
@@ -179,7 +212,11 @@ public final class ChunkEntitySlices {
// Paper end - optimise CraftChunk#getEntities
public boolean isEmpty() {
- final long id = this.accessLock.readLock();
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
+ return this.entities.size() == 0;
+ }
+ id = this.accessLock.readLock();
try {
return this.entities.size() == 0;
} finally {
@@ -188,16 +225,25 @@ public final class ChunkEntitySlices {
}
public void mergeInto(final ChunkEntitySlices slices) {
- final long id = this.accessLock.readLock();
final List<Entity> cop = new ArrayList<>();
- try {
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
final Entity[] entities = this.entities.getRawData();
for (int i = 0, size = Math.min(entities.length, this.entities.size()); i < size; ++i) {
final Entity entity = entities[i];
cop.add(entity);
}
- } finally {
- this.accessLock.unlockRead(id);
+ }else {
+ id = this.accessLock.readLock();
+ try {
+ final Entity[] entities = this.entities.getRawData();
+ for (int i = 0, size = Math.min(entities.length, this.entities.size()); i < size; ++i) {
+ final Entity entity = entities[i];
+ cop.add(entity);
+ }
+ } finally {
+ this.accessLock.unlockRead(id);
+ }
}
for (Entity entity : cop){
slices.addEntity(entity, entity.sectionY);
@@ -209,13 +255,19 @@ public final class ChunkEntitySlices {
Entity[] entities;
- final long id = this.accessLock.readLock();
- try {
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
entities = Arrays.copyOf(this.entities.getRawData(), this.entities.getRawData().length);
- } finally {
- this.accessLock.unlockRead(id);
+ }else {
+ id = this.accessLock.readLock();
+ try {
+ entities = Arrays.copyOf(this.entities.getRawData(), this.entities.getRawData().length);
+ } finally {
+ this.accessLock.unlockRead(id);
+ }
}
+
for (final Entity entity : entities) {
final Visibility oldVisibility = EntityLookup.getEntityStatus(entity);
entity.chunkStatus = status;
@@ -278,7 +330,12 @@ public final class ChunkEntitySlices {
}
public void getHardCollidingEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
- final long id = this.accessLock.readLock();
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
+ this.hardCollidingEntities.getEntities(except, box, into, predicate);
+ return;
+ }
+ id = this.accessLock.readLock();
try {
this.hardCollidingEntities.getEntities(except, box, into, predicate);
} finally {
@@ -287,34 +344,46 @@ public final class ChunkEntitySlices {
}
public void getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
- final long id = this.accessLock.readLock();
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
+ this.allEntities.getEntitiesWithEnderDragonParts(except, box, into, predicate);
+ return;
+ }
+ id = this.accessLock.readLock();
try {
this.allEntities.getEntitiesWithEnderDragonParts(except, box, into, predicate);
} finally {
this.accessLock.unlockRead(id);
}
-
}
public void getEntitiesWithoutDragonParts(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
- final long id = this.accessLock.readLock();
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
+ this.allEntities.getEntities(except, box, into, predicate);
+ return;
+ }
+ id = this.accessLock.readLock();
try {
this.allEntities.getEntities(except, box, into, predicate);
} finally {
this.accessLock.unlockRead(id);
}
-
}
public <T extends Entity> void getEntities(final EntityType<?> type, final AABB box, final List<? super T> into,
final Predicate<? super T> predicate) {
- final long id = this.accessLock.readLock();
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
+ this.allEntities.getEntities(type, box, (List) into, (Predicate) predicate);
+ return;
+ }
+ id = this.accessLock.readLock();
try {
this.allEntities.getEntities(type, box, (List) into, (Predicate) predicate);
} finally {
this.accessLock.unlockRead(id);
}
-
}
protected EntityCollectionBySection initClass(final Class<? extends Entity> clazz) {
@@ -342,7 +411,18 @@ public final class ChunkEntitySlices {
public <T extends Entity> void getEntities(final Class<? extends T> clazz, final Entity except, final AABB box, final List<? super T> into,
final Predicate<? super T> predicate) {
- final long id = this.accessLock.readLock();
+ long id = this.accessLock.tryOptimisticRead();
+ if (this.accessLock.validate(id)){
+ EntityCollectionBySection collection = this.entitiesByClass.get(clazz);
+ if (collection != null) {
+ collection.getEntitiesWithEnderDragonParts(except, clazz, box, (List) into, (Predicate) predicate);
+ } else {
+ this.entitiesByClass.putIfAbsent(clazz, collection = this.initClass(clazz));
+ collection.getEntitiesWithEnderDragonParts(except, clazz, box, (List) into, (Predicate) predicate);
+ }
+ return;
+ }
+ id = this.accessLock.readLock();
try {
EntityCollectionBySection collection = this.entitiesByClass.get(clazz);
if (collection != null) {

View File

@@ -0,0 +1,102 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: wangxyper <wangxyper@163.com>
Date: Sat, 14 Jan 2023 14:23:39 +0800
Subject: [PATCH] Hearse: Remove a lock in ServerChunkCache
Original license: MIT
Original project: https://github.com/NaturalCodeClub/HearseRewrite
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 85c03dc7c1e714fab281374a177cd4c54e97d939..e311724d2e723115bc9549a61e6206a8aed835d8 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -4,6 +4,9 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.mojang.datafixers.DataFixer;
import com.mojang.datafixers.util.Either;
+import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
+import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArraySet;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import net.minecraft.Util;
@@ -57,8 +60,7 @@ public class ServerChunkCache extends ChunkSource {
@VisibleForDebug
private NaturalSpawner.SpawnState lastSpawnState;
// Paper start
- final com.destroystokyo.paper.util.concurrent.WeakSeqLock loadedChunkMapSeqLock = new com.destroystokyo.paper.util.concurrent.WeakSeqLock();
- final it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<LevelChunk> loadedChunkMap = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(8192, 0.5f);
+ private final Long2ObjectMap<LevelChunk> loadedChunkMap = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>(8192, 0.5f));
private final LevelChunk[] lastLoadedChunks = new LevelChunk[4 * 4];
@@ -70,12 +72,7 @@ public class ServerChunkCache extends ChunkSource {
}
public void addLoadedChunk(LevelChunk chunk) {
- this.loadedChunkMapSeqLock.acquireWrite();
- try {
- this.loadedChunkMap.put(chunk.coordinateKey, chunk);
- } finally {
- this.loadedChunkMapSeqLock.releaseWrite();
- }
+ this.loadedChunkMap.put(chunk.coordinateKey, chunk);
// rewrite cache if we have to
// we do this since we also cache null chunks
@@ -85,13 +82,7 @@ public class ServerChunkCache extends ChunkSource {
}
public void removeLoadedChunk(LevelChunk chunk) {
- this.loadedChunkMapSeqLock.acquireWrite();
- try {
- this.loadedChunkMap.remove(chunk.coordinateKey);
- } finally {
- this.loadedChunkMapSeqLock.releaseWrite();
- }
-
+ this.loadedChunkMap.remove(chunk.coordinateKey);
// rewrite cache if we have to
// we do this since we also cache null chunks
int cacheKey = getChunkCacheKey(chunk.locX, chunk.locZ);
@@ -360,22 +351,7 @@ public class ServerChunkCache extends ChunkSource {
return this.getChunkAtIfLoadedMainThread(x, z);
}
- LevelChunk ret = null;
- long readlock;
- do {
- readlock = this.loadedChunkMapSeqLock.acquireRead();
- try {
- ret = this.loadedChunkMap.get(k);
- } catch (Throwable thr) {
- if (thr instanceof ThreadDeath) {
- throw (ThreadDeath)thr;
- }
- // re-try, this means a CME occurred...
- continue;
- }
- } while (!this.loadedChunkMapSeqLock.tryReleaseRead(readlock));
-
- return ret;
+ return this.loadedChunkMap.get(k);
}
// Paper end
// Paper start - async chunk io
@@ -436,7 +412,7 @@ public class ServerChunkCache extends ChunkSource {
// Paper end
com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x1, z1); // Paper - sync load info
//this.level.timings.syncChunkLoad.startTiming(); // Paper // Purpur
- chunkproviderserver_b.managedBlock(completablefuture::isDone);
+ chunkproviderserver_b.managedBlock(completablefuture::isDone);
io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - async chunk debug // Paper - rewrite chunk system
//this.level.timings.syncChunkLoad.stopTiming(); // Paper // Purpur
} // Paper
@@ -495,6 +471,7 @@ public class ServerChunkCache extends ChunkSource {
// Paper start - add isUrgent - old sig left in place for dirty nms plugins
return getChunkFutureMainThread(chunkX, chunkZ, leastStatus, create, false);
}
+
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create, boolean isUrgent) {
// Paper start - rewrite chunk system
io.papermc.paper.util.TickThread.ensureTickThread(this.level, chunkX, chunkZ, "Scheduling chunk load off-main");