Skip to content

Commit

Permalink
- 修复偶然性的死锁问题。
Browse files Browse the repository at this point in the history
  • Loading branch information
KasumiNova committed Oct 9, 2024
1 parent ced5fb0 commit 4e5d7cf
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 113 deletions.
132 changes: 38 additions & 94 deletions src/main/java/github/kasuminova/stellarcore/common/mod/Mods.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,118 +4,62 @@

public enum Mods {

FTBLIB("ftblib"),
FTBQ( "ftbquests"),
MEK( "mekanism"),
MEKCEU("mekanism") {
FTBLIB( "ftblib"),
FTBQ( "ftbquests"),
MEK( "mekanism"),
REPLAY( "replaymod"),
VINTAGE_FIX( "vintagefix"),
RGB_CHAT( "jianghun"), // ?
TLM( "touhou_little_maid"),
MM( "modularmachinery"),
EBWIZARDRY( "ebwizardry"),
LIB_NINE( "libnine"),
MMCE( "modularmachinery", "github.kasuminova.mmce.mixin.MMCEEarlyMixinLoader"),
CENSORED_ASM( "loliasm", "zone.rong.loliasm.core.LoliLoadingPlugin"),
FERMIUM_OR_BLAHAJ_ASM("normalasm", "mirror.normalasm.core.NormalLoadingPlugin"),
TICK_CENTRAL( "tickcentral", "com.github.terminatornl.tickcentral.TickCentral"),
MEKCEU( "mekanism", "mekanism.common.concurrent.TaskExecutor") {
@Override
public boolean loaded() {
if (!MEK.loaded()) {
return false;
}
if (initialized) {
return loaded;
}

try {
Class.forName("mekanism.common.config.MEKCEConfig");
initialized = true;
return loaded = true;
} catch (Throwable e) {
return loaded = false;
}
return super.loaded();
}
},
MM("modularmachinery"),
MMCE("modularmachinery") {
@Override
public boolean loaded() {
if (!MM.loaded()) {
return false;
}
if (initialized) {
return loaded;
}
;

try {
Class.forName("github.kasuminova.mmce.mixin.MMCEEarlyMixinLoader");
initialized = true;
return loaded = true;
} catch (Throwable e) {
return loaded = false;
}
}
},
REPLAY("replaymod"),
VINTAGE_FIX("vintagefix"),
RGB_CHAT("jianghun"), // ?
TLM("touhou_little_maid"),
CENSORED_ASM("loliasm") {
@Override
public boolean loaded() {
if (initialized) {
return loaded;
}
final String modID;
final String requiredClass;
boolean loaded = false;
boolean initialized = false;

try {
Class.forName("zone.rong.loliasm.core.LoliLoadingPlugin");
initialized = true;
return loaded = true;
} catch (Throwable e) {
return loaded = false;
}
}
},
FERMIUM_OR_BLAHAJ_ASM("normalasm") {
@Override
public boolean loaded() {
if (initialized) {
return loaded;
}
Mods(final String modID) {
this.modID = modID;
this.requiredClass = null;
}

try {
Class.forName("mirror.normalasm.core.NormalLoadingPlugin");
initialized = true;
return loaded = true;
} catch (Throwable e) {
return loaded = false;
}
Mods(final String modID, final String requiredClass) {
this.modID = modID;
this.requiredClass = requiredClass;
}

public boolean loaded() {
if (initialized) {
return loaded;
}
},
EBWIZARDRY("ebwizardry"),
TICK_CENTRAL("tickcentral") {
@Override
public boolean loaded() {
if (initialized) {
return loaded;
}

initialized = true;

if (requiredClass != null) {
try {
Class.forName("com.github.terminatornl.tickcentral.TickCentral");
initialized = true;
Class.forName(requiredClass);
return loaded = true;
} catch (Throwable e) {
return loaded = false;
}
}
},
LIB_NINE("libnine"),
;

protected final String modID;
protected boolean loaded = false;
protected boolean initialized = false;

Mods(final String modID) {
this.modID = modID;
}

public boolean loaded() {
if (!initialized) {
loaded = Loader.isModLoaded(modID);
initialized = true;
}
return loaded;
return loaded = Loader.isModLoaded(modID);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import github.kasuminova.stellarcore.common.util.StellarLog;
import github.kasuminova.stellarcore.mixin.util.IC2EnergySyncCalcTask;
import github.kasuminova.stellarcore.mixin.util.IStellarEnergyCalculatorLeg;
import github.kasuminova.stellarcore.shaded.org.jctools.queues.MpmcArrayQueue;
import github.kasuminova.stellarcore.shaded.org.jctools.queues.atomic.MpscLinkedAtomicQueue;
import github.kasuminova.stellarcore.shaded.org.jctools.queues.MpscUnboundedXaddArrayQueue;
import github.kasuminova.stellarcore.shaded.org.jctools.queues.atomic.MpmcAtomicArrayQueue;
import ic2.core.energy.grid.EnergyNetGlobal;
import ic2.core.energy.grid.EnergyNetLocal;
import ic2.core.energy.grid.Grid;
Expand All @@ -26,6 +26,7 @@
import java.util.Collection;
import java.util.Queue;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.IntStream;

@SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter", "unchecked"})
Expand Down Expand Up @@ -82,14 +83,13 @@ void startTransferCalc(final CallbackInfo ci) {
}

this.busy = true;
Collection<Grid> grids = stellar_core$EnergyNetLocal$getGrids(enet);

IStellarEnergyCalculatorLeg stellarCalculator = (IStellarEnergyCalculatorLeg) energyCalculator;

Queue<Grid> calculateQueue = stellar_core$createMpmcQueue(grids.size());
final Collection<Grid> grids = stellar_core$EnergyNetLocal$getGrids(enet);
final IStellarEnergyCalculatorLeg stellarCalculator = (IStellarEnergyCalculatorLeg) energyCalculator;
final Queue<Grid> calculateQueue = stellar_core$createMpmcQueue(grids.size());
calculateQueue.addAll(grids);
int tasks = grids.size();
ForkJoinPool.commonPool().submit(() -> {
final int tasks = grids.size();
final ForkJoinTask<?> future = ForkJoinPool.commonPool().submit(() -> {
int concurrency = Math.min(tasks, Math.max(StellarEnvironment.getConcurrency(), 2));
IntStream.range(0, concurrency).parallel().forEach(i -> {
Grid grid;
Expand All @@ -99,13 +99,7 @@ void startTransferCalc(final CallbackInfo ci) {
});
});

stellar_core$executeSyncTasks(tasks, stellarCalculator, calculateQueue);

if (!stellar_core$syncTaskQueue.isEmpty()) {
StellarLog.LOG.warn("[StellarCore-IC2GridUpdater] Unable to complete all tasks, {} tasks left.", stellar_core$syncTaskQueue.size());
stellar_core$syncTaskQueue.forEach(stellarCalculator::doSyncCalc);
stellar_core$syncTaskQueue.clear();
}
stellar_core$executeSyncTasks(tasks, stellarCalculator, calculateQueue, future);

// TODO why shuffle?
// if (grids.size() > 1) {
Expand All @@ -116,11 +110,11 @@ void startTransferCalc(final CallbackInfo ci) {
}

@Unique
private void stellar_core$executeSyncTasks(final int totalTasks, final IStellarEnergyCalculatorLeg stellarCalculator, final Queue<Grid> calculateQueue) {
private void stellar_core$executeSyncTasks(final int totalTasks, final IStellarEnergyCalculatorLeg stellarCalculator, final Queue<Grid> calculateQueue, final ForkJoinTask<?> parallelFuture) {
int completedTask = 0;
IC2EnergySyncCalcTask task;
boolean syncBusy;
while (completedTask < totalTasks) {
while (!parallelFuture.isDone()) {
syncBusy = true;

while ((task = stellar_core$syncTaskQueue.poll()) != null) {
Expand All @@ -138,6 +132,18 @@ void startTransferCalc(final CallbackInfo ci) {
stellar_core$awaitCompletion();
}
}

while (stellar_core$helpComplete(stellarCalculator, calculateQueue)) {
completedTask++;
}
while ((task = stellar_core$syncTaskQueue.poll()) != null) {
stellarCalculator.doSyncCalc(task);
completedTask++;
}

if (completedTask < totalTasks) {
StellarLog.LOG.warn("[StellarCore-IC2GridUpdater] Unable to complete all tasks, {} tasks left.", totalTasks - completedTask);
}
}

@Unique
Expand Down Expand Up @@ -284,12 +290,12 @@ void startTransferCalc(final CallbackInfo ci) {

@Unique
private static <E> Queue<E> stellar_core$createMpscQueue() {
return new MpscLinkedAtomicQueue<>();
return new MpscUnboundedXaddArrayQueue<>(1000);
}

@Unique
private static <E> Queue<E> stellar_core$createMpmcQueue(final int capacity) {
return new MpmcArrayQueue<>(Math.max(capacity, 2));
return new MpmcAtomicArrayQueue<>(Math.max(capacity, 2));
}

}

0 comments on commit 4e5d7cf

Please sign in to comment.