PageRenderTime 41ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/base/Applications/Runtime/Full/Singularity/AppRuntime.cs

#
C# | 303 lines | 209 code | 44 blank | 50 comment | 22 complexity | 8ea8a4b0b07b896dee44fa8cde55f72e MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // Note:
  8. //
  9. using System;
  10. using System.Collections;
  11. using System.Reflection;
  12. using System.Threading;
  13. using System.Runtime.CompilerServices;
  14. using System.Runtime.InteropServices;
  15. using Microsoft.Bartok.Runtime;
  16. using Microsoft.Singularity.Io;
  17. using Microsoft.Singularity.V1.Services;
  18. using Microsoft.Singularity.Eventing;
  19. [assembly: AssemblyTitle("Microsoft.Singularity")]
  20. [assembly: AssemblyProduct("Microsoft Research Singularity Runtime")]
  21. [assembly: AssemblyCompany("Microsoft Corporation")]
  22. [assembly: AssemblyVersion("1.0.0.0")]
  23. [assembly: AssemblyKeyFile("public.snk")]
  24. [assembly: AssemblyDelaySign(true)]
  25. namespace Microsoft.Singularity
  26. {
  27. [NoCCtor]
  28. [CLSCompliant(false)]
  29. [AccessedByRuntime("referenced from hal.cpp")]
  30. public class AppRuntime
  31. {
  32. // Note: This function is called by Hal.cpp.
  33. [AccessedByRuntime("referenced from hal.cpp")]
  34. public static unsafe int AppStart(Type userClass)
  35. {
  36. System.GCs.Transitions.ThreadStart();
  37. int result = 0;
  38. string arg0 = "(unknown)";
  39. try {
  40. Tracing.Log(Tracing.Audit, "Runtime.Main()");
  41. // Initialize the primitive runtime, which calls the
  42. // class constructor for Runtime().
  43. VTable.Initialize((RuntimeType)typeof(AppRuntime));
  44. //VTable.ParseArgs(args);
  45. Tracing.Log(Tracing.Audit, "Enabling GC Heap");
  46. GC.EnableHeap();
  47. Controller.InitializeSystem();
  48. GCProfilerLogger.StartProfiling();
  49. InitializeConsole();
  50. SetDebuggerPresence(DebugService.IsDebuggerPresent());
  51. int argCount = 0;
  52. int argMaxLen = 0;
  53. for (;; argCount++) {
  54. int len = ProcessService.GetStartupArg(argCount, null, 0);
  55. if (len == 0) {
  56. break;
  57. }
  58. if (argMaxLen < len) {
  59. argMaxLen = len;
  60. }
  61. }
  62. char[] argArray = new char [argMaxLen];
  63. string[] args = new string[argCount];
  64. for (int arg = 0; arg < argCount; arg++) {
  65. fixed (char *argptr = &argArray[0]) {
  66. int len = ProcessService.GetStartupArg(arg,
  67. argptr,
  68. argArray.Length);
  69. args[arg] = String.StringCTOR(argptr, 0, len);
  70. if (arg == 0)
  71. arg0 = args[arg];
  72. }
  73. }
  74. #if DEBUG || true
  75. // Record the first argument passed to this program, under the assumption that
  76. // this is the application name. We use this string in DebugStub.WriteLine.
  77. // Also, if the name has an extension, such as ".x86", chop it off.
  78. // Also chop off any path prefix, such as "/init/".
  79. appName = arg0;
  80. int index = appName.LastIndexOf('.');
  81. if (index != -1)
  82. appName = appName.Substring(0, index);
  83. index = appName.LastIndexOf('/');
  84. if (index != -1)
  85. appName = appName.Substring(index + 1);
  86. // The default DebugName value for the main thread is "main";
  87. // apps can override this by setting Thread.CurrentThread.DebugName.
  88. Thread mainThread = Thread.CurrentThread;
  89. if (mainThread != null) {
  90. mainThread.DebugName = "main";
  91. }
  92. #endif
  93. if (userClass != null) {
  94. VTable.initType((RuntimeType)userClass);
  95. }
  96. result = CallMain(args);
  97. if (!MainReturnsInt()) result = 0;
  98. Tracing.Log(Tracing.Audit, "Main thread exited [{0}]",
  99. (UIntPtr)unchecked((uint)result));
  100. }
  101. catch (Exception e) {
  102. Tracing.Log(Tracing.Fatal, "Failed with exception {0}.{1}",
  103. e.GetType().Namespace, e.GetType().Name);
  104. Tracing.Log(Tracing.Trace, "Exception message was {0}",
  105. e.ToString());
  106. TopLevelException(e);
  107. result = -1;
  108. }
  109. Thread.RemoveThread(Thread.CurrentThread.threadIndex);
  110. Thread.JoinAll();
  111. try {
  112. FinalizeConsole();
  113. }
  114. catch (Exception e) {
  115. Tracing.Log(Tracing.Fatal, "An exception occurred while shutting down the console: {0}",
  116. e.ToString());
  117. }
  118. Controller.Finalize();
  119. Tracing.Log(Tracing.Audit, "Runtime shutdown started.");
  120. VTable.Shutdown(result);
  121. Tracing.Log(Tracing.Audit, "Runtime exiting [{0}]",
  122. (UIntPtr)unchecked((uint)result));
  123. return result;
  124. }
  125. /// <summary>
  126. /// This method runs when the "main" thread terminates by throwing an exception.
  127. /// It is a separate method, rather than simply code within the AppStart method,
  128. /// in order to make life easier during debugging.
  129. /// </summary>
  130. /// <param name="ex"></param>
  131. private static void TopLevelException(Exception/*!*/ ex)
  132. {
  133. DebugStub.WriteLine("AppRuntime: Main app thread terminated with exception:");
  134. for (Exception focus = ex; focus != null; focus = focus.InnerException) {
  135. DebugStub.WriteLine("{0}: {1}", __arglist(focus.GetType().FullName, focus.Message));
  136. }
  137. }
  138. #if DEBUG || true
  139. /// <summary>
  140. /// Returns the name of the application, as determined by the first parameter
  141. /// passed in the argv block. This property is only present on DEBUG builds
  142. /// (Debug and Prototype). It is provided for DebugStub.WriteLine, to provide
  143. /// useful debugging spew.
  144. /// </summary>
  145. public static string AppName
  146. {
  147. [NoHeapAllocation]
  148. get
  149. {
  150. return appName;
  151. }
  152. }
  153. private static string appName;
  154. #endif
  155. [AccessedByRuntime("output to header : defined in hal.cpp")]
  156. [MethodImpl(MethodImplOptions.InternalCall)]
  157. [StackBound(256)]
  158. private static extern int CallMain(String[] args);
  159. [AccessedByRuntime("output to header: defined in hal.cpp")]
  160. [MethodImpl(MethodImplOptions.InternalCall)]
  161. [StackBound(256)]
  162. private static extern bool MainReturnsInt();
  163. [AccessedByRuntime("output to header: defined in hal.cpp")]
  164. [MethodImpl(MethodImplOptions.InternalCall)]
  165. [StackBound(256)]
  166. private static extern void SetDebuggerPresence(bool debuggerPresent);
  167. internal static void Shutdown(int exitCode)
  168. {
  169. //
  170. // Gracefully close down the process.
  171. //
  172. Tracing.Log(Tracing.Audit, "Runtime.Shutdown({0})",
  173. (UIntPtr)unchecked((uint)exitCode));
  174. DebugStub.WriteLine("Runtime.Shutdown({0})", __arglist(exitCode));
  175. VTable.Shutdown(exitCode);
  176. Tracing.Log(Tracing.Audit, "Runtime.Shutdown({0}) terminating",
  177. (UIntPtr)unchecked((uint)exitCode));
  178. ProcessService.Stop(exitCode);
  179. }
  180. internal static void Stop(int exitCode)
  181. {
  182. //
  183. // Halt the process immediately.
  184. //
  185. Tracing.Log(Tracing.Audit, "Runtime.Stop({0})",
  186. (UIntPtr)unchecked((uint)exitCode));
  187. DebugStub.WriteLine("Runtime.Stop({0})", __arglist(exitCode));
  188. ProcessService.Stop(exitCode);
  189. }
  190. //////////////////////////////////////////////////////////////////////
  191. //
  192. [NoHeapAllocation]
  193. public static UIntPtr AddressOf(Object o)
  194. {
  195. return Magic.addressOf(o);
  196. }
  197. [NoHeapAllocation]
  198. public static UIntPtr SizeOf(Object o)
  199. {
  200. return System.GCs.ObjectLayout.Sizeof(o);
  201. }
  202. public static void InitType(Type ty)
  203. {
  204. VTable.initType((RuntimeType) ty);
  205. }
  206. public static void DumpPageTable()
  207. {
  208. System.GCs.PageTable.Dump("PageTable");
  209. }
  210. //////////////////////////////////////////////////////////////////////
  211. //
  212. public static bool EnableGCVerify
  213. {
  214. get {
  215. return VTable.enableGCVerify;
  216. }
  217. set {
  218. VTable.enableGCVerify = value;
  219. }
  220. }
  221. public static bool EnableGCAccounting
  222. {
  223. get {
  224. return VTable.enableGCAccounting;
  225. }
  226. set {
  227. VTable.enableGCAccounting = value;
  228. if (value == true) {
  229. System.GCs.MemoryAccounting.Initialize(GC.gcType);
  230. }
  231. }
  232. }
  233. public static uint GCPerfCounter
  234. {
  235. get {
  236. return System.GC.perfCounter;
  237. }
  238. set {
  239. System.GC.perfCounter = value;
  240. }
  241. }
  242. /// <summary>
  243. /// This stub method is provided for so that System.Console.dll can override it for those
  244. /// apps that want a console. This is necessary, in order to initialize and shutdown the
  245. /// console at the right time.
  246. /// </summary>
  247. private static void InitializeConsole()
  248. {
  249. }
  250. /// <summary>
  251. /// This stub method is provided for so that System.Console.dll can override it for those
  252. /// apps that want a console. This is necessary, in order to initialize and shutdown the
  253. /// console at the right time.
  254. /// </summary>
  255. private static void FinalizeConsole()
  256. {
  257. }
  258. }
  259. }