225 lines
7.1 KiB
C#
225 lines
7.1 KiB
C#
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
// File: Runtime.cs
|
||
|
//
|
||
|
// Note:
|
||
|
//
|
||
|
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.Reflection;
|
||
|
using System.Threading;
|
||
|
using System.Runtime.CompilerServices;
|
||
|
using System.Runtime.InteropServices;
|
||
|
|
||
|
using Microsoft.Bartok.Runtime;
|
||
|
|
||
|
#if !MINRUNTIME
|
||
|
using Microsoft.Singularity.Io;
|
||
|
#endif
|
||
|
using Microsoft.Singularity.V1.Services;
|
||
|
|
||
|
[assembly: AssemblyTitle("Microsoft.Singularity")]
|
||
|
[assembly: AssemblyProduct("Microsoft Research Singularity Runtime")]
|
||
|
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||
|
[assembly: AssemblyKeyFile("public.snk")]
|
||
|
[assembly: AssemblyDelaySign(true)]
|
||
|
|
||
|
namespace Microsoft.Singularity
|
||
|
{
|
||
|
|
||
|
[NoCCtor]
|
||
|
[CLSCompliant(false)]
|
||
|
public class AppRuntime
|
||
|
{
|
||
|
// Note: This function is called by Hal.cpp.
|
||
|
[AccessedByRuntime("referenced from hal.cpp")]
|
||
|
public static unsafe int AppStart(Type userClass)
|
||
|
{
|
||
|
System.GCs.Transitions.ThreadStart();
|
||
|
|
||
|
int result = 0;
|
||
|
|
||
|
try {
|
||
|
Tracing.Log(Tracing.Audit, "Runtime.Main()");
|
||
|
|
||
|
// Initialize the primitive runtime, which calls the
|
||
|
// class constructor for Runtime().
|
||
|
VTable.Initialize((RuntimeType)typeof(AppRuntime));
|
||
|
/*VTable.ParseArgs(args);*/
|
||
|
|
||
|
Tracing.Log(Tracing.Audit, "Enabling GC Heap");
|
||
|
GC.EnableHeap();
|
||
|
|
||
|
#if !MINRUNTIME
|
||
|
ConsoleOutput.Initialize();
|
||
|
ConsoleInput.Initialize();
|
||
|
#endif
|
||
|
|
||
|
SetDebuggerPresence(DebugService.IsDebuggerPresent());
|
||
|
|
||
|
int argCount = 0;
|
||
|
int argMaxLen = 0;
|
||
|
for (;; argCount++) {
|
||
|
int len = ProcessService.GetStartupArg(argCount, null, 0);
|
||
|
if (len == 0) {
|
||
|
break;
|
||
|
}
|
||
|
if (argMaxLen < len) {
|
||
|
argMaxLen = len;
|
||
|
}
|
||
|
}
|
||
|
char[] argArray = new char [argMaxLen];
|
||
|
string[] args = new string[argCount];
|
||
|
for (int arg = 0; arg < argCount; arg++) {
|
||
|
fixed (char *argptr = &argArray[0]) {
|
||
|
int len = ProcessService.GetStartupArg(arg,
|
||
|
argptr,
|
||
|
argArray.Length);
|
||
|
args[arg] = String.StringCTOR(argptr, 0, len);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (userClass != null) {
|
||
|
VTable.initType((RuntimeType)userClass);
|
||
|
}
|
||
|
|
||
|
result = CallMain(args);
|
||
|
if (!MainReturnsInt()) result = 0;
|
||
|
Thread.RemoveThread(Thread.CurrentThread.threadIndex);
|
||
|
|
||
|
Thread.JoinAll();
|
||
|
|
||
|
#if !MINRUNTIME
|
||
|
ConsoleOutput.Finalize();
|
||
|
ConsoleInput.Finalize();
|
||
|
#endif
|
||
|
Tracing.Log(Tracing.Audit, "Main thread exited [{0}]",
|
||
|
(UIntPtr)unchecked((uint)result));
|
||
|
}
|
||
|
catch (Exception e) {
|
||
|
Tracing.Log(Tracing.Fatal, "Failed with exception {0}.{1}",
|
||
|
e.GetType().Namespace, e.GetType().Name);
|
||
|
Tracing.Log(Tracing.Trace, "Exception message was {0}",
|
||
|
e.ToString());
|
||
|
DebugStub.WriteLine("Caught {0}", __arglist(e.Message));
|
||
|
result = -1;
|
||
|
}
|
||
|
|
||
|
Tracing.Log(Tracing.Audit, "Runtime shutdown started.");
|
||
|
VTable.Shutdown(result);
|
||
|
Tracing.Log(Tracing.Audit, "Runtime exiting [{0}]",
|
||
|
(UIntPtr)unchecked((uint)result));
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
[AccessedByRuntime("output to header : defined in hal.cpp")]
|
||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||
|
[StackBound(256)]
|
||
|
private static extern int CallMain(String[] args);
|
||
|
|
||
|
[AccessedByRuntime("output to header: defined in hal.cpp")]
|
||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||
|
[StackBound(256)]
|
||
|
private static extern bool MainReturnsInt();
|
||
|
|
||
|
[AccessedByRuntime("output to header: defined in hal.cpp")]
|
||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||
|
[StackBound(256)]
|
||
|
private static extern void SetDebuggerPresence(bool debuggerPresent);
|
||
|
|
||
|
internal static void Shutdown(int exitCode)
|
||
|
{
|
||
|
//
|
||
|
// Gracefully close down the process.
|
||
|
//
|
||
|
Tracing.Log(Tracing.Audit, "Runtime.Shutdown({0})",
|
||
|
(UIntPtr)unchecked((uint)exitCode));
|
||
|
|
||
|
DebugStub.WriteLine("Runtime.Shutdown({0})", __arglist(exitCode));
|
||
|
|
||
|
VTable.Shutdown(exitCode);
|
||
|
Tracing.Log(Tracing.Audit, "Runtime.Shutdown({0}) terminating",
|
||
|
(UIntPtr)unchecked((uint)exitCode));
|
||
|
ProcessService.Stop(exitCode);
|
||
|
}
|
||
|
|
||
|
internal static void Stop(int exitCode)
|
||
|
{
|
||
|
//
|
||
|
// Halt the process immediately.
|
||
|
//
|
||
|
Tracing.Log(Tracing.Audit, "Runtime.Stop({0})",
|
||
|
(UIntPtr)unchecked((uint)exitCode));
|
||
|
|
||
|
DebugStub.WriteLine("Runtime.Stop({0})", __arglist(exitCode));
|
||
|
|
||
|
ProcessService.Stop(exitCode);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
[NoHeapAllocation]
|
||
|
public static UIntPtr AddressOf(Object o)
|
||
|
{
|
||
|
return Magic.addressOf(o);
|
||
|
}
|
||
|
|
||
|
[NoHeapAllocation]
|
||
|
public static UIntPtr SizeOf(Object o)
|
||
|
{
|
||
|
return System.GCs.ObjectLayout.Sizeof(o);
|
||
|
}
|
||
|
|
||
|
public static void InitType(Type ty)
|
||
|
{
|
||
|
VTable.initType((RuntimeType) ty);
|
||
|
}
|
||
|
|
||
|
public static void DumpPageTable()
|
||
|
{
|
||
|
System.GCs.PageTable.Dump("PageTable");
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
public static bool EnableGCVerify
|
||
|
{
|
||
|
get {
|
||
|
return VTable.enableGCVerify;
|
||
|
}
|
||
|
set {
|
||
|
VTable.enableGCVerify = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool EnableGCAccounting
|
||
|
{
|
||
|
get {
|
||
|
return VTable.enableGCAccounting;
|
||
|
}
|
||
|
set {
|
||
|
VTable.enableGCAccounting = value;
|
||
|
if (value == true) {
|
||
|
System.GCs.MemoryAccounting.Initialize(GC.gcType);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static uint GCPerfCounter
|
||
|
{
|
||
|
get {
|
||
|
return System.GC.perfCounter;
|
||
|
}
|
||
|
set {
|
||
|
System.GC.perfCounter = value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|