Tick scheduling micro-optimization

This commit is contained in:
TheMode 2021-05-07 20:41:40 +02:00
parent a33234d886
commit fb03b953bb

View File

@ -4,8 +4,6 @@ import net.minestom.server.MinecraftServer;
import net.minestom.server.utils.validate.Check; import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.LockSupport;
@ -50,10 +48,7 @@ public class TickThread extends Thread {
private volatile boolean stop; private volatile boolean stop;
private TickThread tickThread; private TickThread tickThread;
private volatile boolean inTick; private final AtomicReference<TickContext> tickContext = new AtomicReference<>();
private final AtomicReference<CountDownLatch> countDownLatch = new AtomicReference<>();
private final Queue<Runnable> queue = new ConcurrentLinkedQueue<>();
@Override @Override
public void run() { public void run() {
@ -62,42 +57,38 @@ public class TickThread extends Thread {
LockSupport.park(tickThread); LockSupport.park(tickThread);
if (stop) if (stop)
break; break;
CountDownLatch localCountDownLatch = this.countDownLatch.get(); TickContext localContext = this.tickContext.get();
// The context is necessary to control the tick rates
// The latch is necessary to control the tick rates if (localContext == null) {
if (localCountDownLatch == null) {
continue; continue;
} }
this.inTick = true; // Execute tick
localContext.runnable.run();
// Execute all pending runnable localContext.countDownLatch.countDown();
Runnable runnable; this.tickContext.compareAndSet(localContext, null);
while ((runnable = queue.poll()) != null) {
runnable.run();
}
localCountDownLatch.countDown();
this.countDownLatch.compareAndSet(localCountDownLatch, null);
// Wait for the next notify (game tick)
this.inTick = false;
} }
} }
public void startTick(@NotNull CountDownLatch countDownLatch, @NotNull Runnable runnable) { protected void startTick(@NotNull CountDownLatch countDownLatch, @NotNull Runnable runnable) {
this.countDownLatch.set(countDownLatch); this.tickContext.set(new TickContext(countDownLatch, runnable));
this.queue.add(runnable);
LockSupport.unpark(tickThread); LockSupport.unpark(tickThread);
} }
public boolean isInTick() {
return inTick;
}
private void setLinkedThread(TickThread tickThread) { private void setLinkedThread(TickThread tickThread) {
this.tickThread = tickThread; this.tickThread = tickThread;
} }
} }
private static class TickContext {
private final CountDownLatch countDownLatch;
private final Runnable runnable;
private TickContext(@NotNull CountDownLatch countDownLatch, @NotNull Runnable runnable) {
this.countDownLatch = countDownLatch;
this.runnable = runnable;
}
}
} }