mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-17 16:37:43 +01:00
91 lines
3.6 KiB
Diff
91 lines
3.6 KiB
Diff
From 0a317004119ae5fc7986815d13d9220aed35c20f Mon Sep 17 00:00:00 2001
|
|
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
|
Date: Sat, 20 Jul 2019 15:20:04 -0700
|
|
Subject: [PATCH] Better server sleeping/waiting
|
|
|
|
---
|
|
.../minecraft/server/IAsyncTaskHandler.java | 47 +++++++++++++++++++
|
|
.../net/minecraft/server/MinecraftServer.java | 8 ++--
|
|
2 files changed, 52 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java
|
|
index 84024e6ba..78ea0a251 100644
|
|
--- a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java
|
|
+++ b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java
|
|
@@ -91,6 +91,53 @@ public abstract class IAsyncTaskHandler<R extends Runnable> implements Mailbox<R
|
|
|
|
}
|
|
|
|
+ // Paper start - better waiting (MC-149018)
|
|
+ public void waitFor(final long time) { // time in ns
|
|
+ final long start = System.nanoTime();
|
|
+
|
|
+ ++this.e;
|
|
+
|
|
+ try {
|
|
+ while ((System.nanoTime() - start) < time) {
|
|
+ if (this.executeNext()) {
|
|
+ // re-check condition
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ // no tasks to execute
|
|
+ final long timeUsed = System.nanoTime() - start;
|
|
+ final long budget = time - timeUsed;
|
|
+
|
|
+ if (budget <= 50_000L) { // 50us, this can be tuned, even to 0
|
|
+ // this is a presumption that park does not have the precision to sleep
|
|
+ // for under 50us and we would oversleep, although this branch is not very
|
|
+ // neccessary for this to work
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ // In order to avoid thread scheduling potentially waking up us
|
|
+ // late we aim to wake up a millisecond early
|
|
+ final long budgetWithPreempt = budget - (int)(1.0e6);
|
|
+
|
|
+ if (budgetWithPreempt <= 0) {
|
|
+ // we don't have a millisecond to spare
|
|
+ LockSupport.parkNanos("short park for timed wait", 50_000L);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ // Optionally before entering the long park we could spinwait a bit here,
|
|
+ // alternatively, we could spinwait for longer periods instead of one park
|
|
+
|
|
+
|
|
+ LockSupport.parkNanos("long park for timed wait", budgetWithPreempt);
|
|
+ // additions to the queue will unpark us
|
|
+ }
|
|
+ } finally {
|
|
+ --this.e;
|
|
+ }
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
public void executeAll() { // Paper - protected -> public
|
|
while (this.executeNext()) {
|
|
;
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index 63e12399e..80c22f3b8 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -994,9 +994,11 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
|
|
|
protected void sleepForTick() {
|
|
//this.executeAll(); // Paper - move this into the tick method for timings
|
|
- this.awaitTasks(() -> {
|
|
- return !this.canSleepForTick();
|
|
- });
|
|
+ // Paper start - improve wait (MC-149018)
|
|
+ // ac will be false here given that flag is set depending on the last value of executeNext, which will be false
|
|
+ // after executing all tasks
|
|
+ this.waitFor((this.nextTick * 1000 * 1000) - System.nanoTime());
|
|
+ // Paper end
|
|
}
|
|
|
|
@Override
|
|
--
|
|
2.20.1
|
|
|