mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-21 06:26:55 +00:00
Improvements for coroutine creation
- Keep track of the number of created and destroyed coroutines for each computer. - Run coroutines with a thread pool executor, which will keep stale threads around for 60 seconds. This substantially reduces the pressure from short-lived coroutines. - Update to the latest Cobalt version.
This commit is contained in:
parent
f9c91f288f
commit
93cb6547bd
@ -66,7 +66,7 @@ dependencies {
|
|||||||
|
|
||||||
runtime "mezz.jei:jei_1.12.2:4.8.5.159"
|
runtime "mezz.jei:jei_1.12.2:4.8.5.159"
|
||||||
|
|
||||||
shade 'org.squiddev:Cobalt:0.3.2'
|
shade 'org.squiddev:Cobalt:0.4.0'
|
||||||
|
|
||||||
testCompile 'junit:junit:4.11'
|
testCompile 'junit:junit:4.11'
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public final class HTTPExecutor
|
|||||||
public static final ListeningExecutorService EXECUTOR = MoreExecutors.listeningDecorator( new ThreadPoolExecutor(
|
public static final ListeningExecutorService EXECUTOR = MoreExecutors.listeningDecorator( new ThreadPoolExecutor(
|
||||||
4, Integer.MAX_VALUE,
|
4, Integer.MAX_VALUE,
|
||||||
60L, TimeUnit.SECONDS,
|
60L, TimeUnit.SECONDS,
|
||||||
new SynchronousQueue<Runnable>(),
|
new SynchronousQueue<>(),
|
||||||
new ThreadFactoryBuilder()
|
new ThreadFactoryBuilder()
|
||||||
.setDaemon( true )
|
.setDaemon( true )
|
||||||
.setPriority( Thread.MIN_PRIORITY + (Thread.NORM_PRIORITY - Thread.MIN_PRIORITY) / 2 )
|
.setPriority( Thread.MIN_PRIORITY + (Thread.NORM_PRIORITY - Thread.MIN_PRIORITY) / 2 )
|
||||||
|
@ -6,15 +6,14 @@
|
|||||||
|
|
||||||
package dan200.computercraft.core.lua;
|
package dan200.computercraft.core.lua;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.lua.ILuaContext;
|
import dan200.computercraft.api.lua.*;
|
||||||
import dan200.computercraft.api.lua.ILuaObject;
|
|
||||||
import dan200.computercraft.api.lua.ILuaTask;
|
|
||||||
import dan200.computercraft.api.lua.LuaException;
|
|
||||||
import dan200.computercraft.api.lua.ILuaAPI;
|
|
||||||
import dan200.computercraft.core.computer.Computer;
|
import dan200.computercraft.core.computer.Computer;
|
||||||
import dan200.computercraft.core.computer.ITask;
|
import dan200.computercraft.core.computer.ITask;
|
||||||
import dan200.computercraft.core.computer.MainThread;
|
import dan200.computercraft.core.computer.MainThread;
|
||||||
|
import dan200.computercraft.core.tracking.Tracking;
|
||||||
|
import dan200.computercraft.core.tracking.TrackingField;
|
||||||
import org.squiddev.cobalt.*;
|
import org.squiddev.cobalt.*;
|
||||||
import org.squiddev.cobalt.compiler.CompileException;
|
import org.squiddev.cobalt.compiler.CompileException;
|
||||||
import org.squiddev.cobalt.compiler.LoadState;
|
import org.squiddev.cobalt.compiler.LoadState;
|
||||||
@ -25,7 +24,7 @@ import org.squiddev.cobalt.function.LibFunction;
|
|||||||
import org.squiddev.cobalt.function.LuaFunction;
|
import org.squiddev.cobalt.function.LuaFunction;
|
||||||
import org.squiddev.cobalt.function.VarArgFunction;
|
import org.squiddev.cobalt.function.VarArgFunction;
|
||||||
import org.squiddev.cobalt.lib.*;
|
import org.squiddev.cobalt.lib.*;
|
||||||
import org.squiddev.cobalt.lib.platform.AbstractResourceManipulator;
|
import org.squiddev.cobalt.lib.platform.VoidResourceManipulator;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -35,6 +34,9 @@ import java.util.Arrays;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.SynchronousQueue;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.squiddev.cobalt.Constants.NONE;
|
import static org.squiddev.cobalt.Constants.NONE;
|
||||||
import static org.squiddev.cobalt.ValueFactory.valueOf;
|
import static org.squiddev.cobalt.ValueFactory.valueOf;
|
||||||
@ -42,6 +44,16 @@ import static org.squiddev.cobalt.ValueFactory.varargsOf;
|
|||||||
|
|
||||||
public class CobaltLuaMachine implements ILuaMachine
|
public class CobaltLuaMachine implements ILuaMachine
|
||||||
{
|
{
|
||||||
|
private static final ThreadPoolExecutor coroutines = new ThreadPoolExecutor(
|
||||||
|
0, Integer.MAX_VALUE,
|
||||||
|
60L, TimeUnit.SECONDS,
|
||||||
|
new SynchronousQueue<>(),
|
||||||
|
new ThreadFactoryBuilder()
|
||||||
|
.setDaemon( true )
|
||||||
|
.setNameFormat( "ComputerCraft-Coroutine-%d" )
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
private final Computer m_computer;
|
private final Computer m_computer;
|
||||||
|
|
||||||
private final LuaState m_state;
|
private final LuaState m_state;
|
||||||
@ -57,15 +69,9 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
m_computer = computer;
|
m_computer = computer;
|
||||||
|
|
||||||
// Create an environment to run in
|
// Create an environment to run in
|
||||||
final LuaState state = this.m_state = new LuaState( new AbstractResourceManipulator()
|
LuaState state = this.m_state = LuaState.builder()
|
||||||
{
|
.resourceManipulator( new VoidResourceManipulator() )
|
||||||
@Override
|
.debug( new DebugHandler()
|
||||||
public InputStream findResource( String filename )
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
state.debug = new DebugHandler( state )
|
|
||||||
{
|
{
|
||||||
private int count = 0;
|
private int count = 0;
|
||||||
private boolean hasSoftAbort;
|
private boolean hasSoftAbort;
|
||||||
@ -76,7 +82,7 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
int count = ++this.count;
|
int count = ++this.count;
|
||||||
if( count > 100000 )
|
if( count > 100000 )
|
||||||
{
|
{
|
||||||
if( m_hardAbortMessage != null ) LuaThread.yield( state, NONE );
|
if( m_hardAbortMessage != null ) LuaThread.yield( m_state, NONE );
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -90,19 +96,22 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
@Override
|
@Override
|
||||||
public void poll() throws LuaError
|
public void poll() throws LuaError
|
||||||
{
|
{
|
||||||
if( m_hardAbortMessage != null ) LuaThread.yield( state, NONE );
|
if( m_hardAbortMessage != null ) LuaThread.yield( m_state, NONE );
|
||||||
handleSoftAbort();
|
handleSoftAbort();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSoftAbort() throws LuaError {
|
private void handleSoftAbort() throws LuaError
|
||||||
|
{
|
||||||
// If the soft abort has been cleared then we can reset our flags and continue.
|
// If the soft abort has been cleared then we can reset our flags and continue.
|
||||||
String message = m_softAbortMessage;
|
String message = m_softAbortMessage;
|
||||||
if (message == null) {
|
if( message == null )
|
||||||
|
{
|
||||||
hasSoftAbort = false;
|
hasSoftAbort = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasSoftAbort && m_hardAbortMessage == null) {
|
if( hasSoftAbort && m_hardAbortMessage == null )
|
||||||
|
{
|
||||||
// If we have fired our soft abort, but we haven't been hard aborted then everything is OK.
|
// If we have fired our soft abort, but we haven't been hard aborted then everything is OK.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -110,7 +119,21 @@ public class CobaltLuaMachine implements ILuaMachine
|
|||||||
hasSoftAbort = true;
|
hasSoftAbort = true;
|
||||||
throw new LuaError( message );
|
throw new LuaError( message );
|
||||||
}
|
}
|
||||||
};
|
} )
|
||||||
|
.coroutineFactory( command -> {
|
||||||
|
Tracking.addValue( m_computer, TrackingField.COROUTINES_CREATED, 1 );
|
||||||
|
coroutines.execute( () -> {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
command.run();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Tracking.addValue( m_computer, TrackingField.COROUTINES_DISPOSED, 1 );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
} )
|
||||||
|
.build();
|
||||||
|
|
||||||
m_globals = new LuaTable();
|
m_globals = new LuaTable();
|
||||||
state.setupThread( m_globals );
|
state.setupThread( m_globals );
|
||||||
|
@ -28,6 +28,9 @@ public class TrackingField
|
|||||||
public static final TrackingField WEBSOCKET_INCOMING = TrackingField.of( "websocket_incoming", "Websocket incoming", TrackingField::formatBytes );
|
public static final TrackingField WEBSOCKET_INCOMING = TrackingField.of( "websocket_incoming", "Websocket incoming", TrackingField::formatBytes );
|
||||||
public static final TrackingField WEBSOCKET_OUTGOING = TrackingField.of( "websocket_outgoing", "Websocket outgoing", TrackingField::formatBytes );
|
public static final TrackingField WEBSOCKET_OUTGOING = TrackingField.of( "websocket_outgoing", "Websocket outgoing", TrackingField::formatBytes );
|
||||||
|
|
||||||
|
public static final TrackingField COROUTINES_CREATED = TrackingField.of( "coroutines_created", "Coroutines created", x -> String.format( "%4d", x ) );
|
||||||
|
public static final TrackingField COROUTINES_DISPOSED = TrackingField.of( "coroutines_dead", "Coroutines disposed", x -> String.format( "%4d", x ) );
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
private final LongFunction<String> format;
|
private final LongFunction<String> format;
|
||||||
|
Loading…
Reference in New Issue
Block a user