1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-03-04 10:38:12 +00:00

Small changes to ComputerThread

- Fix the timeout error message displaying utter rot.
 - Don't resize the runner array. We don't handle this correctly, so
   we shouldn't handle it at all.
 - Increment virtualRuntime after a task has executed.
This commit is contained in:
SquidDev 2019-03-02 09:16:25 +00:00
parent a125a19728
commit e34e833d3d
2 changed files with 28 additions and 12 deletions

View File

@ -10,6 +10,7 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.util.ThreadUtils; import dan200.computercraft.shared.util.ThreadUtils;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -113,9 +114,9 @@ public class ComputerThread
running = true; running = true;
if( monitor == null || !monitor.isAlive() ) (monitor = monitorFactory.newThread( new Monitor() )).start(); if( monitor == null || !monitor.isAlive() ) (monitor = monitorFactory.newThread( new Monitor() )).start();
if( runners == null || runners.length != ComputerCraft.computer_threads ) if( runners == null )
{ {
// TODO: Resize this + kill old runners and start new ones. // TODO: Change the runners lenght on config reloads
runners = new TaskRunner[ComputerCraft.computer_threads]; runners = new TaskRunner[ComputerCraft.computer_threads];
// latency and minPeriod are scaled by 1 + floor(log2(threads)). We can afford to execute tasks for // latency and minPeriod are scaled by 1 + floor(log2(threads)). We can afford to execute tasks for
@ -159,8 +160,16 @@ public class ComputerThread
} }
} }
computerLock.lock();
try
{
computerQueue.clear(); computerQueue.clear();
} }
finally
{
computerLock.unlock();
}
}
/** /**
* Mark a computer as having work, enqueuing it on the thread. * Mark a computer as having work, enqueuing it on the thread.
@ -175,7 +184,7 @@ public class ComputerThread
if( executor.onComputerQueue ) throw new IllegalStateException( "Cannot queue already queued executor" ); if( executor.onComputerQueue ) throw new IllegalStateException( "Cannot queue already queued executor" );
executor.onComputerQueue = true; executor.onComputerQueue = true;
updateRuntimes(); updateRuntimes( null );
// We're not currently on the queue, so update its current execution time to // We're not currently on the queue, so update its current execution time to
// ensure its at least as high as the minimum. // ensure its at least as high as the minimum.
@ -209,19 +218,20 @@ public class ComputerThread
* Update the {@link ComputerExecutor#virtualRuntime}s of all running tasks, and then increment the * Update the {@link ComputerExecutor#virtualRuntime}s of all running tasks, and then increment the
* {@link #minimumVirtualRuntime} of the executor. * {@link #minimumVirtualRuntime} of the executor.
*/ */
private static void updateRuntimes() private static void updateRuntimes( @Nullable ComputerExecutor current )
{ {
long minRuntime = Long.MAX_VALUE; long minRuntime = Long.MAX_VALUE;
// If we've a task on the queue, use that as our base time. // If we've a task on the queue, use that as our base time.
if( !computerQueue.isEmpty() ) minRuntime = computerQueue.first().virtualRuntime; if( !computerQueue.isEmpty() ) minRuntime = computerQueue.first().virtualRuntime;
long now = System.nanoTime();
int tasks = 1 + computerQueue.size();
// Update all the currently executing tasks // Update all the currently executing tasks
TaskRunner[] currentRunners = runners; TaskRunner[] currentRunners = runners;
if( currentRunners != null ) if( currentRunners != null )
{ {
long now = System.nanoTime();
int tasks = 1 + computerQueue.size();
for( TaskRunner runner : currentRunners ) for( TaskRunner runner : currentRunners )
{ {
if( runner == null ) continue; if( runner == null ) continue;
@ -235,6 +245,12 @@ public class ComputerThread
} }
} }
// And update the most recently executed one if set.
if( current != null )
{
minRuntime = Math.min( minRuntime, current.virtualRuntime += (now - current.vRuntimeStart) / tasks );
}
if( minRuntime > minimumVirtualRuntime && minRuntime < Long.MAX_VALUE ) if( minRuntime > minimumVirtualRuntime && minRuntime < Long.MAX_VALUE )
{ {
minimumVirtualRuntime = minRuntime; minimumVirtualRuntime = minRuntime;
@ -251,7 +267,7 @@ public class ComputerThread
computerLock.lock(); computerLock.lock();
try try
{ {
updateRuntimes(); updateRuntimes( executor );
// Add to the queue, and signal the workers. // Add to the queue, and signal the workers.
if( !executor.afterWork() ) return; if( !executor.afterWork() ) return;
@ -353,7 +369,7 @@ public class ComputerThread
{ {
// If we've hard aborted but we're still not dead, dump the stack trace and interrupt // If we've hard aborted but we're still not dead, dump the stack trace and interrupt
// the task. // the task.
timeoutTask( executor, runner.owner, afterStart ); timeoutTask( executor, runner.owner );
runner.owner.interrupt(); runner.owner.interrupt();
} }
} }
@ -432,13 +448,13 @@ public class ComputerThread
} }
} }
private static void timeoutTask( ComputerExecutor executor, Thread thread, long nanotime ) private static void timeoutTask( ComputerExecutor executor, Thread thread )
{ {
if( !ComputerCraft.logPeripheralErrors ) return; if( !ComputerCraft.logPeripheralErrors ) return;
StringBuilder builder = new StringBuilder() StringBuilder builder = new StringBuilder()
.append( "Terminating computer #" ).append( executor.getComputer().getID() ) .append( "Terminating computer #" ).append( executor.getComputer().getID() )
.append( " due to timeout (running for " ).append( nanotime / 1e9 ) .append( " due to timeout (running for " ).append( executor.timeout.nanoCumulative() * 1e-9 )
.append( " seconds). This is NOT a bug, but may mean a computer is misbehaving. " ) .append( " seconds). This is NOT a bug, but may mean a computer is misbehaving. " )
.append( thread.getName() ) .append( thread.getName() )
.append( " is currently " ) .append( " is currently " )

View File

@ -106,7 +106,7 @@ public class Config
computerThreads = config.get( CATEGORY_GENERAL, "computer_threads", ComputerCraft.computer_threads ); computerThreads = config.get( CATEGORY_GENERAL, "computer_threads", ComputerCraft.computer_threads );
computerThreads computerThreads
.setMinValue( 1 ) .setMinValue( 1 )
.setRequiresWorldRestart( true ) .setRequiresMcRestart( true )
.setComment( "Set the number of threads computers can run on. A higher number means more computers can run at once, but may induce lag.\n" + .setComment( "Set the number of threads computers can run on. A higher number means more computers can run at once, but may induce lag.\n" +
"Please note that some mods may not work with a thread count higher than 1. Use with caution." ); "Please note that some mods may not work with a thread count higher than 1. Use with caution." );