fix concurrency concerns

This commit is contained in:
Babbaj 2023-07-24 03:30:06 -04:00
parent 6ffe31b59e
commit 45400a9685
No known key found for this signature in database
GPG Key ID: F044309848A07CAC
3 changed files with 19 additions and 16 deletions

View File

@ -27,7 +27,7 @@ public final class BlockStateOctreeInterface {
private final NetherPathfinderContext context;
private final long contextPtr;
volatile long chunkPtr;
transient long chunkPtr;
// Guarantee that the first lookup will fetch the context by setting MAX_VALUE
private int prevChunkX = Integer.MAX_VALUE;
@ -44,14 +44,11 @@ public final class BlockStateOctreeInterface {
}
final int chunkX = x >> 4;
final int chunkZ = z >> 4;
long pointer = this.chunkPtr;
if (pointer == 0 | ((chunkX ^ this.prevChunkX) | (chunkZ ^ this.prevChunkZ)) != 0) {
if (this.chunkPtr == 0 | ((chunkX ^ this.prevChunkX) | (chunkZ ^ this.prevChunkZ)) != 0) {
this.prevChunkX = chunkX;
this.prevChunkZ = chunkZ;
synchronized (this.context.cacheLock) {
this.chunkPtr = pointer = NetherPathfinder.getOrCreateChunk(this.contextPtr, chunkX, chunkZ);
}
this.chunkPtr = NetherPathfinder.getOrCreateChunk(this.contextPtr, chunkX, chunkZ);
}
return Octree.getBlock(pointer, x & 0xF, y & 0x7F, z & 0xF);
return Octree.getBlock(this.chunkPtr, x & 0xF, y & 0x7F, z & 0xF);
}
}

View File

@ -446,6 +446,17 @@ public final class ElytraBehavior implements Helper {
}
public void onTick() {
synchronized (this.context.cullingLock) {
this.onTick0();
}
final long now = System.currentTimeMillis();
if ((now - this.timeLastCacheCull) / 1000 > Baritone.settings().elytraTimeBetweenCacheCullSecs.value) {
this.context.queueCacheCulling(ctx.player().chunkCoordX, ctx.player().chunkCoordZ, Baritone.settings().elytraCacheCullDistance.value, this.boi);
this.timeLastCacheCull = now;
}
}
private void onTick0() {
// Fetch the previous solution, regardless of if it's going to be used
this.pendingSolution = null;
if (this.solver != null) {
@ -498,12 +509,6 @@ public final class ElytraBehavior implements Helper {
Math.max(playerNear - 30, 0),
Math.min(playerNear + 100, path.size())
);
final long now = System.currentTimeMillis();
if ((now - this.timeLastCacheCull) / 1000 > Baritone.settings().elytraTimeBetweenCacheCullSecs.value) {
this.context.queueCacheCulling(ctx.player().chunkCoordX, ctx.player().chunkCoordZ, Baritone.settings().elytraCacheCullDistance.value, this.boi);
this.timeLastCacheCull = now;
}
}
/**

View File

@ -38,7 +38,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Brady
@ -46,7 +45,9 @@ import java.util.concurrent.atomic.AtomicInteger;
public final class NetherPathfinderContext {
private static final IBlockState AIR_BLOCK_STATE = Blocks.AIR.getDefaultState();
public final Object cacheLock = new Object();
// This lock must be held while there are active pointers to chunks in java,
// but we just hold it for the entire tick so we don't have to think much about it.
public final Object cullingLock = new Object();
// Visible for access in BlockStateOctreeInterface
final long context;
@ -61,7 +62,7 @@ public final class NetherPathfinderContext {
public void queueCacheCulling(int chunkX, int chunkZ, int maxDistanceBlocks, BlockStateOctreeInterface boi) {
this.executor.execute(() -> {
synchronized (this.cacheLock) {
synchronized (this.cullingLock) {
boi.chunkPtr = 0L;
NetherPathfinder.cullFarChunks(this.context, chunkX, chunkZ, maxDistanceBlocks);
}