Skip to content

Commit 2dc53b1

Browse files
committed
Merge schedulers, cleanup locking and adjust thread counts
1 parent 9a9c1a4 commit 2dc53b1

File tree

6 files changed

+33
-33
lines changed

6 files changed

+33
-33
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.yatopiamc.c2me.common.threading;
2+
3+
import com.google.common.util.concurrent.ThreadFactoryBuilder;
4+
5+
import java.util.concurrent.ScheduledThreadPoolExecutor;
6+
7+
public class GlobalExecutors {
8+
9+
public static final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(
10+
1,
11+
new ThreadFactoryBuilder().setNameFormat("C2ME scheduler").setDaemon(true).setPriority(Thread.NORM_PRIORITY - 1).build()
12+
);
13+
14+
}

src/main/java/org/yatopiamc/c2me/common/threading/chunkio/C2MECachedRegionStorage.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.apache.logging.log4j.LogManager;
1717
import org.apache.logging.log4j.Logger;
1818
import org.jetbrains.annotations.Nullable;
19+
import org.yatopiamc.c2me.common.threading.GlobalExecutors;
1920
import org.yatopiamc.c2me.common.util.C2MEForkJoinWorkerThreadFactory;
2021
import org.yatopiamc.c2me.common.util.SneakyThrow;
2122

@@ -36,14 +37,10 @@ public class C2MECachedRegionStorage extends StorageIoWorker {
3637
private static final CompoundTag EMPTY_VALUE = new CompoundTag();
3738
private static final Logger LOGGER = LogManager.getLogger();
3839
private static final ForkJoinPool IOExecutor = new ForkJoinPool(
39-
Math.min(8, Runtime.getRuntime().availableProcessors()),
40+
Math.min(6, Runtime.getRuntime().availableProcessors()),
4041
new C2MEForkJoinWorkerThreadFactory("C2ME chunkio io worker #%d", Thread.NORM_PRIORITY - 3),
4142
null, true
4243
);
43-
private static final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(
44-
1,
45-
new ThreadFactoryBuilder().setNameFormat("C2ME chunkio scheduler").setDaemon(true).setPriority(Thread.NORM_PRIORITY - 1).build()
46-
);
4744

4845
private final RegionBasedStorage storage;
4946
private final Cache<ChunkPos, CompoundTag> chunkCache;
@@ -73,7 +70,7 @@ private void tick() {
7370
long startTime = System.currentTimeMillis();
7471
chunkCache.cleanUp();
7572
if (!isClosed.get())
76-
scheduler.schedule(this::tick, 1000 - (System.currentTimeMillis() - startTime), TimeUnit.MILLISECONDS);
73+
GlobalExecutors.scheduler.schedule(this::tick, 1000 - (System.currentTimeMillis() - startTime), TimeUnit.MILLISECONDS);
7774
}
7875

7976
private CompletableFuture<RegionFile> getRegionFile(ChunkPos pos) {
@@ -86,7 +83,7 @@ private CompletableFuture<RegionFile> getRegionFile(ChunkPos pos) {
8683
} finally {
8784
lockToken.releaseLock();
8885
}
89-
}, scheduler);
86+
}, GlobalExecutors.scheduler);
9087
}
9188

9289
private void scheduleWrite(ChunkPos pos, CompoundTag chunkData) {
@@ -164,7 +161,7 @@ public CompletableFuture<CompoundTag> getNbtAtAsync(ChunkPos pos) {
164161
} finally {
165162
lockToken.releaseLock();
166163
}
167-
}, scheduler);
164+
}, GlobalExecutors.scheduler);
168165
}
169166

170167
@Nullable

