Skip to content

Commit d57650a

Browse files
committed
Try virtual thread
1 parent 99a8f71 commit d57650a

File tree

3 files changed

+76
-76
lines changed

3 files changed

+76
-76
lines changed

src/main/java/one/oktw/galaxy/mixin/tweak/MixinAsyncChunk_IOWorker.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* OKTW Galaxy Project
3-
* Copyright (C) 2018-2025
3+
* Copyright (C) 2018-2026
44
*
55
* This program is free software: you can redistribute it and/or modify
66
* it under the terms of the GNU Affero General Public License as published
@@ -31,7 +31,7 @@
3131
import net.minecraft.world.level.chunk.storage.IOWorker;
3232
import net.minecraft.world.level.chunk.storage.IOWorker.Priority;
3333
import net.minecraft.world.level.chunk.storage.RegionStorageInfo;
34-
import one.oktw.galaxy.util.KotlinCoroutineTaskExecutor;
34+
import one.oktw.galaxy.util.VirtualTaskExecutor;
3535
import org.slf4j.Logger;
3636
import org.spongepowered.asm.mixin.*;
3737
import org.spongepowered.asm.mixin.injection.At;
@@ -76,7 +76,7 @@ public abstract class MixinAsyncChunk_IOWorker {
7676
@Inject(method = "<init>", at = @At("RETURN"))
7777
private void parallelExecutor(RegionStorageInfo storageKey, Path directory, boolean dsync, CallbackInfo ci) {
7878
pendingWrites = new ConcurrentSkipListMap<>(Comparator.comparingLong(ChunkPos::toLong));
79-
consecutiveExecutor = new KotlinCoroutineTaskExecutor(3 /* FOREGROUND,BACKGROUND,SHUTDOWN */, "IOWorker-" + storageKey.type());
79+
consecutiveExecutor = new VirtualTaskExecutor(3 /* FOREGROUND,BACKGROUND,SHUTDOWN */, "IOWorker-" + storageKey.type());
8080
}
8181

8282
/**
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* OKTW Galaxy Project
3+
* Copyright (C) 2018-2026
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Affero General Public License as published
7+
* by the Free Software Foundation, either version 3 of the License, or
8+
* any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Affero General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Affero General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
package one.oktw.galaxy.util;
20+
21+
import net.minecraft.Util;
22+
import net.minecraft.util.thread.PriorityConsecutiveExecutor;
23+
import net.minecraft.util.thread.StrictQueue;
24+
25+
import java.util.concurrent.ExecutorService;
26+
import java.util.concurrent.Executors;
27+
import java.util.concurrent.atomic.AtomicInteger;
28+
29+
public class VirtualTaskExecutor extends PriorityConsecutiveExecutor {
30+
private final ExecutorService executor;
31+
private final StrictQueue.FixedPriorityQueue queue;
32+
private final AtomicInteger executePriority = new AtomicInteger(0);
33+
private final AtomicInteger executingTask = new AtomicInteger(0);
34+
35+
public VirtualTaskExecutor(int queueCount, String name) {
36+
super(queueCount, null, name);
37+
executor = Executors.newThreadPerTaskExecutor(Thread.ofVirtual().name(name, 0).factory());
38+
queue = new StrictQueue.FixedPriorityQueue(queueCount);
39+
}
40+
41+
@Override
42+
public void schedule(StrictQueue.RunnableWithPriority runnable) {
43+
queue.push(runnable);
44+
executor.execute(this::runTasks);
45+
}
46+
47+
private void runTasks() {
48+
while (!queue.isEmpty()) {
49+
StrictQueue.RunnableWithPriority task = (StrictQueue.RunnableWithPriority) queue.pop();
50+
if (task == null) continue;
51+
52+
// Check task priority
53+
if (executingTask.get() > 0 && task.priority() > executePriority.get()) {
54+
// executing task priority higher than next task, wait all task done
55+
queue.push(task);
56+
break;
57+
}
58+
59+
// Run task
60+
executePriority.set(task.priority());
61+
executingTask.incrementAndGet();
62+
executor.execute(() -> {
63+
Util.runNamed(task, name());
64+
if (executingTask.decrementAndGet() <= 0) runTasks(); // Trigger next write batch
65+
});
66+
}
67+
}
68+
69+
@Override
70+
public void close() {
71+
executor.close();
72+
}
73+
}

src/main/kotlin/one/oktw/galaxy/util/KotlinCoroutineTaskExecutor.kt

Lines changed: 0 additions & 73 deletions
This file was deleted.

0 commit comments

Comments
 (0)