Skip to content

Commit 9f10749

Browse files
committed
Tick all worlds and global scheduler in parallel
1 parent 4c21050 commit 9f10749

23 files changed

Lines changed: 450 additions & 260 deletions

patches/server/0005-Add-multithreading-region-scheduler.patch

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -476,10 +476,10 @@ index 0000000000000000000000000000000000000000..f651a277fabf7f863c648c6c2658e2e6
476476
+}
477477
diff --git a/src/main/java/io/multipaper/shreddedpaper/threading/ShreddedPaperRegionScheduler.java b/src/main/java/io/multipaper/shreddedpaper/threading/ShreddedPaperRegionScheduler.java
478478
new file mode 100644
479-
index 0000000000000000000000000000000000000000..5366386f45b931f1f6d58684757bea593347be65
479+
index 0000000000000000000000000000000000000000..ab4774d7eaf13efeb41eae3fb0b646ac11b9dbce
480480
--- /dev/null
481481
+++ b/src/main/java/io/multipaper/shreddedpaper/threading/ShreddedPaperRegionScheduler.java
482-
@@ -0,0 +1,179 @@
482+
@@ -0,0 +1,185 @@
483483
+package io.multipaper.shreddedpaper.threading;
484484
+
485485
+import net.minecraft.server.level.ServerLevel;
@@ -594,63 +594,69 @@ index 0000000000000000000000000000000000000000..5366386f45b931f1f6d58684757bea59
594594
+ return;
595595
+ }
596596
+
597-
+ // Lock acquired, run the task
598-
+ runnable.run();
597+
+ try {
598+
+ runnable.run();
599+
+ } finally {
600+
+ lock.unlock();
601+
+ }
602+
+
599603
+ future.complete(null);
600604
+ } catch (Exception e) {
601605
+ future.completeExceptionally(e);
602-
+ } finally {
603-
+ if (lock != null) lock.unlock();
604606
+ }
605607
+ }
606608
+
607609
+ private void runOnMany(RegionPos[] regionPosArray, Runnable runnable, CompletableFuture<Void> future) {
608610
+ ShreddedPaperRegionLocker.RegionLock[] locks = new ShreddedPaperRegionLocker.RegionLock[regionPosArray.length];
609611
+ try {
610-
+ for (int i = 0; i < regionPosArray.length; i++) {
611-
+ locks[i] = locker.tryTakeLockNow(regionPosArray[i]);
612-
+ if (locks[i] == null) {
613-
+ locker.onUnlock(regionPosArray[i], () -> CompletableFuture.runAsync(() -> runOnMany(regionPosArray, runnable, future), ShreddedPaperTickThread.getExecutor()));
614-
+ return;
612+
+ try {
613+
+ for (int i = 0; i < regionPosArray.length; i++) {
614+
+ locks[i] = locker.tryTakeLockNow(regionPosArray[i]);
615+
+ if (locks[i] == null) {
616+
+ locker.onUnlock(regionPosArray[i], () -> CompletableFuture.runAsync(() -> runOnMany(regionPosArray, runnable, future), ShreddedPaperTickThread.getExecutor()));
617+
+ return;
618+
+ }
619+
+ }
620+
+
621+
+ // All locks acquired, run the task
622+
+ runnable.run();
623+
+ } finally {
624+
+ for (int i = locks.length - 1; i >= 0; i--) {
625+
+ if (locks[i] != null) locks[i].unlock();
615626
+ }
616627
+ }
617628
+
618-
+ // All locks acquired, run the task
619-
+ runnable.run();
620629
+ future.complete(null);
621-
+
622630
+ } catch (Exception e) {
623631
+ future.completeExceptionally(e);
624-
+ } finally {
625-
+ for (int i = locks.length - 1; i >= 0; i--) {
626-
+ if (locks[i] != null) locks[i].unlock();
627-
+ }
628632
+ }
629633
+ }
630634
+
631635
+ private static void runAcrossLevels(ServerLevel level1, RegionPos regionPos1, ServerLevel level2, RegionPos regionPos2, Runnable runnable, CompletableFuture<Void> future) {
632636
+ ShreddedPaperRegionLocker.RegionLock lock1 = null;
633637
+ ShreddedPaperRegionLocker.RegionLock lock2 = null;
634638
+ try {
635-
+ lock1 = level1.chunkScheduler.locker.tryTakeLockNow(regionPos1);
636-
+ lock2 = lock1 == null ? null : level2.chunkScheduler.locker.tryTakeLockNow(regionPos2);
639+
+ try {
640+
+ lock1 = level1.chunkScheduler.locker.tryTakeLockNow(regionPos1);
641+
+ lock2 = lock1 == null ? null : level2.chunkScheduler.locker.tryTakeLockNow(regionPos2);
642+
+
643+
+ if (lock2 == null) {
644+
+ Supplier<CompletableFuture<Void>> unlockCallback = () -> CompletableFuture.runAsync(() -> runAcrossLevels(level1, regionPos1, level2, regionPos2, runnable, future), ShreddedPaperTickThread.getExecutor());
645+
+ if (lock1 == null) level1.chunkScheduler.locker.onUnlock(regionPos1, unlockCallback);
646+
+ else level2.chunkScheduler.locker.onUnlock(regionPos2, unlockCallback);
647+
+ return;
648+
+ }
637649
+
638-
+ if (lock2 == null) {
639-
+ Supplier<CompletableFuture<Void>> unlockCallback = () -> CompletableFuture.runAsync(() -> runAcrossLevels(level1, regionPos1, level2, regionPos2, runnable, future), ShreddedPaperTickThread.getExecutor());
640-
+ if (lock1 == null) level1.chunkScheduler.locker.onUnlock(regionPos1, unlockCallback);
641-
+ else level2.chunkScheduler.locker.onUnlock(regionPos2, unlockCallback);
642-
+ return;
650+
+ // Both locks acquired, run the task
651+
+ runnable.run();
652+
+ } finally {
653+
+ if (lock2 != null) lock2.unlock();
654+
+ if (lock1 != null) lock1.unlock();
643655
+ }
644656
+
645-
+ // Both locks acquired, run the task
646-
+ runnable.run();
647657
+ future.complete(null);
648-
+
649658
+ } catch (Exception e) {
650659
+ future.completeExceptionally(e);
651-
+ } finally {
652-
+ if (lock2 != null) lock2.unlock();
653-
+ if (lock1 != null) lock1.unlock();
654660
+ }
655661
+ }
656662
+
@@ -661,7 +667,7 @@ index 0000000000000000000000000000000000000000..5366386f45b931f1f6d58684757bea59
661667
+}
662668
diff --git a/src/main/java/io/multipaper/shreddedpaper/threading/ShreddedPaperTickThread.java b/src/main/java/io/multipaper/shreddedpaper/threading/ShreddedPaperTickThread.java
663669
new file mode 100644
664-
index 0000000000000000000000000000000000000000..00394883983dc1e17e5e310884009802e32a7907
670+
index 0000000000000000000000000000000000000000..4083ed79587332391cedf8108f8adeeeffe4a8ad
665671
--- /dev/null
666672
+++ b/src/main/java/io/multipaper/shreddedpaper/threading/ShreddedPaperTickThread.java
667673
@@ -0,0 +1,62 @@
@@ -710,7 +716,7 @@ index 0000000000000000000000000000000000000000..00394883983dc1e17e5e310884009802
710716
+ return Thread.currentThread() instanceof ShreddedPaperTickThread;
711717
+ }
712718
+
713-
+ static ExecutorService getExecutor() {
719+
+ public static ExecutorService getExecutor() {
714720
+ return executor;
715721
+ }
716722
+

0 commit comments

Comments
 (0)