src/main/java/org/yatopiamc/c2me/common/threading/chunkio/ChunkIoThreadingExecutorUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
public class ChunkIoThreadingExecutorUtils {
88

99
public static final ForkJoinPool serializerExecutor = new ForkJoinPool(
10-
Math.min(6, Runtime.getRuntime().availableProcessors()),
10+
Math.min(2, Runtime.getRuntime().availableProcessors()),
1111
new C2MEForkJoinWorkerThreadFactory("C2ME chunkio serializer worker #%d", Thread.NORM_PRIORITY - 1),
1212
null,
1313
true

src/main/java/org/yatopiamc/c2me/common/threading/worldgen/ChunkStatusUtils.java

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
import com.ibm.asyncutil.locks.AsyncLock;
44
import com.ibm.asyncutil.locks.AsyncNamedLock;
5+
import com.ibm.asyncutil.util.Combinators;
56
import net.minecraft.util.math.ChunkPos;
67
import net.minecraft.world.chunk.ChunkStatus;
78
import org.jetbrains.annotations.NotNull;
9+
import org.yatopiamc.c2me.common.threading.GlobalExecutors;
810

911
import java.util.ArrayList;
1012
import java.util.List;
1113
import java.util.concurrent.CompletableFuture;
14+
import java.util.concurrent.CompletionStage;
1215
import java.util.function.Supplier;
1316

1417
public class ChunkStatusUtils {
@@ -32,25 +35,17 @@ public static ChunkStatusThreadingType getThreadingType(final ChunkStatus status
3235
}
3336
}
3437

35-
private static <T> CompletableFuture<T> buildChain0(@NotNull List<CompletableFuture<AsyncLock.LockToken>> list, int index, Supplier<CompletableFuture<T>> code) {
36-
if (index < list.size()) {
37-
return list.get(index).thenCompose(lockToken -> {
38-
final CompletableFuture<T> future = buildChain0(list, index + 1, code);
39-
future.thenRun(lockToken::releaseLock);
40-
return future;
41-
});
42-
} else {
43-
return code.get();
44-
}
45-
}
46-
4738
public static <T> CompletableFuture<T> runChunkGenWithLock(ChunkPos target, int radius, AsyncNamedLock<ChunkPos> chunkLock, Supplier<CompletableFuture<T>> action) {
48-
List<CompletableFuture<AsyncLock.LockToken>> acquiredLocks = new ArrayList<>((radius + 1) * (radius + 1));
39+
List<CompletionStage<AsyncLock.LockToken>> acquiredLocks = new ArrayList<>((radius + 1) * (radius + 1));
4940
for (int x = target.x - radius; x <= target.x + radius; x++)
5041
for (int z = target.z - radius; z <= target.z + radius; z++)
51-
acquiredLocks.add(chunkLock.acquireLock(new ChunkPos(x, z)).toCompletableFuture());
42+
acquiredLocks.add(chunkLock.acquireLock(new ChunkPos(x, z)));
5243

53-
return buildChain0(acquiredLocks, 0, action);
44+
return Combinators.collect(acquiredLocks).toCompletableFuture().thenComposeAsync(lockTokens -> {
45+
final CompletableFuture<T> future = action.get();
46+
future.thenRun(() -> lockTokens.forEach(AsyncLock.LockToken::releaseLock));
47+
return future;
48+
}, GlobalExecutors.scheduler);
5449
}
5550

5651
}

src/main/java/org/yatopiamc/c2me/common/threading/worldgen/WorldGenThreadingExecutorUtils.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,10 @@
1111
public class WorldGenThreadingExecutorUtils {
1212

1313
public static final ForkJoinPool mainExecutor = new ForkJoinPool(
14-
Math.min(8, Runtime.getRuntime().availableProcessors()),
14+
Math.min(6, Runtime.getRuntime().availableProcessors()),
1515
new C2MEForkJoinWorkerThreadFactory("C2ME worldgen worker #%d", Thread.NORM_PRIORITY - 1),
1616
null,
1717
true
1818
);
19-
public static final ThreadPoolExecutor scheduler = new ThreadPoolExecutor(
20-
1,
21-
1,
22-
0, TimeUnit.SECONDS,
23-
new LinkedBlockingQueue<>(),
24-
new ThreadFactoryBuilder().setNameFormat("C2ME worldgen scheduler").setDaemon(true).setPriority(Thread.NORM_PRIORITY).build()
25-
);
2619

2720
}

src/main/java/org/yatopiamc/c2me/mixin/threading/worldgen/MixinThreadedAnvilChunkStorage.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.spongepowered.asm.mixin.Dynamic;
66
import org.spongepowered.asm.mixin.Mixin;
77
import org.spongepowered.asm.mixin.Overwrite;
8+
import org.yatopiamc.c2me.common.threading.GlobalExecutors;
89
import org.yatopiamc.c2me.common.threading.worldgen.WorldGenThreadingExecutorUtils;
910

1011
@Mixin(ThreadedAnvilChunkStorage.class)
@@ -18,7 +19,7 @@ public class MixinThreadedAnvilChunkStorage {
1819
@Dynamic
1920
@Overwrite
2021
private void method_17259(ChunkHolder chunkHolder, Runnable runnable) { // synthetic method for worldGenExecutor scheduling
21-
WorldGenThreadingExecutorUtils.scheduler.execute(runnable);
22+
GlobalExecutors.scheduler.execute(runnable);
2223
}
2324

2425
}

0 commit comments

Comments
 (0)