Attempt to reduce reaquires on miss

This commit is contained in:
mcrcortex
2025-06-19 22:15:29 +10:00
parent 156b30756d
commit 4d839e3662
4 changed files with 41 additions and 20 deletions

View File

@@ -109,7 +109,7 @@ dependencies {
modCompileOnly("maven.modrinth:chunky:1.4.36-fabric") modCompileOnly("maven.modrinth:chunky:1.4.36-fabric")
modRuntimeOnlyMsk("maven.modrinth:chunky:1.4.36-fabric") modRuntimeOnlyMsk("maven.modrinth:chunky:1.4.36-fabric")
modRuntimeOnlyMsk("maven.modrinth:spark:1.10.138-fabric") modRuntimeOnlyMsk("maven.modrinth:spark:1.10.139-fabric")
modRuntimeOnlyMsk("maven.modrinth:fabric-permissions-api:0.3.3") modRuntimeOnlyMsk("maven.modrinth:fabric-permissions-api:0.3.3")
//modRuntimeOnly("maven.modrinth:nsight-loader:1.2.0") //modRuntimeOnly("maven.modrinth:nsight-loader:1.2.0")

View File

@@ -272,7 +272,7 @@ public class ServiceThreadPool {
} }
//Sleep for a bit after running a job, yeild the thread //Sleep for a bit after running a job, yeild the thread
Thread.yield(); //Thread.yield();
break; break;
} }
} }

View File

@@ -1,5 +0,0 @@
package me.cortex.voxy.common.util;
public class VolatileHolder <T> {
public volatile T obj;
}

View File

@@ -3,15 +3,13 @@ package me.cortex.voxy.common.world;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.util.VolatileHolder;
import me.cortex.voxy.common.voxelization.WorldConversionFactory;
import me.cortex.voxy.common.world.other.Mapper;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle; import java.lang.invoke.VarHandle;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.StampedLock; import java.util.concurrent.locks.StampedLock;
public class ActiveSectionTracker { public class ActiveSectionTracker {
@@ -20,6 +18,21 @@ public class ActiveSectionTracker {
public interface SectionLoader {int load(WorldSection section);} public interface SectionLoader {int load(WorldSection section);}
//Loaded section world cache, TODO: get rid of VolatileHolder and use something more sane //Loaded section world cache, TODO: get rid of VolatileHolder and use something more sane
private static final class VolatileHolder <T> {
private static final VarHandle PRE_ACQUIRE_COUNT;
private static final VarHandle POST_ACQUIRE_COUNT;
static {
try {
PRE_ACQUIRE_COUNT = MethodHandles.lookup().findVarHandle(VolatileHolder.class, "preAcquireCount", int.class);
POST_ACQUIRE_COUNT = MethodHandles.lookup().findVarHandle(VolatileHolder.class, "postAcquireCount", int.class);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public volatile int preAcquireCount;
public volatile int postAcquireCount;
public volatile T obj;
}
private final AtomicInteger loadedSections = new AtomicInteger(); private final AtomicInteger loadedSections = new AtomicInteger();
private final Long2ObjectOpenHashMap<VolatileHolder<WorldSection>>[] loadedSectionCache; private final Long2ObjectOpenHashMap<VolatileHolder<WorldSection>>[] loadedSectionCache;
@@ -102,6 +115,8 @@ public class ActiveSectionTracker {
section = this.lruSecondaryCache.remove(key); section = this.lruSecondaryCache.remove(key);
this.lruLock.unlockWrite(stamp); this.lruLock.unlockWrite(stamp);
lock.unlockRead(stamp2); lock.unlockRead(stamp2);
} else {
VolatileHolder.PRE_ACQUIRE_COUNT.getAndAdd(holder, 1);
} }
//If this thread was the one to create the reference then its the thread to load the section //If this thread was the one to create the reference then its the thread to load the section
@@ -131,8 +146,12 @@ public class ActiveSectionTracker {
} else { } else {
section.primeForReuse(); section.primeForReuse();
} }
int preAcquireCount = (int) VolatileHolder.PRE_ACQUIRE_COUNT.getAndSet(holder, 0);
section.acquire(preAcquireCount+1);//pre acquire amount
VolatileHolder.POST_ACQUIRE_COUNT.set(holder, preAcquireCount);
//TODO: mark if the section was loaded null
section.acquire();
VarHandle.storeStoreFence();//Do not reorder setting this object VarHandle.storeStoreFence();//Do not reorder setting this object
holder.obj = section; holder.obj = section;
VarHandle.releaseFence(); VarHandle.releaseFence();
@@ -142,6 +161,7 @@ public class ActiveSectionTracker {
} }
return section; return section;
} else { } else {
//TODO: mark the time the loading started in nanos, then here if it has been a while, spin lock, else jump back to the executing service and do work
VarHandle.fullFence(); VarHandle.fullFence();
while ((section = holder.obj) == null) { while ((section = holder.obj) == null) {
VarHandle.fullFence(); VarHandle.fullFence();
@@ -149,16 +169,22 @@ public class ActiveSectionTracker {
Thread.yield(); Thread.yield();
} }
//lock.lock(); //Try to acquire a pre lock
{//Dont think need to lock here if (0<((int)VolatileHolder.POST_ACQUIRE_COUNT.getAndAdd(holder, -1))) {
if (section.tryAcquire()) { //We managed to acquire one of the pre locks, so just return the section
return section; return section;
} else {
//lock.lock();
{//Dont think need to lock here
if (section.tryAcquire()) {
return section;
}
} }
} //lock.unlock();
//lock.unlock();
//We failed everything, try get it again //We failed everything, try get it again
return this.acquire(key, nullOnEmpty); return this.acquire(key, nullOnEmpty);
}
} }
} }