Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #2259 Boot from archive - minimal #2433

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions src/kOS.Safe/Execution/CPU.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,13 @@ public void Boot()
shared.Screen.Print(bootMessage);
}

if (!shared.Processor.CheckCanBoot()) return;

VolumePath path = shared.Processor.BootFilePath;
// Check to make sure the boot file name is valid, and then that the boot file exists.
if (path == null)
{
SafeHouse.Logger.Log("Boot file name is empty, skipping boot script");
}
else
else if (shared.Processor.CheckCanBoot())
{
// Boot is only called once right after turning the processor on,
// the volume cannot yet have been changed from that set based on
Expand Down Expand Up @@ -176,6 +174,25 @@ public void Boot()

}
}
else //cannot boot right now
{
shared.Screen?.Print(string.Format(" \nWaiting for connection to boot from {0}.\n \n", path));
var bootContext = "program";
shared.ScriptHandler.ClearContext(bootContext);
IProgramContext programContext = SwitchToProgramContext();
programContext.Silent = true;

string bootCommand = string.Format("run \"{0}\".", path);

var options = new CompilerOptions
{
LoadProgramsInSameAddressSpace = true,
FuncManager = shared.FunctionManager,
IsCalledFromRun = false
};

YieldProgram(YieldFinishedCompileBoot.RunScript(new BootGlobalPath(bootCommand), 1, bootCommand, bootContext, options));
}
}

private void PushInterpreterContext()
Expand Down
47 changes: 19 additions & 28 deletions src/kOS.Safe/Execution/YieldFinishedCompile.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
using kOS.Safe.Compilation;
using kOS.Safe.Compilation;
using kOS.Safe.Encapsulation;
using kOS.Safe.Persistence;
using System.Collections.Generic;
using System.Threading;

