mirror of
https://github.com/Minestom/Minestom.git
synced 2025-03-10 05:39:11 +01:00
Avoid unnecessary thread local lookup for acquirable entities
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
2ecd10a4ec
commit
a0c38b94c6
@ -7,7 +7,6 @@ import net.minestom.server.utils.async.AsyncUtils;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
@ -25,19 +24,12 @@ public interface Acquirable<T> {
|
||||
* @return the entities ticked in the current thread
|
||||
*/
|
||||
static @NotNull Stream<@NotNull Entity> currentEntities() {
|
||||
return AcquirableImpl.ENTRIES.get().stream()
|
||||
final Thread currentThread = Thread.currentThread();
|
||||
if (currentThread instanceof TickThread) {
|
||||
return ((TickThread) currentThread).entries().stream()
|
||||
.flatMap(chunkEntry -> chunkEntry.getEntities().stream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostly for internal use, external calls are unrecommended as they could lead
|
||||
* to unexpected behavior.
|
||||
*
|
||||
* @param entries the new chunk entries
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
static void refreshEntries(@NotNull Collection<ThreadDispatcher.ChunkEntry> entries) {
|
||||
AcquirableImpl.ENTRIES.set(entries);
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,17 +1,13 @@
|
||||
package net.minestom.server.acquirable;
|
||||
|
||||
import net.minestom.server.thread.ThreadDispatcher;
|
||||
import net.minestom.server.thread.TickThread;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
final class AcquirableImpl<T> implements Acquirable<T> {
|
||||
static final ThreadLocal<Collection<ThreadDispatcher.ChunkEntry>> ENTRIES = ThreadLocal.withInitial(Collections::emptySet);
|
||||
static final AtomicLong WAIT_COUNTER_NANO = new AtomicLong();
|
||||
|
||||
/**
|
||||
@ -40,8 +36,8 @@ final class AcquirableImpl<T> implements Acquirable<T> {
|
||||
static @Nullable ReentrantLock enter(@NotNull Thread currentThread, @Nullable TickThread elementThread) {
|
||||
if (elementThread == null) return null;
|
||||
if (currentThread == elementThread) return null;
|
||||
final ReentrantLock currentLock = currentThread instanceof TickThread ? ((TickThread) currentThread).getLock() : null;
|
||||
final ReentrantLock targetLock = elementThread.getLock();
|
||||
final ReentrantLock currentLock = currentThread instanceof TickThread ? ((TickThread) currentThread).lock() : null;
|
||||
final ReentrantLock targetLock = elementThread.lock();
|
||||
if (targetLock.isHeldByCurrentThread()) return null;
|
||||
|
||||
// Monitoring
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.minestom.server.thread;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.acquirable.Acquirable;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.instance.Chunk;
|
||||
import net.minestom.server.instance.Instance;
|
||||
@ -98,9 +97,9 @@ public final class ThreadDispatcher {
|
||||
// Execute tick
|
||||
this.phaser.register();
|
||||
thread.startTick(() -> {
|
||||
Acquirable.refreshEntries(chunkEntries);
|
||||
thread.updateEntries(chunkEntries);
|
||||
|
||||
final ReentrantLock lock = thread.getLock();
|
||||
final ReentrantLock lock = thread.lock();
|
||||
lock.lock();
|
||||
for (ChunkEntry chunkEntry : chunkEntries) {
|
||||
final Chunk chunk = chunkEntry.chunk;
|
||||
|
@ -3,6 +3,8 @@ package net.minestom.server.thread;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.Phaser;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@ -18,6 +20,9 @@ public final class TickThread extends Thread {
|
||||
private volatile boolean stop;
|
||||
private Runnable tickRunnable;
|
||||
|
||||
private boolean isTicking;
|
||||
private Collection<ThreadDispatcher.ChunkEntry> entries;
|
||||
|
||||
public TickThread(Phaser phaser, int number) {
|
||||
super(MinecraftServer.THREAD_NAME_TICK + "-" + number);
|
||||
this.phaser = phaser;
|
||||
@ -27,7 +32,9 @@ public final class TickThread extends Thread {
|
||||
public void run() {
|
||||
LockSupport.park(this);
|
||||
while (!stop) {
|
||||
this.isTicking = true;
|
||||
this.tickRunnable.run();
|
||||
this.isTicking = false;
|
||||
this.phaser.arriveAndDeregister();
|
||||
LockSupport.park(this);
|
||||
}
|
||||
@ -38,12 +45,20 @@ public final class TickThread extends Thread {
|
||||
LockSupport.unpark(this);
|
||||
}
|
||||
|
||||
public Collection<ThreadDispatcher.ChunkEntry> entries() {
|
||||
return isTicking ? entries : Collections.emptyList();
|
||||
}
|
||||
|
||||
void updateEntries(Collection<ThreadDispatcher.ChunkEntry> entries) {
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lock used to ensure the safety of entity acquisition.
|
||||
*
|
||||
* @return the thread lock
|
||||
*/
|
||||
public @NotNull ReentrantLock getLock() {
|
||||
public @NotNull ReentrantLock lock() {
|
||||
return lock;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user