From 73360bb66c6de11d71afa3076bdddda5100ce3db Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sun, 13 Dec 2020 09:37:58 -0500 Subject: [PATCH] Fix parallax deadlocking --- .../com/volmit/iris/generator/IrisEngine.java | 19 +------- .../iris/generator/IrisEngineFramework.java | 45 ++++++++++++++++++- .../iris/scaffold/engine/EngineFramework.java | 12 +---- .../scaffold/hunk/io/HunkRegionSlice.java | 6 +-- .../scaffold/parallax/ParallaxRegion.java | 6 +-- .../iris/scaffold/parallax/ParallaxWorld.java | 25 +++++------ 6 files changed, 65 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/volmit/iris/generator/IrisEngine.java b/src/main/java/com/volmit/iris/generator/IrisEngine.java index dcb0195e3..b947c4e50 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngine.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngine.java @@ -3,8 +3,6 @@ package com.volmit.iris.generator; import com.volmit.iris.Iris; import com.volmit.iris.scaffold.engine.*; import com.volmit.iris.scaffold.hunk.Hunk; -import com.volmit.iris.scaffold.parallel.MultiBurst; -import com.volmit.iris.util.ChronoLatch; import com.volmit.iris.util.J; import com.volmit.iris.util.PrecisionStopwatch; import com.volmit.iris.util.RNG; @@ -52,7 +50,6 @@ public class IrisEngine extends BlockPopulator implements Engine private volatile int minHeight; private int permits; private boolean failing; - private ChronoLatch cl = new ChronoLatch(10000); private boolean closed; private int cacheId; private Semaphore s; @@ -62,7 +59,7 @@ public class IrisEngine extends BlockPopulator implements Engine { Iris.info("Initializing Engine: " + target.getWorld().getName() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)"); metrics = new EngineMetrics(32); - permits = 1000; + permits = 10000; this.s = new Semaphore(permits); this.target = target; this.framework = new IrisEngineFramework(this); @@ -127,19 +124,7 @@ public class IrisEngine extends BlockPopulator implements Engine getFramework().getEngineParallax().insertParallax(x, z, fringe); getMetrics().getTotal().put(p.getMilliseconds()); s.release(1); - - if(cl.flip()) - { - MultiBurst.burst.lazy(() -> { - try { - s.acquire(permits); - getFramework().recycle(); - s.release(permits); - } catch (InterruptedException e) { - e.printStackTrace(); - } - }); - } + getFramework().recycle(); } catch(Throwable e) diff --git a/src/main/java/com/volmit/iris/generator/IrisEngineFramework.java b/src/main/java/com/volmit/iris/generator/IrisEngineFramework.java index 2281abb5d..2c015e34e 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngineFramework.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngineFramework.java @@ -1,15 +1,22 @@ package com.volmit.iris.generator; -import com.volmit.iris.generator.actuator.*; +import com.volmit.iris.Iris; +import com.volmit.iris.IrisSettings; +import com.volmit.iris.generator.actuator.IrisBiomeActuator; +import com.volmit.iris.generator.actuator.IrisDecorantActuator; +import com.volmit.iris.generator.actuator.IrisTerrainActuator; import com.volmit.iris.generator.modifier.IrisCaveModifier; import com.volmit.iris.generator.modifier.IrisDepositModifier; import com.volmit.iris.generator.modifier.IrisPostModifier; import com.volmit.iris.generator.modifier.IrisRavineModifier; import com.volmit.iris.scaffold.engine.*; +import com.volmit.iris.util.ChronoLatch; import lombok.Getter; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; +import java.util.concurrent.atomic.AtomicBoolean; + public class IrisEngineFramework implements EngineFramework { @Getter @@ -42,6 +49,9 @@ public class IrisEngineFramework implements EngineFramework { @Getter private final EngineModifier postModifier; + private final AtomicBoolean cleaning; + private final ChronoLatch cleanLatch; + public IrisEngineFramework(Engine engine) { this.engine = engine; @@ -54,6 +64,39 @@ public class IrisEngineFramework implements EngineFramework { this.ravineModifier = new IrisRavineModifier(getEngine()); this.caveModifier = new IrisCaveModifier(engine); this.postModifier = new IrisPostModifier(engine); + cleaning = new AtomicBoolean(false); + cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().parallaxChunkEvictionMS, IrisSettings.get().parallaxRegionEvictionMS))); + } + + @Override + public synchronized void recycle() { + if(!cleanLatch.flip()) + { + return; + } + + if (cleaning.get()) + { + cleanLatch.flipDown(); + return; + } + + cleaning.set(true); + + try + { + getEngine().getParallax().cleanup(); + getData().getObjectLoader().clean(); + Iris.verbose("Ran Cleanup"); + } + + catch(Throwable e) + { + Iris.error("Cleanup failed!"); + e.printStackTrace(); + } + + cleaning.lazySet(false); } @Override diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineFramework.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineFramework.java index 97f3288ef..71b3b7e97 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineFramework.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineFramework.java @@ -3,7 +3,6 @@ package com.volmit.iris.scaffold.engine; import com.volmit.iris.generator.IrisComplex; import com.volmit.iris.manager.IrisDataManager; import com.volmit.iris.scaffold.data.DataProvider; -import com.volmit.iris.util.M; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -21,15 +20,8 @@ public interface EngineFramework extends DataProvider default void recycle() { - if(M.r(0.1)) - { - synchronized (getEngine().getParallax()) - { - getEngine().getParallax().cleanup(); - } - - getData().getObjectLoader().clean(); - } + getEngine().getParallax().cleanup(); + getData().getObjectLoader().clean(); } public EngineActuator getTerrainActuator(); diff --git a/src/main/java/com/volmit/iris/scaffold/hunk/io/HunkRegionSlice.java b/src/main/java/com/volmit/iris/scaffold/hunk/io/HunkRegionSlice.java index 3b9a438ab..1329333ec 100644 --- a/src/main/java/com/volmit/iris/scaffold/hunk/io/HunkRegionSlice.java +++ b/src/main/java/com/volmit/iris/scaffold/hunk/io/HunkRegionSlice.java @@ -9,9 +9,9 @@ import java.io.IOException; public class HunkRegionSlice { - public static final Function2> BLOCKDATA = (h, c) -> new HunkRegionSlice<>(h, Hunk::newMappedHunk, new BlockDataHunkIOAdapter(), c, "blockdata"); - public static final Function3> STRING = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newMappedHunk, new StringHunkIOAdapter(), c, t); - public static final Function3> BOOLEAN = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newMappedHunk, new BooleanHunkIOAdapter(), c, t); + public static final Function2> BLOCKDATA = (h, c) -> new HunkRegionSlice<>(h, Hunk::newAtomicHunk, new BlockDataHunkIOAdapter(), c, "blockdata"); + public static final Function3> STRING = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newAtomicHunk, new StringHunkIOAdapter(), c, t); + public static final Function3> BOOLEAN = (h, c, t) -> new HunkRegionSlice<>(h, Hunk::newAtomicHunk, new BooleanHunkIOAdapter(), c, t); private final Function3> factory; private final HunkIOAdapter adapter; private final CompoundTag compound; diff --git a/src/main/java/com/volmit/iris/scaffold/parallax/ParallaxRegion.java b/src/main/java/com/volmit/iris/scaffold/parallax/ParallaxRegion.java index 28abe35da..6c7dc6ed9 100644 --- a/src/main/java/com/volmit/iris/scaffold/parallax/ParallaxRegion.java +++ b/src/main/java/com/volmit/iris/scaffold/parallax/ParallaxRegion.java @@ -90,7 +90,7 @@ public class ParallaxRegion extends HunkRegion return getMetaHunkR(); } - public synchronized Hunk loadMetaHunk() + public Hunk loadMetaHunk() { lastUse = M.ms(); if(meta == null) @@ -115,7 +115,7 @@ public class ParallaxRegion extends HunkRegion return meta; } - public synchronized void unloadMetaHunk() + public void unloadMetaHunk() { if(dirtyMeta) { @@ -126,7 +126,7 @@ public class ParallaxRegion extends HunkRegion meta = null; } - public synchronized void saveMetaHunk() + public void saveMetaHunk() { if(meta != null && dirtyMeta) { diff --git a/src/main/java/com/volmit/iris/scaffold/parallax/ParallaxWorld.java b/src/main/java/com/volmit/iris/scaffold/parallax/ParallaxWorld.java index 2e06abddb..3e4f6c6d7 100644 --- a/src/main/java/com/volmit/iris/scaffold/parallax/ParallaxWorld.java +++ b/src/main/java/com/volmit/iris/scaffold/parallax/ParallaxWorld.java @@ -54,7 +54,7 @@ public class ParallaxWorld implements ParallaxAccess return m; } - public synchronized void close() + public void close() { for(ParallaxRegion i : loadedRegions.v()) { @@ -65,7 +65,7 @@ public class ParallaxWorld implements ParallaxAccess loadedRegions.clear(); } - public synchronized void save(ParallaxRegion region) + public void save(ParallaxRegion region) { try { @@ -83,7 +83,7 @@ public class ParallaxWorld implements ParallaxAccess return loadedRegions.containsKey(key(x, z)); } - public synchronized void save(int x, int z) + public void save(int x, int z) { if(isLoaded(x, z)) { @@ -91,7 +91,7 @@ public class ParallaxWorld implements ParallaxAccess } } - public synchronized void unload(int x, int z) + public void unload(int x, int z) { long key = key(x, z); @@ -107,7 +107,7 @@ public class ParallaxWorld implements ParallaxAccess } } - public synchronized ParallaxRegion load(int x, int z) + public ParallaxRegion load(int x, int z) { if(isLoaded(x, z)) { @@ -157,7 +157,7 @@ public class ParallaxWorld implements ParallaxAccess } @Override - public synchronized Hunk getBlocksRW(int x, int z) + public Hunk getBlocksRW(int x, int z) { return getRW(x >> 5, z >> 5).getBlockSlice().getRW(x & 31, z & 31); } @@ -169,7 +169,7 @@ public class ParallaxWorld implements ParallaxAccess } @Override - public synchronized Hunk getObjectsRW(int x, int z) + public Hunk getObjectsRW(int x, int z) { return getRW(x >> 5, z >> 5).getObjectSlice().getRW(x & 31, z & 31); } @@ -181,7 +181,7 @@ public class ParallaxWorld implements ParallaxAccess } @Override - public synchronized Hunk getUpdatesRW(int x, int z) + public Hunk getUpdatesRW(int x, int z) { return getRW(x >> 5, z >> 5).getUpdateSlice().getRW(x & 31, z & 31); } @@ -227,15 +227,12 @@ public class ParallaxWorld implements ParallaxAccess } @Override - public synchronized void saveAllNOW() { + public void saveAllNOW() { for(ParallaxRegion i : loadedRegions.v()) { - synchronized (save) + if(save.contains(key(i.getX(), i.getZ()))) { - if(save.contains(key(i.getX(), i.getZ()))) - { - save(i.getX(), i.getZ()); - } + save(i.getX(), i.getZ()); } } }