Skip to content

Commit eee7128

Browse files
committed
Update Paper
This update includes a new scheduler which may be used. Currently, there are two schedulers that may be configured in the global config file: - EDF - WORK_STEALING The EDF is simply the old scheduler has used since inception. The new WORK_STEALING scheduler provides possibly better scheduling: - intermediate task execution i.e chunk loading and packet processing may happen inbetween ticks, lowering latency for these tasks - NUMA aware scheduling on Linux with the `-DPaper.NumaScheduling=true` startup flag - better thread/NUMA locality, as the scheduler attempts to keep regions on the same scheduler thread/node - dynamic thread count adjustment The EDF scheduler is default as it has proven to be reliable, even if lacking.
1 parent 39b4122 commit eee7128

File tree

7 files changed

+452
-242
lines changed

7 files changed

+452
-242
lines changed

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ jobs:
1212
runs-on: ubuntu-latest
1313
steps:
1414
- name: Checkout Git Repository
15-
uses: actions/checkout@v4
15+
uses: actions/checkout@v6
1616
- name: Set up JDK
17-
uses: actions/setup-java@v4
17+
uses: actions/setup-java@v5
1818
with:
1919
distribution: 'temurin'
2020
java-version: '21'
2121
- name: Setup Gradle
22-
uses: gradle/actions/setup-gradle@v4
22+
uses: gradle/actions/setup-gradle@v5
2323
- name: Configure Git User Details
2424
run: git config --global user.email "[email protected]" && git config --global user.name "Github Actions"
2525
- name: Apply Patches

