From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Thu, 8 Jul 2021 15:03:15 -0400 Subject: [PATCH] JettPack patches Use LinkedBlockingDeque in IAsyncTaskHandler Original license: GPLv3 Original project: https://gitlab.com/Titaniumtown/JettPack Use MCUtil.asyncExecutor for MAIN_WORKER_EXECUTOR in SystemUtils Original code by Titaniumtown, licensed under GNU General Public License v3.0 You can find the original code on https://gitlab.com/Titaniumtown/JettPack diff --git a/src/main/java/me/titaniumtown/ServerWorkerWrapper.java b/src/main/java/me/titaniumtown/ServerWorkerWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..7bd88761137b2a68c04fbaa920a9ea9ce1f9e873 --- /dev/null +++ b/src/main/java/me/titaniumtown/ServerWorkerWrapper.java @@ -0,0 +1,24 @@ +package me.titaniumtown; + +import com.google.common.base.Preconditions; +import net.minecraft.Util; + +public final class ServerWorkerWrapper implements Runnable { + private final Runnable internalRunnable; + + public ServerWorkerWrapper(Runnable runnable) { + this.internalRunnable = Preconditions.checkNotNull(runnable, "internalRunnable"); + } + + @Override + public final void run() { + try { + this.internalRunnable.run(); + return; + } + catch (Throwable throwable) { + Util.onThreadException(Thread.currentThread(), throwable); + return; + } + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java index cdb7aea969b56f59d88f60bc3744e4932228c50a..b759f82b265542f42821e35ead56a5c073625d36 100644 --- a/src/main/java/net/minecraft/Util.java +++ b/src/main/java/net/minecraft/Util.java @@ -73,6 +73,12 @@ import net.minecraft.util.TimeSource; import net.minecraft.util.datafix.DataFixers; import net.minecraft.world.level.block.state.properties.Property; import org.slf4j.Logger; +// JettPack start +import java.util.concurrent.AbstractExecutorService; +import me.titaniumtown.ServerWorkerWrapper; +import net.minecraft.server.MCUtil; +import java.util.Collections; +// JettPack end public class Util { static final Logger LOGGER = LogUtils.getLogger(); @@ -165,7 +171,46 @@ public class Util { if (i <= 0) { executorService = MoreExecutors.newDirectExecutorService(); } else { - executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue(), target -> new net.minecraft.server.ServerWorkerThread(target, s, priorityModifier)); + //executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue(), target -> new net.minecraft.server.ServerWorkerThread(target, s, priorityModifier)); // JettPack + // JettPack start + executorService = Integer.getInteger("Paper.WorkerThreadCount", i) <= 0 ? MoreExecutors.newDirectExecutorService() : new AbstractExecutorService(){ + private volatile boolean shutdown = false; + + @Override + public final List shutdownNow() { + this.shutdown = true; + return Collections.emptyList(); + } + + @Override + public final void shutdown() { + this.shutdown = true; + } + + @Override + public final boolean isShutdown() { + return this.shutdown; + } + + @Override + public final boolean isTerminated() { + return this.shutdown; + } + + @Override + public final boolean awaitTermination(long l2, TimeUnit timeUnit) throws InterruptedException { + if (!this.shutdown) { + throw new UnsupportedOperationException(); + } + return true; + } + + @Override + public final void execute(Runnable runnable) { + MCUtil.asyncExecutor.execute(new ServerWorkerWrapper(runnable)); + } + }; + // JettPack end } /* @Override diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java index 7a4ade1a4190bf4fbb048919ae2be230f7b80fff..5edd42d22c320e126ef377f7a9ce6fee97b2c19f 100644 --- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java +++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java @@ -1,13 +1,13 @@ package net.minecraft.util.thread; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Queues; +//import com.google.common.collect.Queues; // JettPack import com.mojang.logging.LogUtils; import java.util.List; -import java.util.Queue; +//import java.util.Queue; // JettPack import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; -import java.util.concurrent.locks.LockSupport; +//import java.util.concurrent.locks.LockSupport; // JettPack import java.util.function.BooleanSupplier; import java.util.function.Supplier; import net.minecraft.util.profiling.metrics.MetricCategory; @@ -15,12 +15,15 @@ import net.minecraft.util.profiling.metrics.MetricSampler; import net.minecraft.util.profiling.metrics.MetricsRegistry; import net.minecraft.util.profiling.metrics.ProfilerMeasured; import org.slf4j.Logger; +import java.util.concurrent.LinkedBlockingDeque; // JettPack +import java.util.concurrent.TimeUnit; // JettPack public abstract class BlockableEventLoop implements ProfilerMeasured, ProcessorHandle, Executor { private final String name; private static final Logger LOGGER = LogUtils.getLogger(); - private final Queue pendingRunnables = Queues.newConcurrentLinkedQueue(); + private final LinkedBlockingDeque pendingRunnables = new LinkedBlockingDeque(); // JettPack private int blockingCount; + private R next = null; // JettPack protected BlockableEventLoop(String name) { this.name = name; @@ -89,7 +92,7 @@ public abstract class BlockableEventLoop implements Profiler @Override public void tell(R runnable) { this.pendingRunnables.add(runnable); - LockSupport.unpark(this.getRunningThread()); + //LockSupport.unpark(this.getRunningThread()); // JettPack } @Override @@ -117,15 +120,20 @@ public abstract class BlockableEventLoop implements Profiler } public boolean pollTask() { - R runnable = this.pendingRunnables.peek(); - if (runnable == null) { - return false; - } else if (this.blockingCount == 0 && !this.shouldRun(runnable)) { + // JettPack start + if (this.next == null && !this.pendingRunnables.isEmpty()) { + this.waitForTasks(); + } + + if (this.next == null) { return false; } else { - this.doRunTask(this.pendingRunnables.remove()); + R r2 = this.next; + this.next = null; + this.doRunTask(r2); return true; } + // JettPack end } public void managedBlock(BooleanSupplier stopCondition) { @@ -144,8 +152,18 @@ public abstract class BlockableEventLoop implements Profiler } protected void waitForTasks() { - Thread.yield(); - LockSupport.parkNanos("waiting for tasks", 100000L); + // JettPack start + if (this.next != null) { + throw new IllegalStateException("next != null"); + } + try { + this.next = this.pendingRunnables.poll(100L, TimeUnit.MICROSECONDS); + return; + } + catch (InterruptedException interruptedException) { + return; + } + // JettPack end } protected void doRunTask(R task) {