namespace kOS.Safe.Execution
{
public class YieldFinishedCompile : YiedFinishedThreadedDetector
public class YieldFinishedCompile : YieldFinishedThreadedDetector
{
private enum CompileMode
protected enum CompileMode
{
RUN = 0,
LOAD = 1,
Expand All @@ -28,29 +28,30 @@ private enum CompileMode

private IProgramContext programContext;

private YieldFinishedCompile(GlobalPath scriptPath, int lineNumber, string fileContent, string contextIdentifier, CompilerOptions compilerOptions)
protected YieldFinishedCompile(CompileMode mode, GlobalPath scriptPath, int lineNumber, string fileContent, string contextIdentifier, CompilerOptions compilerOptions)
{
compileMode = CompileMode.RUN;
compileMode = mode;
path = scriptPath;
startLineNum = lineNumber;
content = fileContent;
contextId = contextIdentifier;
options = compilerOptions;
}

public override void ThreadInitialize(SafeSharedObjects shared)
protected override bool ThreadInitialize()
{
if (compileMode != CompileMode.FILE)
programContext = shared.Cpu.SwitchToProgramContext(); // only switch the context if executing
codeParts = new List<CodePart>();
return true;
}

public override void ThreadExecute()
protected override void ThreadExecute()
{
codeParts = shared.ScriptHandler.Compile(path, startLineNum, content, contextId, options);
}

public override void ThreadFinish()
protected override void ThreadFinish()
{
switch (compileMode)
{
Expand All @@ -76,27 +77,17 @@ public override void ThreadFinish()
shared.Cpu.StopCompileStopwatch();
}

public static YieldFinishedCompile RunScript(GlobalPath scriptPath, int lineNumber, string fileContent, string contextIdentifier, CompilerOptions compilerOptions)
{
var ret = new YieldFinishedCompile(scriptPath, lineNumber, fileContent, contextIdentifier, compilerOptions);
ret.compileMode = CompileMode.RUN;
return ret;
}
public static YieldFinishedCompile RunScript(GlobalPath scriptPath, int lineNumber, string fileContent, string contextIdentifier, CompilerOptions compilerOptions) =>
new YieldFinishedCompile(CompileMode.RUN, scriptPath, lineNumber, fileContent, contextIdentifier, compilerOptions);

public static YieldFinishedCompile LoadScript(GlobalPath scriptPath, int lineNumber, string fileContent, string contextIdentifier, CompilerOptions compilerOptions)
{
var ret = new YieldFinishedCompile(scriptPath, lineNumber, fileContent, contextIdentifier, compilerOptions);
ret.compileMode = CompileMode.LOAD;
return ret;
}
public static YieldFinishedCompile LoadScript(GlobalPath scriptPath, int lineNumber, string fileContent, string contextIdentifier, CompilerOptions compilerOptions) =>
new YieldFinishedCompile(CompileMode.LOAD, scriptPath, lineNumber, fileContent, contextIdentifier, compilerOptions);

public static YieldFinishedCompile CompileScriptToFile(GlobalPath scriptPath, int lineNumber, string fileContent, CompilerOptions compilerOptions, Volume storageVolume, GlobalPath storagePath)
{
var ret = new YieldFinishedCompile(scriptPath, lineNumber, fileContent, string.Empty, compilerOptions);
ret.compileMode = CompileMode.FILE;
ret.volume = storageVolume;
ret.outPath = storagePath;
return ret;
}
public static YieldFinishedCompile CompileScriptToFile(GlobalPath scriptPath, int lineNumber, string fileContent, CompilerOptions compilerOptions, Volume storageVolume, GlobalPath storagePath) =>
new YieldFinishedCompile(CompileMode.FILE, scriptPath, lineNumber, fileContent, string.Empty, compilerOptions)
{
volume = storageVolume,
outPath = storagePath
};
}
}
27 changes: 27 additions & 0 deletions src/kOS.Safe/Execution/YieldFinishedCompileBoot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using kOS.Safe.Compilation;
using kOS.Safe.Encapsulation;
using kOS.Safe.Persistence;
using System.Collections.Generic;
using System.Threading;

namespace kOS.Safe.Execution
{
public class YieldFinishedCompileBoot : YieldFinishedCompile
{
protected YieldFinishedCompileBoot(CompileMode mode, GlobalPath scriptPath, int lineNumber, string fileContent, string contextIdentifier, CompilerOptions compilerOptions) :
base(mode, scriptPath, lineNumber, fileContent, contextIdentifier, compilerOptions)
{ }

protected override bool ThreadInitialize()
{
if (!shared.Processor.CheckCanBoot())
return false;
shared.Screen?.Print("Booting ...\n");
base.ThreadInitialize();
return true;
}

public static new YieldFinishedCompileBoot RunScript(GlobalPath scriptPath, int lineNumber, string fileContent, string contextIdentifier, CompilerOptions compilerOptions) =>
new YieldFinishedCompileBoot(CompileMode.RUN, scriptPath, lineNumber, fileContent, contextIdentifier, compilerOptions);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace kOS.Safe.Execution
{
public abstract class YiedFinishedThreadedDetector : YieldFinishedDetector
public abstract class YieldFinishedThreadedDetector : YieldFinishedDetector
{
private ManualResetEvent childThreadEvent;
private Thread childThread;
Expand All @@ -23,15 +23,23 @@ public override void Begin(SafeSharedObjects sharedObj)

childThreadEvent = new ManualResetEvent(false);

ThreadInitialize(sharedObj);
TryStartThread();
}

childThread = new Thread(DoThread);
childThread.IsBackground = true;
childThread.Start();
private void TryStartThread()
{
if (ThreadInitialize())
{
childThread = new Thread(DoThread);
childThread.IsBackground = true;
childThread.Start();
}
}

public override bool IsFinished()
{
// Thread may not be started yet, but this distinguishes between finished and not-started
// in case IsFinished() gets called multiple times even after it returns true
if (childThreadEvent.WaitOne(0))
{
childThread.Join();
Expand All @@ -46,6 +54,10 @@ public override bool IsFinished()
childException = ex;
}
}

// Remove the reference now, before we potentially (re)throw the exception
childThread = null;

// Note this is *deliberately* NOT an "else" of the above "if" even though
// it looks like it should be. That is because the above IF clause can actually
// alter this flag and if it does so it needs to fall through to here and do this.
Expand All @@ -59,9 +71,12 @@ public override bool IsFinished()
shared.Cpu.BreakExecution(false);
throw childException;
}
childThread = null;
return true;
}
// Try starting the thread now, if not started yet
if (childThread == null)
TryStartThread();

return false;
}

Expand All @@ -82,8 +97,8 @@ private void DoThread()
/// This method is executed before starting the child thread. It is called from the main thread and is not required
/// to be thread safe with respect to KSP.
/// </summary>
/// <param name="shared"></param>
public abstract void ThreadInitialize(SafeSharedObjects shared);
/// <returns>True if ready to start the thread (false if waiting for some condition, e.g. Processor.CheckCanBoot)</returns>
protected abstract bool ThreadInitialize();

/// <summary>
/// <para>
Expand All @@ -96,12 +111,12 @@ private void DoThread()
/// </para>
/// </summary>
/// <param name="shared"></param>
public abstract void ThreadExecute();
protected abstract void ThreadExecute();

/// <summary>
/// This method is executed after the child thread is finished, when the CPU checks IsFinished. It is called from
/// the main thread and is not required to be thread safe with respect to KSP.
/// </summary>
public abstract void ThreadFinish();
protected abstract void ThreadFinish();
}
}
5 changes: 3 additions & 2 deletions src/kOS.Safe/kOS.Safe.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,9 @@
<Compile Include="Execution\TriggerInfo.cs" />
<Compile Include="Execution\Variable.cs" />
<Compile Include="Execution\VariableScope.cs" />
<Compile Include="Execution\YiedFinishedThreadedDetector.cs" />
<Compile Include="Execution\YieldFinishedThreadedDetector.cs" />
<Compile Include="Execution\YieldFinishedCompile.cs" />
<Compile Include="Execution\YieldFinishedCompileBoot.cs" />
<Compile Include="Execution\YieldFinishedDetector.cs" />
<Compile Include="Execution\YieldFinishedGameTimer.cs" />
<Compile Include="Execution\YieldFinishedGetChar.cs" />
Expand Down Expand Up @@ -319,4 +320,4 @@
-->
<ItemGroup />
<ItemGroup />
</Project>
</Project>