1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-26 07:03:22 +00:00

Add support for tracking server-thread tasks too

This allows us to track how much work various peripherals are doing.
This will not work with all systems, such as Plethora, as that has its
own execution system.
This commit is contained in:
SquidDev 2018-04-24 12:26:26 +01:00
parent cac65ef755
commit bfbb18bdfc
7 changed files with 118 additions and 23 deletions

View File

@ -69,17 +69,17 @@ public static void start()
s_stopped = false;
if( s_threads == null || s_threads.length != ComputerCraft.computer_threads )
{
s_threads = new Thread[ ComputerCraft.computer_threads ];
s_threads = new Thread[ComputerCraft.computer_threads];
}
SecurityManager manager = System.getSecurityManager();
final ThreadGroup group = manager == null ? Thread.currentThread().getThreadGroup() : manager.getThreadGroup();
for( int i = 0; i < s_threads.length; i++ )
{
Thread thread = s_threads[ i ];
Thread thread = s_threads[i];
if( thread == null || !thread.isAlive() )
{
thread = s_threads[ i ] = new Thread( group, new TaskExecutor(), "ComputerCraft-Computer-Manager-" + s_ManagerCounter.getAndIncrement() );
thread = s_threads[i] = new Thread( group, new TaskExecutor(), "ComputerCraft-Computer-Manager-" + s_ManagerCounter.getAndIncrement() );
thread.setDaemon( true );
thread.start();
}
@ -251,8 +251,8 @@ private void execute( BlockingQueue<ITask> queue ) throws InterruptedException
{
long stop = System.nanoTime();
Computer computer = task.getOwner();
if( computer != null ) Tracking.addTiming( computer, stop - start );
if( computer != null ) Tracking.addTaskTiming( computer, stop - start );
// Re-add it back onto the queue or remove it
synchronized( s_taskLock )
{

View File

@ -6,14 +6,17 @@
package dan200.computercraft.core.computer;
import java.util.LinkedList;
import dan200.computercraft.core.tracking.Tracking;
import java.util.ArrayDeque;
import java.util.Queue;
public class MainThread
{
private static final int MAX_TASKS_PER_TICK = 1000;
private static final int MAX_TASKS_TOTAL = 50000;
private static final LinkedList<ITask> m_outstandingTasks = new LinkedList<>();
private static final Queue<ITask> m_outstandingTasks = new ArrayDeque<>();
private static final Object m_nextUnusedTaskIDLock = new Object();
private static long m_nextUnusedTaskID = 0;
@ -31,7 +34,7 @@ public static boolean queueTask( ITask task )
{
if( m_outstandingTasks.size() < MAX_TASKS_TOTAL )
{
m_outstandingTasks.addLast( task );
m_outstandingTasks.offer( task );
return true;
}
}
@ -46,14 +49,17 @@ public static void executePendingTasks()
ITask task = null;
synchronized( m_outstandingTasks )
{
if( m_outstandingTasks.size() > 0 )
{
task = m_outstandingTasks.removeFirst();
}
task = m_outstandingTasks.poll();
}
if( task != null )
{
long start = System.nanoTime();
task.execute();
long stop = System.nanoTime();
Computer computer = task.getOwner();
if( computer != null ) Tracking.addServerTiming( computer, stop - start );
++tasksThisTick;
}
else

View File

@ -15,6 +15,9 @@ public class ComputerTracker
private long totalTime;
private long maxTime;
private long serverCount;
private long serverTime;
private final TObjectLongHashMap<TrackingField> fields;
public ComputerTracker( Computer computer )
@ -32,10 +35,13 @@ public ComputerTracker( Computer computer )
this.tasks = timings.tasks;
this.totalTime = timings.totalTime;
this.maxTime = timings.maxTime;
this.serverCount = timings.serverCount;
this.serverTime = timings.serverTime;
this.fields = new TObjectLongHashMap<>( timings.fields );
}
@Nullable
public Computer getComputer()
{
@ -67,13 +73,19 @@ public long getAverage()
return totalTime / tasks;
}
void addTiming( long time )
void addTaskTiming( long time )
{
tasks++;
totalTime += time;
if( time > maxTime ) maxTime = time;
}
void addMainTiming( long time )
{
serverCount++;
serverTime += time;
}
void addValue( TrackingField field, long change )
{
synchronized( fields )
@ -89,6 +101,9 @@ public long get( TrackingField field )
if( field == TrackingField.TOTAL_TIME ) return totalTime;
if( field == TrackingField.AVERAGE_TIME ) return totalTime / tasks;
if( field == TrackingField.SERVER_COUNT ) return serverCount;
if( field == TrackingField.SERVER_TIME ) return serverTime;
synchronized( fields )
{
return fields.get( field );

View File

@ -4,7 +4,46 @@
public interface Tracker
{
void addTiming( Computer computer, long time );
@Deprecated
default void addTiming( Computer computer, long time )
{
}
void addValue( Computer computer, TrackingField field, long change );
/**
* Report how long a task executed on the computer thread took.
*
* Computer thread tasks include events or a computer being turned on/off.
*
* @param computer The computer processing this task
* @param time The time taken for this task.
*/
default void addTaskTiming( Computer computer, long time )
{
//noinspection deprecation
addTiming( computer, time );
}
/**
* Report how long a task executed on the server thread took.
*
* Server tasks include actions performed by peripherals.
*
* @param computer The computer processing this task
* @param time The time taken for this task.
*/
default void addServerTiming( Computer computer, long time )
{
}
/**
* Increment an arbitrary field by some value. Implementations may track how often this is called
* as well as the change, to compute some level of "average".
*
* @param computer The computer to increment
* @param field The field to increment.
* @param change The amount to increment said field by.
*/
default void addValue( Computer computer, TrackingField field, long change )
{
}
}

View File

@ -35,14 +35,25 @@ public static void add( Tracker tracker )
}
}
public static void addTiming( Computer computer, long time )
public static void addTaskTiming( Computer computer, long time )
{
if( tracking.get() == 0 ) return;
synchronized( contexts )
{
for( TrackingContext context : contexts.values() ) context.addTiming( computer, time );
for( Tracker tracker : trackers ) tracker.addTiming( computer, time );
for( TrackingContext context : contexts.values() ) context.addTaskTiming( computer, time );
for( Tracker tracker : trackers ) tracker.addTaskTiming( computer, time );
}
}
public static void addServerTiming( Computer computer, long time )
{
if( tracking.get() == 0 ) return;
synchronized( contexts )
{
for( TrackingContext context : contexts.values() ) context.addServerTiming( computer, time );
for( Tracker tracker : trackers ) tracker.addServerTiming( computer, time );
}
}

View File

@ -14,7 +14,7 @@
* Note that this <em>will</em> track computers which have been deleted (hence
* the presence of {@link #timingLookup} and {@link #timings}
*/
public class TrackingContext
public class TrackingContext implements Tracker
{
private boolean tracking = false;
@ -52,7 +52,8 @@ public synchronized List<ComputerTracker> getTimings()
return new ArrayList<>( timings );
}
public void addTiming( Computer computer, long time )
@Override
public void addTaskTiming( Computer computer, long time )
{
if( !tracking ) return;
@ -66,11 +67,31 @@ public void addTiming( Computer computer, long time )
timings.add( computerTimings );
}
computerTimings.addTiming( time );
computerTimings.addTaskTiming( time );
}
}
public synchronized void addValue( Computer computer, TrackingField field, long change )
@Override
public void addServerTiming( Computer computer, long time )
{
if( !tracking ) return;
synchronized( this )
{
ComputerTracker computerTimings = timingLookup.get( computer );
if( computerTimings == null )
{
computerTimings = new ComputerTracker( computer );
timingLookup.put( computer, computerTimings );
timings.add( computerTimings );
}
computerTimings.addMainTiming( time );
}
}
@Override
public void addValue( Computer computer, TrackingField field, long change )
{
if( !tracking ) return;

View File

@ -14,6 +14,9 @@ public class TrackingField
public static final TrackingField AVERAGE_TIME = TrackingField.of( "average", "Average time", x -> String.format( "%4.1fms", x / 1e6 ) );
public static final TrackingField MAX_TIME = TrackingField.of( "max", "Max time", x -> String.format( "%5.1fms", x / 1e6 ) );
public static final TrackingField SERVER_COUNT = TrackingField.of( "server_count", "Server task count", x -> String.format( "%4d", x ) );
public static final TrackingField SERVER_TIME = TrackingField.of( "server_time", "Server task time", x -> String.format( "%7.1fms", x / 1e6 ) );
public static final TrackingField PERIPHERAL_OPS = TrackingField.of( "peripheral", "Peripheral calls", x -> String.format( "%6d", x ) );
public static final TrackingField FS_OPS = TrackingField.of( "fs", "Filesystem operations", x -> String.format( "%6d", x ) );
public static final TrackingField TURTLE_OPS = TrackingField.of( "turtle", "Turtle operations", x -> String.format( "%6d", x ) );