From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Sun, 6 Apr 2025 18:03:38 +0300 Subject: [PATCH] Chunk System Optimizations diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java index 7fed43a1e7bcf35c4d7fd3224837a47fedd59860..353f1412b6edf481162ded50fa9a23d3442b9ed5 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java @@ -1,5 +1,7 @@ package ca.spottedleaf.moonrise.common.list; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntMaps; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import net.minecraft.world.entity.Entity; import java.util.Arrays; @@ -13,7 +15,7 @@ import java.util.NoSuchElementException; */ public final class EntityList implements Iterable { - private final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f); + private final Int2IntMap entityToIndex = Int2IntMaps.synchronize(new Int2IntOpenHashMap(2, 0.8f)); // DivineMC - Chunk System Optimizations { this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); } @@ -27,11 +29,11 @@ public final class EntityList implements Iterable { return this.count; } - public boolean contains(final Entity entity) { + public synchronized boolean contains(final Entity entity) { // DivineMC - Chunk System Optimizations return this.entityToIndex.containsKey(entity.getId()); } - public boolean remove(final Entity entity) { + public synchronized boolean remove(final Entity entity) { // DivineMC - Chunk System Optimizations final int index = this.entityToIndex.remove(entity.getId()); if (index == Integer.MIN_VALUE) { return false; @@ -50,7 +52,7 @@ public final class EntityList implements Iterable { return true; } - public boolean add(final Entity entity) { + public synchronized boolean add(final Entity entity) { // DivineMC - Chunk System Optimizations final int count = this.count; final int currIndex = this.entityToIndex.putIfAbsent(entity.getId(), count); @@ -82,18 +84,18 @@ public final class EntityList implements Iterable { return this.entities[index]; } - public Entity[] getRawData() { + public synchronized Entity[] getRawData() { // DivineMC - Chunk System Optimizations return this.entities; } - public void clear() { + public synchronized void clear() { // DivineMC - Chunk System Optimizations this.entityToIndex.clear(); Arrays.fill(this.entities, 0, this.count, null); this.count = 0; } @Override - public Iterator iterator() { + public synchronized Iterator iterator() { // DivineMC - Chunk System Optimizations return new Iterator<>() { private Entity lastRet; private int current; diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java index 2e876b918672e8ef3b5197b7e6b1597247fdeaa1..aab585e226e0928d778dc83a33bdcaf5f5a6f213 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ReferenceList.java @@ -1,142 +1,26 @@ package ca.spottedleaf.moonrise.common.list; -import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; -import java.util.Arrays; -import java.util.Iterator; -import java.util.NoSuchElementException; +// DivineMC start - Chunk System Optimizations - rewrite +import it.unimi.dsi.fastutil.objects.ReferenceArrayList; +import it.unimi.dsi.fastutil.objects.ReferenceLists; -public final class ReferenceList implements Iterable { - - private static final Object[] EMPTY_LIST = new Object[0]; - - private final Reference2IntOpenHashMap referenceToIndex; - private E[] references; - private int count; - - public ReferenceList() { - this((E[])EMPTY_LIST); - } - - public ReferenceList(final E[] referenceArray) { - this.references = referenceArray; - this.referenceToIndex = new Reference2IntOpenHashMap<>(2, 0.8f); - this.referenceToIndex.defaultReturnValue(Integer.MIN_VALUE); - } - - private ReferenceList(final E[] references, final int count, final Reference2IntOpenHashMap referenceToIndex) { - this.references = references; - this.count = count; - this.referenceToIndex = referenceToIndex; - } - - public ReferenceList copy() { - return new ReferenceList<>(this.references.clone(), this.count, this.referenceToIndex.clone()); - } - - public int size() { - return this.count; - } - - public boolean contains(final E obj) { - return this.referenceToIndex.containsKey(obj); +public class ReferenceList extends ReferenceLists.SynchronizedList { + public ReferenceList(E[] elements) { + super(new RefListInner<>(elements)); } - public boolean remove(final E obj) { - final int index = this.referenceToIndex.removeInt(obj); - if (index == Integer.MIN_VALUE) { - return false; - } - - // move the object at the end to this index - final int endIndex = --this.count; - final E end = (E)this.references[endIndex]; - if (index != endIndex) { - // not empty after this call - this.referenceToIndex.put(end, index); // update index - } - this.references[index] = end; - this.references[endIndex] = null; - - return true; + public synchronized E[] getRawDataUnchecked() { + return ((RefListInner) this.list).getRawDataUnchecked(); } - public boolean add(final E obj) { - final int count = this.count; - final int currIndex = this.referenceToIndex.putIfAbsent(obj, count); - - if (currIndex != Integer.MIN_VALUE) { - return false; // already in this list + public static class RefListInner extends ReferenceArrayList { + public RefListInner(A[] elements) { + super(elements, true); } - E[] list = this.references; - - if (list.length == count) { - // resize required - list = this.references = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative + public A[] getRawDataUnchecked() { + return this.a; } - - list[count] = obj; - this.count = count + 1; - - return true; - } - - public E getChecked(final int index) { - if (index < 0 || index >= this.count) { - throw new IndexOutOfBoundsException("Index: " + index + " is out of bounds, size: " + this.count); - } - return this.references[index]; - } - - public E getUnchecked(final int index) { - return this.references[index]; - } - - public Object[] getRawData() { - return this.references; - } - - public E[] getRawDataUnchecked() { - return this.references; - } - - public void clear() { - this.referenceToIndex.clear(); - Arrays.fill(this.references, 0, this.count, null); - this.count = 0; - } - - @Override - public Iterator iterator() { - return new Iterator<>() { - private E lastRet; - private int current; - - @Override - public boolean hasNext() { - return this.current < ReferenceList.this.count; - } - - @Override - public E next() { - if (this.current >= ReferenceList.this.count) { - throw new NoSuchElementException(); - } - return this.lastRet = ReferenceList.this.references[this.current++]; - } - - @Override - public void remove() { - final E lastRet = this.lastRet; - - if (lastRet == null) { - throw new IllegalStateException(); - } - this.lastRet = null; - - ReferenceList.this.remove(lastRet); - --this.current; - } - }; } } +// DivineMC end - Chunk System Optimizations - rewrite diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java index 2bae9949ef325d0001aa638150fbbdf968367e75..11bf4ddb298bb39f7f39a9c33c90b48a3171266b 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java @@ -1,11 +1,13 @@ package ca.spottedleaf.moonrise.common.list; +import it.unimi.dsi.fastutil.shorts.Short2ShortMap; +import it.unimi.dsi.fastutil.shorts.Short2ShortMaps; import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; import java.util.Arrays; public final class ShortList { - private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap(); + private final Short2ShortMap map = Short2ShortMaps.synchronize(new Short2ShortOpenHashMap()); // DivineMC - Chunk System Optimizations { this.map.defaultReturnValue(Short.MIN_VALUE); } @@ -13,13 +15,13 @@ public final class ShortList { private static final short[] EMPTY_LIST = new short[0]; private short[] byIndex = EMPTY_LIST; - private short count; + private volatile short count; // DivineMC - Chunk System Optimizations public int size() { - return (int)this.count; + return this.count; // DivineMC - Chunk System Optimizations } - public short getRaw(final int index) { + public synchronized short getRaw(final int index) { // DivineMC - Chunk System Optimizations return this.byIndex[index]; } @@ -30,8 +32,8 @@ public final class ShortList { } } - public boolean add(final short value) { - final int count = (int)this.count; + public synchronized boolean add(final short value) { // DivineMC - Chunk System Optimizations + final int count = this.count; // DivineMC - Chunk System Optimizations final short currIndex = this.map.putIfAbsent(value, (short)count); if (currIndex != Short.MIN_VALUE) { @@ -51,7 +53,7 @@ public final class ShortList { return true; } - public boolean remove(final short value) { + public synchronized boolean remove(final short value) { // DivineMC - Chunk System Optimizations final short index = this.map.remove(value); if (index == Short.MIN_VALUE) { return false; @@ -70,7 +72,7 @@ public final class ShortList { return true; } - public void clear() { + public synchronized void clear() { // DivineMC - Chunk System Optimizations this.count = (short)0; this.map.clear(); } diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java index 460e27ab0506c83a28934800ee74ee886d4b025e..49e53bf85352f4d1b9997fa3c30e37e40c0ff01c 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed26WayDistancePropagator3D.java @@ -15,7 +15,7 @@ public final class Delayed26WayDistancePropagator3D { // Generally updates to positions are made close to other updates, so we link to decrease cache misses when // propagating updates - protected final LongLinkedOpenHashSet updatedSources = new LongLinkedOpenHashSet(); + protected final it.unimi.dsi.fastutil.longs.LongSet updatedSources = it.unimi.dsi.fastutil.longs.LongSets.synchronize(new LongLinkedOpenHashSet()); // DivineMC - Chunk System Optimizations @FunctionalInterface public static interface LevelChangeCallback { @@ -94,29 +94,29 @@ public final class Delayed26WayDistancePropagator3D { protected final void addToIncreaseWorkQueue(final long coordinate, final byte level) { final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[level]; - queue.queuedCoordinates.enqueue(coordinate); - queue.queuedLevels.enqueue(level); + queue.queuedCoordinates.add(coordinate); // DivineMC - Chunk System Optimizations + queue.queuedLevels.add(level); // DivineMC - Chunk System Optimizations this.levelIncreaseWorkQueueBitset |= (1L << level); } protected final void addToIncreaseWorkQueue(final long coordinate, final byte index, final byte level) { final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[index]; - queue.queuedCoordinates.enqueue(coordinate); - queue.queuedLevels.enqueue(level); + queue.queuedCoordinates.add(coordinate); // DivineMC - Chunk System Optimizations + queue.queuedLevels.add(level); // DivineMC - Chunk System Optimizations this.levelIncreaseWorkQueueBitset |= (1L << index); } protected final void addToRemoveWorkQueue(final long coordinate, final byte level) { final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelRemoveWorkQueues[level]; - queue.queuedCoordinates.enqueue(coordinate); - queue.queuedLevels.enqueue(level); + queue.queuedCoordinates.add(coordinate); // DivineMC - Chunk System Optimizations + queue.queuedLevels.add(level); // DivineMC - Chunk System Optimizations this.levelRemoveWorkQueueBitset |= (1L << level); } - public boolean propagateUpdates() { + public synchronized boolean propagateUpdates() { // DivineMC - Chunk System Optimizations if (this.updatedSources.isEmpty()) { return false; } @@ -157,15 +157,15 @@ public final class Delayed26WayDistancePropagator3D { return ret; } - protected void propagateIncreases() { + protected synchronized void propagateIncreases() { // DivineMC - Chunk System Optimizations for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset); this.levelIncreaseWorkQueueBitset != 0L; this.levelIncreaseWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelIncreaseWorkQueueBitset)) { final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelIncreaseWorkQueues[queueIndex]; while (!queue.queuedLevels.isEmpty()) { - final long coordinate = queue.queuedCoordinates.removeFirstLong(); - byte level = queue.queuedLevels.removeFirstByte(); + final long coordinate = queue.queuedCoordinates.removeFirst(); // DivineMC - Chunk System Optimizations + byte level = queue.queuedLevels.removeFirst(); // DivineMC - Chunk System Optimizations final boolean neighbourCheck = level < 0; @@ -226,15 +226,15 @@ public final class Delayed26WayDistancePropagator3D { } } - protected void propagateDecreases() { + protected synchronized void propagateDecreases() { // DivineMC - Chunk System Optimizations for (int queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset); this.levelRemoveWorkQueueBitset != 0L; this.levelRemoveWorkQueueBitset ^= (1L << queueIndex), queueIndex = 63 ^ Long.numberOfLeadingZeros(this.levelRemoveWorkQueueBitset)) { final Delayed8WayDistancePropagator2D.WorkQueue queue = this.levelRemoveWorkQueues[queueIndex]; while (!queue.queuedLevels.isEmpty()) { - final long coordinate = queue.queuedCoordinates.removeFirstLong(); - final byte level = queue.queuedLevels.removeFirstByte(); + final long coordinate = queue.queuedCoordinates.removeFirst(); // DivineMC - Chunk System Optimizations + final byte level = queue.queuedLevels.removeFirst(); // DivineMC - Chunk System Optimizations final byte currentLevel = this.levels.removeIfGreaterOrEqual(coordinate, level); if (currentLevel == 0) { diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java index ab2fa1563d5e32a5313dfcc1da411cab45fb5ca0..1bababc2515d8c805e4ee0c943065f451a38b7b8 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/Delayed8WayDistancePropagator2D.java @@ -356,24 +356,24 @@ public final class Delayed8WayDistancePropagator2D { protected final void addToIncreaseWorkQueue(final long coordinate, final byte level) { final WorkQueue queue = this.levelIncreaseWorkQueues[level]; - queue.queuedCoordinates.enqueue(coordinate); - queue.queuedLevels.enqueue(level); + queue.queuedCoordinates.add(coordinate); // DivineMC - Chunk System Optimizations + queue.queuedLevels.add(level); // DivineMC - Chunk System Optimizations this.levelIncreaseWorkQueueBitset |= (1L << level); } protected final void addToIncreaseWorkQueue(final long coordinate, final byte index, final byte level) { final WorkQueue queue = this.levelIncreaseWorkQueues[index]; - queue.queuedCoordinates.enqueue(coordinate); - queue.queuedLevels.enqueue(level); + queue.queuedCoordinates.add(coordinate); // DivineMC - Chunk System Optimizations + queue.queuedLevels.add(level); // DivineMC - Chunk System Optimizations this.levelIncreaseWorkQueueBitset |= (1L << index); } protected final void addToRemoveWorkQueue(final long coordinate, final byte level) { final WorkQueue queue = this.levelRemoveWorkQueues[level]; - queue.queuedCoordinates.enqueue(coordinate); - queue.queuedLevels.enqueue(level); + queue.queuedCoordinates.add(coordinate); // DivineMC - Chunk System Optimizations + queue.queuedLevels.add(level); // DivineMC - Chunk System Optimizations this.levelRemoveWorkQueueBitset |= (1L << level); } @@ -426,8 +426,8 @@ public final class Delayed8WayDistancePropagator2D { final WorkQueue queue = this.levelIncreaseWorkQueues[queueIndex]; while (!queue.queuedLevels.isEmpty()) { - final long coordinate = queue.queuedCoordinates.removeFirstLong(); - byte level = queue.queuedLevels.removeFirstByte(); + final long coordinate = queue.queuedCoordinates.removeFirst(); // DivineMC - Chunk System Optimizations + byte level = queue.queuedLevels.removeFirst(); // DivineMC - Chunk System Optimizations final boolean neighbourCheck = level < 0; @@ -492,8 +492,8 @@ public final class Delayed8WayDistancePropagator2D { final WorkQueue queue = this.levelRemoveWorkQueues[queueIndex]; while (!queue.queuedLevels.isEmpty()) { - final long coordinate = queue.queuedCoordinates.removeFirstLong(); - final byte level = queue.queuedLevels.removeFirstByte(); + final long coordinate = queue.queuedCoordinates.removeFirst(); // DivineMC - Chunk System Optimizations + final byte level = queue.queuedLevels.removeFirst(); // DivineMC - Chunk System Optimizations final byte currentLevel = this.levels.removeIfGreaterOrEqual(coordinate, level); if (currentLevel == 0) { @@ -561,7 +561,7 @@ public final class Delayed8WayDistancePropagator2D { } // copied from superclass - private int find(final long k) { + private synchronized int find(final long k) { // DivineMC - Chunk System Optimizations if (k == 0L) { return this.containsNullKey ? this.n : -(this.n + 1); } else { @@ -585,7 +585,7 @@ public final class Delayed8WayDistancePropagator2D { } // copied from superclass - private void insert(final int pos, final long k, final byte v) { + private synchronized void insert(final int pos, final long k, final byte v) { // DivineMC - Chunk System Optimizations if (pos == this.n) { this.containsNullKey = true; } @@ -598,7 +598,7 @@ public final class Delayed8WayDistancePropagator2D { } // copied from superclass - public byte putIfGreater(final long key, final byte value) { + public synchronized byte putIfGreater(final long key, final byte value) { // DivineMC - Chunk System Optimizations final int pos = this.find(key); if (pos < 0) { if (this.defRetValue < value) { @@ -616,7 +616,7 @@ public final class Delayed8WayDistancePropagator2D { } // copied from superclass - private void removeEntry(final int pos) { + private synchronized void removeEntry(final int pos) { // DivineMC - Chunk System Optimizations --this.size; this.shiftKeys(pos); if (this.n > this.minN && this.size < this.maxFill / 4 && this.n > 16) { @@ -625,7 +625,7 @@ public final class Delayed8WayDistancePropagator2D { } // copied from superclass - private void removeNullEntry() { + private synchronized void removeNullEntry() { // DivineMC - Chunk System Optimizations this.containsNullKey = false; --this.size; if (this.n > this.minN && this.size < this.maxFill / 4 && this.n > 16) { @@ -634,7 +634,7 @@ public final class Delayed8WayDistancePropagator2D { } // copied from superclass - public byte removeIfGreaterOrEqual(final long key, final byte value) { + public synchronized byte removeIfGreaterOrEqual(final long key, final byte value) { // DivineMC - Chunk System Optimizations if (key == 0L) { if (!this.containsNullKey) { return this.defRetValue; @@ -679,8 +679,8 @@ public final class Delayed8WayDistancePropagator2D { protected static final class WorkQueue { - public final NoResizeLongArrayFIFODeque queuedCoordinates = new NoResizeLongArrayFIFODeque(); - public final NoResizeByteArrayFIFODeque queuedLevels = new NoResizeByteArrayFIFODeque(); + public final java.util.concurrent.ConcurrentLinkedDeque queuedCoordinates = new java.util.concurrent.ConcurrentLinkedDeque<>(); + public final java.util.concurrent.ConcurrentLinkedDeque queuedLevels = new java.util.concurrent.ConcurrentLinkedDeque<>(); } diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java index 632920e04686d8a0fd0a60e87348be1fe7862a3c..f10c6c156b8dd9acecc8b1ee81bd28260fb6e4d8 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java @@ -3,6 +3,12 @@ package ca.spottedleaf.moonrise.common.util; import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; import ca.spottedleaf.moonrise.common.PlatformHooks; import com.mojang.logging.LogUtils; +import org.bxteam.divinemc.DivineConfig; +import org.bxteam.divinemc.server.chunk.ChunkSystemAlgorithms; +import org.bxteam.divinemc.server.chunk.TheChunkSystem; +import org.bxteam.divinemc.spark.ThreadDumperRegistry; +import org.bxteam.divinemc.util.ThreadBuilder; +import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -12,83 +18,63 @@ public final class MoonriseCommon { private static final Logger LOGGER = LogUtils.getClassLogger(); - public static final PrioritisedThreadPool WORKER_POOL = new PrioritisedThreadPool( - new Consumer<>() { - private final AtomicInteger idGenerator = new AtomicInteger(); + public static TheChunkSystem WORKER_POOL; + public static TheChunkSystem.ExecutorGroup PARALLEL_GEN_GROUP; + public static TheChunkSystem.ExecutorGroup RADIUS_AWARE_GROUP; + public static TheChunkSystem.ExecutorGroup LOAD_GROUP; - @Override - public void accept(Thread thread) { - thread.setDaemon(true); - thread.setName(PlatformHooks.get().getBrand() + " Common Worker #" + this.idGenerator.getAndIncrement()); - thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(final Thread thread, final Throwable throwable) { - LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); - } - }); - } - } - ); - public static final long WORKER_QUEUE_HOLD_TIME = (long)(20.0e6); // 20ms - public static final int CLIENT_DIVISION = 0; - public static final PrioritisedThreadPool.ExecutorGroup RENDER_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0); - public static final int SERVER_DIVISION = 1; - public static final PrioritisedThreadPool.ExecutorGroup PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); - public static final PrioritisedThreadPool.ExecutorGroup RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); - public static final PrioritisedThreadPool.ExecutorGroup LOAD_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); - - public static void adjustWorkerThreads(final int configWorkerThreads, final int configIoThreads) { - int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2; - if (defaultWorkerThreads <= 4) { - defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2; - } else { - defaultWorkerThreads = defaultWorkerThreads / 2; - } - defaultWorkerThreads = Integer.getInteger(PlatformHooks.get().getBrand() + ".WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); - - int workerThreads = configWorkerThreads; + public static void init(final int configWorkerThreads, final int configIoThreads) { + ChunkSystemAlgorithms algorithm = DivineConfig.chunkWorkerAlgorithm; + int workerThreads = algorithm.evalWorkers(configWorkerThreads, configIoThreads); + int ioThreads = algorithm.evalIO(configWorkerThreads, configIoThreads); - if (workerThreads <= 0) { - workerThreads = defaultWorkerThreads; - } + WORKER_POOL = buildChunkSystem(workerThreads); - final int ioThreads = Math.max(1, configIoThreads); + PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(); + RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(); + LOAD_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(); - WORKER_POOL.adjustThreadCount(workerThreads); IO_POOL.adjustThreadCount(ioThreads); + LOGGER.info("Running ChunkSystem with {} worker threads and {} I/O threads", workerThreads, ioThreads); + } - LOGGER.info(PlatformHooks.get().getBrand() + " is using " + workerThreads + " worker threads, " + ioThreads + " I/O threads"); + private static @NotNull TheChunkSystem buildChunkSystem(int workerThreads) { + return new TheChunkSystem(workerThreads, new ThreadBuilder() { + @Override + public void accept(final Thread thread) { + thread.setPriority(DivineConfig.threadPoolPriority); + thread.setDaemon(true); + thread.setUncaughtExceptionHandler((thread1, throwable) -> LOGGER.error("Uncaught exception in thread {}", thread1.getName(), throwable)); + thread.setName("World Gen Worker #" + getAndIncrementId()); + ThreadDumperRegistry.REGISTRY.add(thread.getName()); + } + }); } public static final PrioritisedThreadPool IO_POOL = new PrioritisedThreadPool( - new Consumer<>() { - private final AtomicInteger idGenerator = new AtomicInteger(); - - @Override - public void accept(final Thread thread) { - thread.setDaemon(true); - thread.setName(PlatformHooks.get().getBrand() + " I/O Worker #" + this.idGenerator.getAndIncrement()); - thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(final Thread thread, final Throwable throwable) { - LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable); - } - }); - } + new Consumer<>() { + private final AtomicInteger idGenerator = new AtomicInteger(); + + @Override + public void accept(final Thread thread) { + thread.setDaemon(true); + thread.setName(PlatformHooks.get().getBrand() + " I/O Worker #" + this.idGenerator.getAndIncrement()); + ThreadDumperRegistry.REGISTRY.add(thread.getName()); + thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(final Thread thread, final Throwable throwable) { + LOGGER.error("Uncaught exception in thread {}", thread.getName(), throwable); + } + }); } + } ); public static final long IO_QUEUE_HOLD_TIME = (long)(100.0e6); // 100ms - public static final PrioritisedThreadPool.ExecutorGroup CLIENT_PROFILER_IO_GROUP = IO_POOL.createExecutorGroup(CLIENT_DIVISION, 0); - public static final PrioritisedThreadPool.ExecutorGroup SERVER_REGION_IO_GROUP = IO_POOL.createExecutorGroup(SERVER_DIVISION, 0); + public static final PrioritisedThreadPool.ExecutorGroup SERVER_REGION_IO_GROUP = IO_POOL.createExecutorGroup(1, 0); public static void haltExecutors() { - MoonriseCommon.WORKER_POOL.shutdown(false); - LOGGER.info("Awaiting termination of worker pool for up to 60s..."); - if (!MoonriseCommon.WORKER_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { - LOGGER.error("Worker pool did not shut down in time!"); - MoonriseCommon.WORKER_POOL.halt(false); - } - + LOGGER.info("Shutting down ChunkSystem..."); + MoonriseCommon.WORKER_POOL.shutdown(); MoonriseCommon.IO_POOL.shutdown(false); LOGGER.info("Awaiting termination of I/O pool for up to 60s..."); if (!MoonriseCommon.IO_POOL.join(TimeUnit.SECONDS.toMillis(60L))) { diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java index 559c959aff3c9deef867b9e425fba3e2e669cac6..a5b0585b56d71d21c9da3b129d213def142bb1f6 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java @@ -4,7 +4,7 @@ import ca.spottedleaf.moonrise.common.PlatformHooks; public final class MoonriseConstants { - public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32); + public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", org.bxteam.divinemc.DivineConfig.maxViewDistance); // DivineMC - Configurable view distance private MoonriseConstants() {} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java index c2b53adb5f0fd8207cf13cb6f7249385b1c30f34..83419bbcbf79d8eed1302d66356a62fa61a33473 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -227,7 +227,7 @@ public class GlobalConfiguration extends ConfigurationPart { @PostProcess private void postProcess() { - ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads); + ca.spottedleaf.moonrise.common.util.MoonriseCommon.init(this.workerThreads, this.ioThreads); String newChunkSystemGenParallelism = this.genParallelism; if (newChunkSystemGenParallelism.equalsIgnoreCase("default")) { newChunkSystemGenParallelism = "true"; @@ -243,7 +243,6 @@ public class GlobalConfiguration extends ConfigurationPart { } else { throw new IllegalStateException("Invalid option for gen-parallelism: must be one of [on, off, enabled, disabled, true, false, default]"); } - FeatureHooks.initChunkTaskScheduler(useParallelGen); } }