Skip to content

Commit bfbb18b

Browse files
committed
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.
1 parent cac65ef commit bfbb18b

7 files changed

Lines changed: 118 additions & 23 deletions

File tree

src/main/java/dan200/computercraft/core/computer/ComputerThread.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,17 @@ public static void start()
6969
s_stopped = false;
7070
if( s_threads == null || s_threads.length != ComputerCraft.computer_threads )
7171
{
72-
s_threads = new Thread[ ComputerCraft.computer_threads ];
72+
s_threads = new Thread[ComputerCraft.computer_threads];
7373
}
7474

7575
SecurityManager manager = System.getSecurityManager();
7676
final ThreadGroup group = manager == null ? Thread.currentThread().getThreadGroup() : manager.getThreadGroup();
7777
for( int i = 0; i < s_threads.length; i++ )
7878
{
79-
Thread thread = s_threads[ i ];
79+
Thread thread = s_threads[i];
8080
if( thread == null || !thread.isAlive() )
8181
{
82-
thread = s_threads[ i ] = new Thread( group, new TaskExecutor(), "ComputerCraft-Computer-Manager-" + s_ManagerCounter.getAndIncrement() );
82+
thread = s_threads[i] = new Thread( group, new TaskExecutor(), "ComputerCraft-Computer-Manager-" + s_ManagerCounter.getAndIncrement() );
8383
thread.setDaemon( true );
8484
thread.start();
8585
}
@@ -251,8 +251,8 @@ private void execute( BlockingQueue<ITask> queue ) throws InterruptedException
251251
{
252252
long stop = System.nanoTime();
253253
Computer computer = task.getOwner();
254-
if( computer != null ) Tracking.addTiming( computer, stop - start );
255-
254+
if( computer != null ) Tracking.addTaskTiming( computer, stop - start );
255+
256256
// Re-add it back onto the queue or remove it
257257
synchronized( s_taskLock )
258258
{

src/main/java/dan200/computercraft/core/computer/MainThread.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@
66

77
package dan200.computercraft.core.computer;
88

9-
import java.util.LinkedList;
9+
import dan200.computercraft.core.tracking.Tracking;
10+
11+
import java.util.ArrayDeque;
12+
import java.util.Queue;
1013

1114
public class MainThread
1215
{
1316
private static final int MAX_TASKS_PER_TICK = 1000;
1417
private static final int MAX_TASKS_TOTAL = 50000;
1518

16-
private static final LinkedList<ITask> m_outstandingTasks = new LinkedList<>();
19+
private static final Queue<ITask> m_outstandingTasks = new ArrayDeque<>();
1720
private static final Object m_nextUnusedTaskIDLock = new Object();
1821
private static long m_nextUnusedTaskID = 0;
1922

@@ -31,7 +34,7 @@ public static boolean queueTask( ITask task )
3134
{
3235
if( m_outstandingTasks.size() < MAX_TASKS_TOTAL )
3336
{
34-
m_outstandingTasks.addLast( task );
37+
m_outstandingTasks.offer( task );
3538
return true;
3639
}
3740
}
@@ -46,14 +49,17 @@ public static void executePendingTasks()
4649
ITask task = null;
4750
synchronized( m_outstandingTasks )
4851
{
49-
if( m_outstandingTasks.size() > 0 )
50-
{
51-
task = m_outstandingTasks.removeFirst();
52-
}
52+
task = m_outstandingTasks.poll();
5353
}
5454
if( task != null )
5555
{
56+
long start = System.nanoTime();
5657
task.execute();
58+
59+
long stop = System.nanoTime();
60+
Computer computer = task.getOwner();
61+
if( computer != null ) Tracking.addServerTiming( computer, stop - start );
62+
5763
++tasksThisTick;
5864
}
5965
else

src/main/java/dan200/computercraft/core/tracking/ComputerTracker.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ public class ComputerTracker
1515
private long totalTime;
1616
private long maxTime;
1717

18+
private long serverCount;
19+
private long serverTime;
20+
1821
private final TObjectLongHashMap<TrackingField> fields;
1922

2023
public ComputerTracker( Computer computer )
@@ -32,10 +35,13 @@ public ComputerTracker( Computer computer )
3235
this.tasks = timings.tasks;
3336
this.totalTime = timings.totalTime;
3437
this.maxTime = timings.maxTime;
38+
39+
this.serverCount = timings.serverCount;
40+
this.serverTime = timings.serverTime;
41+
3542
this.fields = new TObjectLongHashMap<>( timings.fields );
3643
}
3744

38-
3945
@Nullable
4046
public Computer getComputer()
4147
{
@@ -67,13 +73,19 @@ public long getAverage()
6773
return totalTime / tasks;
6874
}
6975

70-
void addTiming( long time )
76+
void addTaskTiming( long time )
7177
{
7278
tasks++;
7379
totalTime += time;
7480
if( time > maxTime ) maxTime = time;
7581
}
7682

83+
void addMainTiming( long time )
84+
{
85+
serverCount++;
86+
serverTime += time;
87+
}
88+
7789
void addValue( TrackingField field, long change )
7890
{
7991
synchronized( fields )
@@ -89,6 +101,9 @@ public long get( TrackingField field )
89101
if( field == TrackingField.TOTAL_TIME ) return totalTime;
90102
if( field == TrackingField.AVERAGE_TIME ) return totalTime / tasks;
91103

104+
if( field == TrackingField.SERVER_COUNT ) return serverCount;
105+
if( field == TrackingField.SERVER_TIME ) return serverTime;
106+
92107
synchronized( fields )
93108
{
94109
return fields.get( field );

src/main/java/dan200/computercraft/core/tracking/Tracker.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,46 @@
44

55
public interface Tracker
66
{
7-
void addTiming( Computer computer, long time );
7+
@Deprecated
8+
default void addTiming( Computer computer, long time )
9+
{
10+
}
811

9-
void addValue( Computer computer, TrackingField field, long change );
12+
/**
13+
* Report how long a task executed on the computer thread took.
14+
*
15+
* Computer thread tasks include events or a computer being turned on/off.
16+
*
17+
* @param computer The computer processing this task
18+
* @param time The time taken for this task.
19+
*/
20+
default void addTaskTiming( Computer computer, long time )
21+
{
22+
//noinspection deprecation
23+
addTiming( computer, time );
24+
}
25+
26+
/**
27+
* Report how long a task executed on the server thread took.
28+
*
29+
* Server tasks include actions performed by peripherals.
30+
*
31+
* @param computer The computer processing this task
32+
* @param time The time taken for this task.
33+
*/
34+
default void addServerTiming( Computer computer, long time )
35+
{
36+
}
37+
38+
/**
39+
* Increment an arbitrary field by some value. Implementations may track how often this is called
40+
* as well as the change, to compute some level of "average".
41+
*
42+
* @param computer The computer to increment
43+
* @param field The field to increment.
44+
* @param change The amount to increment said field by.
45+
*/
46+
default void addValue( Computer computer, TrackingField field, long change )
47+
{
48+
}
1049
}

src/main/java/dan200/computercraft/core/tracking/Tracking.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,25 @@ public static void add( Tracker tracker )
3535
}
3636
}
3737

38-
public static void addTiming( Computer computer, long time )
38+
public static void addTaskTiming( Computer computer, long time )
3939
{
4040
if( tracking.get() == 0 ) return;
4141

4242
synchronized( contexts )
4343
{
44-
for( TrackingContext context : contexts.values() ) context.addTiming( computer, time );
45-
for( Tracker tracker : trackers ) tracker.addTiming( computer, time );
44+
for( TrackingContext context : contexts.values() ) context.addTaskTiming( computer, time );
45+
for( Tracker tracker : trackers ) tracker.addTaskTiming( computer, time );
46+
}
47+
}
48+
49+
public static void addServerTiming( Computer computer, long time )
50+
{
51+
if( tracking.get() == 0 ) return;
52+
53+
synchronized( contexts )
54+
{
55+
for( TrackingContext context : contexts.values() ) context.addServerTiming( computer, time );
56+
for( Tracker tracker : trackers ) tracker.addServerTiming( computer, time );
4657
}
4758
}
4859

src/main/java/dan200/computercraft/core/tracking/TrackingContext.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* Note that this <em>will</em> track computers which have been deleted (hence
1515
* the presence of {@link #timingLookup} and {@link #timings}
1616
*/
17-
public class TrackingContext
17+
public class TrackingContext implements Tracker
1818
{
1919
private boolean tracking = false;
2020

@@ -52,7 +52,8 @@ public synchronized List<ComputerTracker> getTimings()
5252
return new ArrayList<>( timings );
5353
}
5454

55-
public void addTiming( Computer computer, long time )
55+
@Override
56+
public void addTaskTiming( Computer computer, long time )
5657
{
5758
if( !tracking ) return;
5859

@@ -66,11 +67,31 @@ public void addTiming( Computer computer, long time )
6667
timings.add( computerTimings );
6768
}
6869

69-
computerTimings.addTiming( time );
70+
computerTimings.addTaskTiming( time );
7071
}
7172
}
7273

73-
public synchronized void addValue( Computer computer, TrackingField field, long change )
74+
@Override
75+
public void addServerTiming( Computer computer, long time )
76+
{
77+
if( !tracking ) return;
78+
79+
synchronized( this )
80+
{
81+
ComputerTracker computerTimings = timingLookup.get( computer );
82+
if( computerTimings == null )
83+
{
84+
computerTimings = new ComputerTracker( computer );
85+
timingLookup.put( computer, computerTimings );
86+
timings.add( computerTimings );
87+
}
88+
89+
computerTimings.addMainTiming( time );
90+
}
91+
}
92+
93+
@Override
94+
public void addValue( Computer computer, TrackingField field, long change )
7495
{
7596
if( !tracking ) return;
7697

src/main/java/dan200/computercraft/core/tracking/TrackingField.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ public class TrackingField
1414
public static final TrackingField AVERAGE_TIME = TrackingField.of( "average", "Average time", x -> String.format( "%4.1fms", x / 1e6 ) );
1515
public static final TrackingField MAX_TIME = TrackingField.of( "max", "Max time", x -> String.format( "%5.1fms", x / 1e6 ) );
1616

17+
public static final TrackingField SERVER_COUNT = TrackingField.of( "server_count", "Server task count", x -> String.format( "%4d", x ) );
18+
public static final TrackingField SERVER_TIME = TrackingField.of( "server_time", "Server task time", x -> String.format( "%7.1fms", x / 1e6 ) );
19+
1720
public static final TrackingField PERIPHERAL_OPS = TrackingField.of( "peripheral", "Peripheral calls", x -> String.format( "%6d", x ) );
1821
public static final TrackingField FS_OPS = TrackingField.of( "fs", "Filesystem operations", x -> String.format( "%6d", x ) );
1922
public static final TrackingField TURTLE_OPS = TrackingField.of( "turtle", "Turtle operations", x -> String.format( "%6d", x ) );

0 commit comments

Comments
 (0)