folia-server/build.gradle.kts.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
dependencies {
4747
- implementation(project(":paper-api"))
4848
+ implementation(project(":folia-api"))
49-
implementation("ca.spottedleaf:concurrentutil:0.0.7")
49+
implementation("ca.spottedleaf:concurrentutil:0.0.8")
5050
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
5151
implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21
5252
@@ -198,14 +_,14 @@

folia-server/minecraft-patches/features/0001-Region-Threading-Base.patch

Lines changed: 366 additions & 184 deletions
Large diffs are not rendered by default.

folia-server/minecraft-patches/features/0007-Region-profiler.patch

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,10 +1059,10 @@ index fdb0bcdca1cd38f55f191d42e422c354af4452b5..24c8581b2fa9c3ef6f6aad64bd4454d6
10591059

10601060
private boolean saveChunk(final ChunkAccess chunk, final boolean unloading, final Completable<CompoundTag>[] chunkSave) {
10611061
diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
1062-
index 615f30ce344455112088220a953ad78e07b284bc..94cffb77dd8aeb8329ec89d94c8709a2b67a5513 100644
1062+
index ffb6d2ef658bc658eaf7d26d9d20590fc94432e2..9772d0f7b003de2544210c5e11f7a8c8feaf0cdd 100644
10631063
--- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
10641064
+++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
1065-
@@ -69,8 +69,13 @@ public final class TickRegionScheduler {
1065+
@@ -135,8 +135,13 @@ public final class TickRegionScheduler {
10661066
tickThreadRunner.currentTickingRegion = region;
10671067
if (region != null) {
10681068
tickThreadRunner.currentTickingWorldRegionizedData = region.regioniser.world.worldRegionData.get();
@@ -1076,7 +1076,7 @@ index 615f30ce344455112088220a953ad78e07b284bc..94cffb77dd8aeb8329ec89d94c8709a2
10761076
}
10771077
}
10781078

1079-
@@ -125,6 +130,17 @@ public final class TickRegionScheduler {
1079+
@@ -191,6 +196,17 @@ public final class TickRegionScheduler {
10801080
return tickThreadRunner.currentTickingTask;
10811081
}
10821082

@@ -1094,21 +1094,21 @@ index 615f30ce344455112088220a953ad78e07b284bc..94cffb77dd8aeb8329ec89d94c8709a2
10941094
/**
10951095
* Schedules the given region
10961096
* @throws IllegalStateException If the region is already scheduled or is ticking
1097-
@@ -206,6 +222,9 @@ public final class TickRegionScheduler {
1097+
@@ -263,6 +279,9 @@ public final class TickRegionScheduler {
10981098
private ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> currentTickingRegion;
10991099
private RegionizedWorldData currentTickingWorldRegionizedData;
1100-
private SchedulerThreadPool.SchedulableTick currentTickingTask;
1100+
private SchedulableTick currentTickingTask;
11011101
+ // Folia start - profiler
11021102
+ private ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle.NO_OP_HANDLE;
11031103
+ // Folia end - profiler
11041104

1105-
public TickThreadRunner(final Runnable run, final String name) {
1106-
super(run, name);
1105+
public TickThreadRunner(final ThreadGroup group, final Runnable run, final String name) {
1106+
super(group, run, name);
11071107
diff --git a/io/papermc/paper/threadedregions/TickRegions.java b/io/papermc/paper/threadedregions/TickRegions.java
1108-
index 312a98beecb95153cd10424c1c44f0d5e97a87d8..e61fbf9fbb9330087e49f92117aa0e8bad3770f6 100644
1108+
index 40d2883d86a43175b49260bd2cb17459cc329639..4cae0a644bc979c1efeb784adff0f49dab3c6bef 100644
11091109
--- a/io/papermc/paper/threadedregions/TickRegions.java
11101110
+++ b/io/papermc/paper/threadedregions/TickRegions.java
1111-
@@ -82,6 +82,11 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
1111+
@@ -103,6 +103,11 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
11121112
@Override
11131113
public void onRegionDestroy(final ThreadedRegionizer.ThreadedRegion<TickRegionData, TickRegionSectionData> region) {
11141114
// nothing for now
@@ -1120,7 +1120,7 @@ index 312a98beecb95153cd10424c1c44f0d5e97a87d8..e61fbf9fbb9330087e49f92117aa0e8b
11201120
}
11211121

11221122
@Override
1123-
@@ -104,13 +109,23 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
1123+
@@ -125,13 +130,23 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
11241124
@Override
11251125
public void preMerge(final ThreadedRegionizer.ThreadedRegion<TickRegionData, TickRegionSectionData> from,
11261126
final ThreadedRegionizer.ThreadedRegion<TickRegionData, TickRegionSectionData> into) {
@@ -1146,16 +1146,16 @@ index 312a98beecb95153cd10424c1c44f0d5e97a87d8..e61fbf9fbb9330087e49f92117aa0e8b
11461146
}
11471147

11481148
public static final class TickRegionSectionData implements ThreadedRegionizer.ThreadedRegionSectionData {}
1149-
@@ -168,6 +183,8 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
1150-
// async-safe read-only region data
1151-
private final RegionStats regionStats;
1149+
@@ -191,6 +206,8 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
1150+
1151+
private final AtomicBoolean hasPackets = new AtomicBoolean(false);
11521152

11531153
+ public volatile ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler; // Folia - profiler
11541154
+
11551155
private TickRegionData(final ThreadedRegionizer.ThreadedRegion<TickRegionData, TickRegionSectionData> region) {
11561156
this.region = region;
11571157
this.world = region.regioniser.world;
1158-
@@ -373,13 +390,29 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
1158+
@@ -450,13 +467,29 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
11591159
return this.region.region.markNotTicking();
11601160
}
11611161

@@ -1179,16 +1179,16 @@ index 312a98beecb95153cd10424c1c44f0d5e97a87d8..e61fbf9fbb9330087e49f92117aa0e8b
11791179
}
11801180

11811181
@Override
1182-
protected boolean runRegionTasks(final BooleanSupplier canContinue) {
1182+
protected void runRegionTasks(final BooleanSupplier canContinue) {
11831183
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia start - profiler
11841184
+ profiler.startInBetweenTick(); try { // Folia - profiler
11851185
final RegionizedTaskQueue.RegionTaskQueueData queue = this.region.taskQueueData;
11861186

11871187
boolean processedChunkTask = false;
1188-
@@ -400,6 +433,7 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
1188+
@@ -476,6 +509,7 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
1189+
// if we processed any chunk tasks, try to process ticket level updates for full status changes
11891190
this.region.world.moonrise$getChunkTaskScheduler().chunkHolderManager.processTicketUpdates();
11901191
}
1191-
return true;
11921192
+ } finally { profiler.stopInBetweenTick(); } // Folia - profiler
11931193
}
11941194

@@ -1446,7 +1446,7 @@ index 0000000000000000000000000000000000000000..08a0f331ac8895acb1d0fe163d85037c
14461446
+ }
14471447
+}
14481448
diff --git a/net/minecraft/network/PacketProcessor.java b/net/minecraft/network/PacketProcessor.java
1449-
index 406849772f764eb5f5f986ea5e3e0213f83b3255..758cb258a7e0478bfaacfc1b6c93ce8a501b0e6c 100644
1449+
index f9300b9f8d15843dae8fd73ff066e4be99b60451..e07e5eced7e32d1c3a0ac14e8639c1f19b0f641a 100644
14501450
--- a/net/minecraft/network/PacketProcessor.java
14511451
+++ b/net/minecraft/network/PacketProcessor.java
14521452
@@ -103,7 +103,10 @@ public class PacketProcessor implements AutoCloseable {
@@ -1461,7 +1461,7 @@ index 406849772f764eb5f5f986ea5e3e0213f83b3255..758cb258a7e0478bfaacfc1b6c93ce8a
14611461
if (var3 instanceof ReportedException reportedException && reportedException.getCause() instanceof OutOfMemoryError) {
14621462
throw PacketUtils.makeReportedException(var3, this.packet, this.listener);
14631463
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
1464-
index ae5ef245999e456612edc6c566e8a8c302684fb7..bcbce98f97169f98053badeabf2d20f3a798b488 100644
1464+
index aa2c7732749400ffaf6c0e3ff17b698959bfd5f4..9464cf735cedbf662355d9e86c37bb2851680fd6 100644
14651465
--- a/net/minecraft/server/MinecraftServer.java
14661466
+++ b/net/minecraft/server/MinecraftServer.java
14671467
@@ -1658,6 +1658,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1872,18 +1872,18 @@ index dd140762829f7311e04263e3ebf29e68192b8b28..455e4f95efc0c27e09d41d4a4deff5ab
18721872
}
18731873

18741874
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
1875-
index ef90696df3fa0f6b29a76addac256c64da0f571f..2dcd7ece555d2343cc734097831787d29309f070 100644
1875+
index 791cd313abcd2d98c8cf356211e539a714e951ad..9eff0ae2bc1024ecddb646faf767d969bb8950e8 100644
18761876
--- a/net/minecraft/server/players/PlayerList.java
18771877
+++ b/net/minecraft/server/players/PlayerList.java
1878-
@@ -1023,6 +1023,7 @@ public abstract class PlayerList {
1878+
@@ -1024,6 +1024,7 @@ public abstract class PlayerList {
18791879

18801880
public void saveAll(final int interval) {
18811881
io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
18821882
+ final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle profiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
18831883
int numSaved = 0;
18841884
final long now = System.nanoTime(); // Folia - region threading
18851885
long timeInterval = (long)interval * io.papermc.paper.threadedregions.TickRegionScheduler.TIME_BETWEEN_TICKS; // Folia - region threading
1886-
@@ -1033,7 +1034,9 @@ public abstract class PlayerList {
1886+
@@ -1034,7 +1035,9 @@ public abstract class PlayerList {
18871887
}
18881888
// Folia end - region threading
18891889
if (interval == -1 || now - player.lastSave >= timeInterval) { // Folia - region threading
@@ -1938,7 +1938,7 @@ index abccad13c2bb3a33e98ad8eb6d7f08c0ef021811..0590d5723854a03a59fe9471710802f4
19381938
}
19391939
}
19401940
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
1941-
index 9f7fa145f7f6a765c668dc7754626a91bef4ce6a..6809547216f9767d600cc4bf0bff43d572161417 100644
1941+
index 38a7af35f2e77b36d6b32ed40d0aaf7cd79440f2..dd66bd2d10b4ed98ed72112f3d0505d66539c831 100644
19421942
--- a/net/minecraft/world/level/Level.java
19431943
+++ b/net/minecraft/world/level/Level.java
19441944
@@ -194,6 +194,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl

folia-server/minecraft-patches/features/0008-Add-watchdog-thread.patch

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,41 +117,40 @@ index 0000000000000000000000000000000000000000..e9ca1a15049b0211d10401cb78e953b9
117117
+ }
118118
+}
119119
diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
120-
index 94cffb77dd8aeb8329ec89d94c8709a2b67a5513..e7a1a4cd49c65296e3235b9ba1eeaa28c5a275d2 100644
120+
index 9772d0f7b003de2544210c5e11f7a8c8feaf0cdd..a121c71e953eff821cb1655045b60221deed46b1 100644
121121
--- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
122122
+++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
123-
@@ -36,6 +36,13 @@ public final class TickRegionScheduler {
123+
@@ -41,6 +41,12 @@ public final class TickRegionScheduler {
124+
124125
public static final int TICK_RATE = 20;
125126
public static final long TIME_BETWEEN_TICKS = 1_000_000_000L / TICK_RATE; // ns
126-
127127
+ // Folia start - watchdog
128128
+ public static final FoliaWatchdogThread WATCHDOG_THREAD = new FoliaWatchdogThread();
129129
+ static {
130130
+ WATCHDOG_THREAD.start();
131131
+ }
132132
+ // Folia end - watchdog
133-
+
134-
private final SchedulerThreadPool scheduler;
135133

136-
public TickRegionScheduler(final int threads) {
137-
@@ -325,6 +332,8 @@ public final class TickRegionScheduler {
134+
private final Scheduler scheduler;
135+
136+
@@ -382,6 +388,8 @@ public final class TickRegionScheduler {
137+
this.currentTickingThread = Thread.currentThread();
138138
}
139139

140-
final boolean ret;
141140
+ final FoliaWatchdogThread.RunningTick runningTick = new FoliaWatchdogThread.RunningTick(tickStart, this, Thread.currentThread()); // Folia - watchdog
142141
+ WATCHDOG_THREAD.addTick(runningTick); // Folia - watchdog
143142
try {
144-
ret = this.runRegionTasks(() -> {
143+
this.runRegionTasks(() -> {
145144
return !RegionScheduleHandle.this.cancelled.get() && canContinue.getAsBoolean();
146-
@@ -334,6 +343,7 @@ public final class TickRegionScheduler {
145+
@@ -391,6 +399,7 @@ public final class TickRegionScheduler {
147146
// don't release region for another tick
148-
return null;
147+
return false;
149148
} finally {
150149
+ WATCHDOG_THREAD.removeTick(runningTick); // Folia - watchdog
151150
final long tickEnd = System.nanoTime();
152151
final long cpuEnd = MEASURE_CPU_TIME ? THREAD_MX_BEAN.getCurrentThreadCpuTime() : 0L;
153152

154-
@@ -397,6 +407,8 @@ public final class TickRegionScheduler {
153+
@@ -464,6 +473,8 @@ public final class TickRegionScheduler {
155154
this.currentTickingThread = Thread.currentThread();
156155
}
157156

@@ -160,7 +159,7 @@ index 94cffb77dd8aeb8329ec89d94c8709a2b67a5513..e7a1a4cd49c65296e3235b9ba1eeaa28
160159
try {
161160
// next start isn't updated until the end of this tick
162161
this.tickRegion(tickCount, tickStart, scheduledEnd);
163-
@@ -405,6 +417,7 @@ public final class TickRegionScheduler {
162+
@@ -472,6 +483,7 @@ public final class TickRegionScheduler {
164163
// regionFailed will schedule a shutdown, so we should avoid letting this region tick further
165164
return false;
166165
} finally {
@@ -169,10 +168,10 @@ index 94cffb77dd8aeb8329ec89d94c8709a2b67a5513..e7a1a4cd49c65296e3235b9ba1eeaa28
169168
final long cpuEnd = MEASURE_CPU_TIME ? THREAD_MX_BEAN.getCurrentThreadCpuTime() : 0L;
170169

171170
diff --git a/io/papermc/paper/threadedregions/TickRegions.java b/io/papermc/paper/threadedregions/TickRegions.java
172-
index e61fbf9fbb9330087e49f92117aa0e8bad3770f6..7f3bd370ee505d0f66281cdbd87d9dd43b936bb8 100644
171+
index 4cae0a644bc979c1efeb784adff0f49dab3c6bef..cf65aece53f7a1398b8e7dba527901444146a631 100644
173172
--- a/io/papermc/paper/threadedregions/TickRegions.java
174173
+++ b/io/papermc/paper/threadedregions/TickRegions.java
175-
@@ -331,9 +331,9 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
174+
@@ -408,9 +408,9 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
176175
}
177176
}
178177

0 commit comments

Comments
 (0)