Skip to content

Commit 3122d8f

Browse files
Remove Collections::synchronizedMap due to performance reason
1 parent ff3c9a9 commit 3122d8f

8 files changed

Lines changed: 71 additions & 45 deletions

File tree

src/main/java/wearblackallday/dimthread/DimThread.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
11
package wearblackallday.dimthread;
22

33
import net.fabricmc.api.ModInitializer;
4+
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
45
import net.minecraft.server.MinecraftServer;
56
import net.minecraft.server.world.ServerWorld;
67
import wearblackallday.dimthread.init.ModGameRules;
78
import wearblackallday.dimthread.thread.IMutableMainThread;
9+
import wearblackallday.dimthread.util.IThreadedServer;
810
import wearblackallday.dimthread.util.ServerManager;
911
import wearblackallday.dimthread.util.ThreadPool;
1012

1113
public class DimThread implements ModInitializer {
1214

1315
public static final String MOD_ID = "dimthread";
14-
public static final ServerManager MANAGER = new ServerManager();
1516

1617
@Override
1718
public void onInitialize() {
1819
ModGameRules.registerGameRules();
20+
ServerLifecycleEvents.SERVER_STARTED.register(this::onServerLoaded);
21+
}
22+
23+
public void onServerLoaded(MinecraftServer server) {
24+
((IThreadedServer)server).setDimThreadPool(new ThreadPool(server.getGameRules().getInt(ModGameRules.THREAD_COUNT.getKey())));
25+
((IThreadedServer)server).setDimThreadActive(server.getGameRules().getBoolean(ModGameRules.ACTIVE.getKey()));
1926
}
2027

2128
public static ThreadPool getThreadPool(MinecraftServer server) {
22-
return MANAGER.getThreadPool(server);
29+
return ServerManager.getThreadPool(server);
2330
}
2431

2532
public static void swapThreadsAndRun(Runnable task, Object... threadedObjects) {
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package wearblackallday.dimthread.init;
22

3-
import wearblackallday.dimthread.DimThread;
3+
import net.minecraft.world.GameRules;
44
import wearblackallday.dimthread.gamerule.BoolRule;
55
import wearblackallday.dimthread.gamerule.IntRule;
6-
import net.minecraft.world.GameRules;
6+
import wearblackallday.dimthread.util.ServerManager;
77

88
public class ModGameRules {
99

@@ -12,10 +12,10 @@ public class ModGameRules {
1212

1313
public static void registerGameRules() {
1414
ACTIVE = BoolRule.builder("active", GameRules.Category.UPDATES).setInitial(true)
15-
.setCallback(DimThread.MANAGER::setActive).build();
15+
.setCallback(ServerManager::setActive).build();
1616

1717
THREAD_COUNT = IntRule.builder("thread_count", GameRules.Category.UPDATES).setInitial(3)
18-
.setBounds(1, Runtime.getRuntime().availableProcessors()).setCallback(DimThread.MANAGER::setThreadCount).build();
18+
.setBounds(1, Runtime.getRuntime().availableProcessors()).setCallback(ServerManager::setThreadCount).build();
1919
}
2020

2121
}

src/main/java/wearblackallday/dimthread/mixin/EntityMixin.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
3131
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
3232
import wearblackallday.dimthread.DimThread;
33+
import wearblackallday.dimthread.util.ServerManager;
3334
import wearblackallday.dimthread.util.UncompletedTeleportTarget;
3435

3536
import java.util.Optional;
@@ -99,7 +100,7 @@ public abstract class EntityMixin {
99100
*/
100101
@Inject(method = "moveToWorld", at = @At("HEAD"), cancellable = true)
101102
public void onMoveToWorld(ServerWorld destination, CallbackInfoReturnable<Entity> ci) {
102-
if (!DimThread.MANAGER.isActive(destination.getServer()))
103+
if (!ServerManager.isActive(destination.getServer()))
103104
return;
104105

105106
if (DimThread.owns(Thread.currentThread())) {
@@ -129,7 +130,7 @@ public void onMoveToWorld(ServerWorld destination, CallbackInfoReturnable<Entity
129130
*/
130131
@Redirect(method = "moveToWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;copyFrom(Lnet/minecraft/entity/Entity;)V"))
131132
private void onMoveToWorldCopyFrom(Entity instance, Entity original) {
132-
if(DimThread.MANAGER.isActive(getServer())) {
133+
if(ServerManager.isActive(getServer())) {
133134
NbtCompound nbtCompound = ((EntityMixin) (Object) original).nbtCachedForMoveToWorld;
134135
nbtCompound.remove("Dimension");
135136
instance.readNbt(nbtCompound);
@@ -147,7 +148,7 @@ private void onMoveToWorldCopyFrom(Entity instance, Entity original) {
147148
@Redirect(method = "moveToWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getTeleportTarget(Lnet/minecraft/server/world/ServerWorld;)Lnet/minecraft/world/TeleportTarget;"))
148149
private TeleportTarget onMoveToWorldGetTeleportTarget(@NotNull Entity instance, ServerWorld destination) {
149150
EntityMixin ins = ((EntityMixin) (Object) instance);
150-
if(DimThread.MANAGER.isActive(getServer())) {
151+
if(ServerManager.isActive(getServer())) {
151152
return ins.uncompletedTeleportTargetForMoveToWorld == null ? null : ins.uncompletedTeleportTargetForMoveToWorld.complete(destination);
152153
} else {
153154
return ins.getTeleportTarget(destination);

src/main/java/wearblackallday/dimthread/mixin/MinecraftServerMixin.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,15 @@
1212
import org.spongepowered.asm.mixin.injection.ModifyVariable;
1313
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
1414
import wearblackallday.dimthread.DimThread;
15-
import wearblackallday.dimthread.util.CrashInfo;
16-
import wearblackallday.dimthread.util.ServerWorldAccessor;
17-
import wearblackallday.dimthread.util.ThreadPool;
15+
import wearblackallday.dimthread.util.*;
1816

1917
import java.util.Collections;
2018
import java.util.Iterator;
2119
import java.util.concurrent.atomic.AtomicReference;
2220
import java.util.function.BooleanSupplier;
2321

2422
@Mixin(MinecraftServer.class)
25-
public abstract class MinecraftServerMixin {
23+
public abstract class MinecraftServerMixin implements IThreadedServer {
2624

2725
@Shadow private int ticks;
2826
@Shadow private PlayerManager playerManager;
@@ -37,7 +35,7 @@ public abstract class MinecraftServerMixin {
3735
@ModifyVariable(method = "tickWorlds", at = @At(value = "INVOKE_ASSIGN",
3836
target = "Ljava/lang/Iterable;iterator()Ljava/util/Iterator;", ordinal = 0))
3937
public Iterator<?> tickWorlds(Iterator<?> oldValue) {
40-
return DimThread.MANAGER.isActive((MinecraftServer)(Object)this) ? Collections.emptyIterator() : oldValue;
38+
return ServerManager.isActive((MinecraftServer)(Object)this) ? Collections.emptyIterator() : oldValue;
4139
}
4240

4341
/**
@@ -47,7 +45,7 @@ public Iterator<?> tickWorlds(Iterator<?> oldValue) {
4745
@Inject(method = "tickWorlds", at = @At(value = "INVOKE",
4846
target = "Ljava/lang/Iterable;iterator()Ljava/util/Iterator;"))
4947
public void tickWorlds(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
50-
if(!DimThread.MANAGER.isActive((MinecraftServer)(Object)this))return;
48+
if(!ServerManager.isActive((MinecraftServer)(Object)this))return;
5149

5250
AtomicReference<CrashInfo> crash = new AtomicReference<>();
5351
ThreadPool pool = DimThread.getThreadPool((MinecraftServer)(Object)this);
@@ -86,6 +84,28 @@ public void tickWorlds(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
8684
* */
8785
@Inject(method = "shutdown", at = @At("HEAD"))
8886
public void shutdownThreadpool(CallbackInfo ci) {
89-
DimThread.MANAGER.threadPools.forEach((server, pool) -> pool.shutdown());
87+
getDimThreadPool().shutdown();
88+
}
89+
90+
private boolean dimthread_active;
91+
private ThreadPool dimthread_threadPool;
92+
@Override
93+
public boolean isDimThreadActive() {
94+
return dimthread_active;
95+
}
96+
97+
@Override
98+
public void setDimThreadActive(boolean active) {
99+
this.dimthread_active = active;
100+
}
101+
102+
@Override
103+
public ThreadPool getDimThreadPool() {
104+
return dimthread_threadPool;
105+
}
106+
107+
@Override
108+
public void setDimThreadPool(ThreadPool pool) {
109+
this.dimthread_threadPool = pool;
90110
}
91111
}

src/main/java/wearblackallday/dimthread/mixin/ServerChunkManagerMixin.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.spongepowered.asm.mixin.injection.Inject;
1717
import org.spongepowered.asm.mixin.injection.Redirect;
1818
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
19+
import wearblackallday.dimthread.util.ServerManager;
1920

2021
@Mixin(value = ServerChunkManager.class, priority = 1001)
2122
public abstract class ServerChunkManagerMixin extends ChunkManager implements IMutableMainThread {
@@ -46,7 +47,7 @@ private void getTotalChunksLoadedCount(CallbackInfoReturnable<Integer> ci) {
4647
public Thread currentThread(int x, int z, ChunkStatus leastStatus, boolean create) {
4748
Thread thread = Thread.currentThread();
4849

49-
if(DimThread.MANAGER.isActive(this.world.getServer()) && DimThread.owns(thread)) {
50+
if(ServerManager.isActive(this.world.getServer()) && DimThread.owns(thread)) {
5051
return this.serverThread;
5152
}
5253

src/main/java/wearblackallday/dimthread/mixin/ServerWorldMixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import org.spongepowered.asm.mixin.injection.At;
1313
import org.spongepowered.asm.mixin.injection.Inject;
1414
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
15-
import wearblackallday.dimthread.DimThread;
15+
import wearblackallday.dimthread.util.ServerManager;
1616
import wearblackallday.dimthread.util.ServerWorldAccessor;
1717

1818
import java.util.function.Supplier;
@@ -33,7 +33,7 @@ protected ServerWorldMixin(MutableWorldProperties properties, RegistryKey<World>
3333
*/
3434
@Inject(method = "tickTime", at = @At("HEAD"), cancellable = true)
3535
private void preventTimeTicking(CallbackInfo ci) {
36-
if (DimThread.MANAGER.isActive(getServer()) && !onMainThread) {
36+
if (ServerManager.isActive(getServer()) && !onMainThread) {
3737
timeTickedOnWorldThread = true;
3838
ci.cancel();
3939
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package wearblackallday.dimthread.util;
2+
3+
/**
4+
* In order to fix the serious performance problem, we migrated to this implement
5+
*/
6+
7+
public interface IThreadedServer {
8+
boolean isDimThreadActive();
9+
void setDimThreadActive(boolean active);
10+
ThreadPool getDimThreadPool();
11+
void setDimThreadPool(ThreadPool pool);
12+
}

src/main/java/wearblackallday/dimthread/util/ServerManager.java

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,24 @@
22

33
import net.minecraft.server.MinecraftServer;
44
import net.minecraft.world.GameRules;
5-
import wearblackallday.dimthread.init.ModGameRules;
6-
import wearblackallday.dimthread.util.ThreadPool;
75

8-
import java.util.Collections;
9-
import java.util.ConcurrentModificationException;
10-
import java.util.Map;
11-
import java.util.WeakHashMap;
12-
13-
public class ServerManager {
14-
15-
private final Map<MinecraftServer, Boolean> actives = Collections.synchronizedMap(new WeakHashMap<>());
16-
public final Map<MinecraftServer, ThreadPool> threadPools = Collections.synchronizedMap(new WeakHashMap<>());
17-
18-
public boolean isActive(MinecraftServer server) {
19-
return this.actives.computeIfAbsent(server, s -> s.getGameRules().get(ModGameRules.ACTIVE.getKey()).get());
6+
public final class ServerManager {
7+
public static boolean isActive(MinecraftServer server) {
8+
return ((IThreadedServer)server).isDimThreadActive();
209
}
2110

22-
public void setActive(MinecraftServer server, GameRules.BooleanRule value) {
23-
this.actives.put(server, value.get());
11+
public static void setActive(MinecraftServer server, GameRules.BooleanRule value) {
12+
((IThreadedServer) server).setDimThreadActive(value.get());
2413
}
2514

26-
public ThreadPool getThreadPool(MinecraftServer server) {
27-
return this.threadPools.computeIfAbsent(server, s -> new ThreadPool(s.getGameRules().get(ModGameRules.THREAD_COUNT.getKey()).get()));
15+
public static ThreadPool getThreadPool(MinecraftServer server) {
16+
return ((IThreadedServer) server).getDimThreadPool();
2817
}
2918

30-
public void setThreadCount(MinecraftServer server, GameRules.IntRule value) {
31-
ThreadPool current = this.threadPools.get(server);
32-
33-
if(current.getActiveCount() != 0) {
34-
throw new ConcurrentModificationException("Setting the thread count in wrong phase");
35-
}
36-
37-
this.threadPools.put(server, new ThreadPool(value.get()));
19+
public static void setThreadCount(MinecraftServer server, GameRules.IntRule value) {
20+
IThreadedServer server1 = (IThreadedServer) server;
21+
ThreadPool current = server1.getDimThreadPool();
22+
server1.setDimThreadPool(new ThreadPool(value.get()));
3823
current.shutdown();
3924
}
4025
}

0 commit comments

Comments
 (0)