mirror of
https://github.com/Minestom/Minestom.git
synced 2025-03-02 11:21:15 +01:00
Simplify acquisition, reduce overhead
This commit is contained in:
parent
a5df2376cf
commit
23664292de
@ -121,18 +121,10 @@ public final class UpdateManager {
|
||||
final CountDownLatch countDownLatch = threadProvider.update(tickStart);
|
||||
|
||||
// Wait tick end
|
||||
while (countDownLatch.getCount() != 0) {
|
||||
this.threadProvider.getThreads().forEach(batchThread -> {
|
||||
BatchThread waitingOn = batchThread.waitingOn;
|
||||
if (waitingOn != null && !waitingOn.getMainRunnable().isInTick()) {
|
||||
BatchThread waitingOn2 = waitingOn.waitingOn;
|
||||
if(waitingOn2 != null){
|
||||
Acquisition.processMonitored(waitingOn2);
|
||||
}else{
|
||||
Acquisition.processMonitored(waitingOn);
|
||||
}
|
||||
}
|
||||
});
|
||||
try {
|
||||
countDownLatch.await();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Clear removed entities & update threads
|
||||
|
@ -488,9 +488,6 @@ public class Entity implements Viewable, Tickable, LockedElement, EventHandler,
|
||||
}
|
||||
}
|
||||
|
||||
// Acquisition
|
||||
getAcquiredElement().getHandler().acquisitionTick();
|
||||
|
||||
final boolean isNettyClient = PlayerUtils.isNettyClient(this);
|
||||
|
||||
// Synchronization with updated fields in #getPosition()
|
||||
|
@ -44,6 +44,8 @@ import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import net.minestom.server.item.metadata.WrittenBookMeta;
|
||||
import net.minestom.server.listener.PlayerDiggingListener;
|
||||
import net.minestom.server.lock.Acquirable;
|
||||
import net.minestom.server.lock.AcquirableCollection;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.network.ConnectionState;
|
||||
import net.minestom.server.network.PlayerProvider;
|
||||
@ -325,13 +327,22 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
packet.process(this);
|
||||
}
|
||||
|
||||
Collection<Acquirable<Player>> players = new ArrayList<>();
|
||||
//if (username.equals("TheMode911"))
|
||||
for (Player p1 : MinecraftServer.getConnectionManager().getOnlinePlayers()) {
|
||||
p1.getAcquiredElement().acquire(o -> {
|
||||
//for (Player p2 : MinecraftServer.getConnectionManager().getOnlinePlayers())
|
||||
// p2.getAcquiredElement().acquire(o2 -> { });
|
||||
});
|
||||
}
|
||||
for (Player p1 : MinecraftServer.getConnectionManager().getOnlinePlayers()) {
|
||||
//players.add(p1.getAcquiredElement());
|
||||
p1.getAcquiredElement().acquire(o -> {
|
||||
for (Player p2 : MinecraftServer.getConnectionManager().getOnlinePlayers())
|
||||
p2.getAcquiredElement().acquire(o2 -> {});
|
||||
});
|
||||
}
|
||||
|
||||
/*AcquirableCollection<Player> players1 = new AcquirableCollection<>(players);
|
||||
players1.forEach(player -> {
|
||||
players1.forEach(player2 -> {
|
||||
|
||||
});
|
||||
});*/
|
||||
|
||||
super.update(time); // Super update (item pickup/fire management)
|
||||
|
||||
|
@ -8,7 +8,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@ -78,19 +77,6 @@ public interface Acquirable<T> {
|
||||
this.batchThread = batchThread;
|
||||
this.batchChunk = batchChunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executed during this element tick to empty the current thread acquisition queue.
|
||||
*/
|
||||
public void acquisitionTick() {
|
||||
if (batchThread == null)
|
||||
return;
|
||||
Acquisition.process(batchThread);
|
||||
}
|
||||
}
|
||||
|
||||
class Request {
|
||||
public CountDownLatch localLatch, processLatch;
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package net.minestom.server.lock;
|
||||
|
||||
import com.google.common.util.concurrent.Monitor;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.thread.BatchThread;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -13,7 +14,7 @@ import java.util.function.Consumer;
|
||||
|
||||
public final class Acquisition {
|
||||
|
||||
private static final Map<BatchThread, Collection<Acquirable.Request>> REQUEST_MAP = new ConcurrentHashMap<>();
|
||||
private static final Map<BatchThread, Collection<Request>> REQUEST_MAP = new ConcurrentHashMap<>();
|
||||
private static final ThreadLocal<ScheduledAcquisition> SCHEDULED_ACQUISITION = ThreadLocal.withInitial(ScheduledAcquisition::new);
|
||||
|
||||
private static final Monitor GLOBAL_MONITOR = new Monitor();
|
||||
@ -68,53 +69,41 @@ public final class Acquisition {
|
||||
if (elementThread == null || elementThread == currentThread) {
|
||||
callback.run();
|
||||
} else {
|
||||
final BatchThread currentBatch = currentThread instanceof BatchThread ? ((BatchThread) currentThread) : null;
|
||||
final Monitor currentMonitor = currentBatch != null ? currentBatch.monitor : null;
|
||||
|
||||
boolean enter = false;
|
||||
if (currentMonitor != null && currentMonitor.isOccupiedByCurrentThread()) {
|
||||
process((BatchThread) currentThread);
|
||||
currentMonitor.leave();
|
||||
enter = true;
|
||||
// Monitoring
|
||||
final boolean monitoring = MinecraftServer.hasWaitMonitoring();
|
||||
long time = 0;
|
||||
if (monitoring) {
|
||||
time = System.nanoTime();
|
||||
}
|
||||
|
||||
Monitor monitor = elementThread.monitor;
|
||||
BatchThread current = (BatchThread) currentThread;
|
||||
Monitor currentMonitor = current.monitor;
|
||||
final boolean currentAcquired = currentMonitor.isOccupiedByCurrentThread();
|
||||
if (currentAcquired)
|
||||
current.monitor.leave();
|
||||
|
||||
if (monitor.isOccupiedByCurrentThread() || GLOBAL_MONITOR.isOccupiedByCurrentThread()) {
|
||||
// We already have access to the thread
|
||||
callback.run();
|
||||
} else if (monitor.tryEnter()) {
|
||||
// Acquire the thread
|
||||
callback.run();
|
||||
GLOBAL_MONITOR.enter();
|
||||
|
||||
final var monitor = elementThread.monitor;
|
||||
final boolean acquired = monitor.isOccupiedByCurrentThread();
|
||||
if (!acquired) {
|
||||
monitor.enter();
|
||||
}
|
||||
|
||||
// Monitoring
|
||||
if (monitoring) {
|
||||
time = System.nanoTime() - time;
|
||||
WAIT_COUNTER_NANO.addAndGet(time);
|
||||
}
|
||||
|
||||
callback.run();
|
||||
if (!acquired) {
|
||||
monitor.leave();
|
||||
} else {
|
||||
// Thread is not available, forward request to be executed later
|
||||
|
||||
while (!GLOBAL_MONITOR.tryEnter())
|
||||
processMonitored(currentBatch);
|
||||
|
||||
var requests = getRequests(elementThread);
|
||||
Acquirable.Request request = new Acquirable.Request();
|
||||
request.localLatch = new CountDownLatch(1);
|
||||
request.processLatch = new CountDownLatch(1);
|
||||
requests.add(request);
|
||||
|
||||
try {
|
||||
currentBatch.waitingOn = elementThread;
|
||||
request.localLatch.await();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
currentBatch.waitingOn = null;
|
||||
callback.run();
|
||||
request.processLatch.countDown();
|
||||
|
||||
GLOBAL_MONITOR.leave();
|
||||
}
|
||||
|
||||
if (currentMonitor != null && enter) {
|
||||
currentMonitor.enter();
|
||||
}
|
||||
GLOBAL_MONITOR.leave();
|
||||
if (currentAcquired)
|
||||
current.monitor.enter();
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,13 +120,7 @@ public final class Acquisition {
|
||||
});
|
||||
}
|
||||
|
||||
public static void processMonitored(@NotNull BatchThread thread) {
|
||||
thread.monitor.enter();
|
||||
process(thread);
|
||||
thread.monitor.leave();
|
||||
}
|
||||
|
||||
private static @NotNull Collection<Acquirable.Request> getRequests(@NotNull BatchThread thread) {
|
||||
private static @NotNull Collection<Request> getRequests(@NotNull BatchThread thread) {
|
||||
return REQUEST_MAP.computeIfAbsent(thread, batchThread -> ConcurrentHashMap.newKeySet());
|
||||
}
|
||||
|
||||
@ -179,6 +162,11 @@ public final class Acquisition {
|
||||
WAIT_COUNTER_NANO.set(0);
|
||||
}
|
||||
|
||||
private static class Request {
|
||||
public CountDownLatch localLatch, processLatch;
|
||||
public Runnable runnable;
|
||||
}
|
||||
|
||||
private static class ScheduledAcquisition {
|
||||
private final List<Acquirable<Object>> acquirableElements = new ArrayList<>();
|
||||
private final Map<Object, List<Consumer<Object>>> callbacks = new HashMap<>();
|
||||
|
@ -2,8 +2,6 @@ package net.minestom.server.thread;
|
||||
|
||||
import com.google.common.util.concurrent.Monitor;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.lock.Acquirable;
|
||||
import net.minestom.server.lock.Acquisition;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -17,8 +15,7 @@ public class BatchThread extends Thread {
|
||||
|
||||
private final BatchRunnable runnable;
|
||||
|
||||
public final Monitor monitor = new Monitor();
|
||||
public volatile BatchThread waitingOn;
|
||||
public volatile Monitor monitor = new Monitor();
|
||||
|
||||
public BatchThread(@NotNull BatchRunnable runnable, int number) {
|
||||
super(runnable, MinecraftServer.THREAD_NAME_TICK + "-" + number);
|
||||
@ -69,11 +66,6 @@ public class BatchThread extends Thread {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
// Execute waiting acquisition
|
||||
{
|
||||
Acquisition.processMonitored(batchThread);
|
||||
}
|
||||
|
||||
localCountDownLatch.countDown();
|
||||
this.countDownLatch.compareAndSet(localCountDownLatch, null);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user