PageRenderTime 67ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/base/Applications/Godot/Godot.cs

#
C# | 191 lines | 130 code | 32 blank | 29 comment | 5 complexity | d1213d813f3a3ec6f9a5442079d7fb6f MD5 | raw file
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // Note: Singularity wait primitives test program.
  8. //
  9. using Microsoft.Singularity.V1.Services;
  10. using Microsoft.Singularity.V1.Threads;
  11. using System;
  12. using System.Runtime.CompilerServices;
  13. using System.Threading;
  14. using Microsoft.Contracts;
  15. using Microsoft.SingSharp.Reflection;
  16. using Microsoft.Singularity.Applications;
  17. using Microsoft.Singularity.Channels;
  18. using Microsoft.Singularity.Io;
  19. using Microsoft.Singularity.Configuration;
  20. [assembly: Transform(typeof(ApplicationResourceTransform))]
  21. namespace Microsoft.Singularity.Applications
  22. {
  23. [ConsoleCategory(HelpMessage="Showcase thread synchronization with Mutex/Waithandle", DefaultAction=true)]
  24. internal class Parameters {
  25. [InputEndpoint("data")]
  26. public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
  27. [OutputEndpoint("data")]
  28. public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
  29. [LongParameter( "t", Default=2, HelpMessage="Number of Waiters (threads)")]
  30. internal long numberOfWaiters;
  31. [BoolParameter( "d", Default=false, HelpMessage="Debug Mode")]
  32. internal bool debugMode;
  33. reflective internal Parameters();
  34. internal int AppMain() {
  35. return Godot.AppMain(this);
  36. }
  37. }
  38. public class Godot
  39. {
  40. private static Mutex! mutex;
  41. private static WaitHandle[]! waiters;
  42. private static WaitHandle[]! others;
  43. private static String[]! names;
  44. private static WaiterThread[] threadDetails;
  45. private static Thread[] threads;
  46. private static bool debugMode;
  47. private class WaiterThread {
  48. private uint myIndex;
  49. public WaiterThread(uint index) {
  50. myIndex = index;
  51. }
  52. public void Go()
  53. {
  54. String myName = names[myIndex];
  55. Write(String.Format("Enter Thread {0}\n", myName));
  56. Write(String.Format(" {0}: signaling auto-reset event\n", myName));
  57. ((AutoResetEvent!)waiters[myIndex]).Set();
  58. for (uint Loop = 0; Loop < 5; Loop++) {
  59. Write(String.Format(" {0}: waiting for mutex\n", myName));
  60. mutex.WaitOne();
  61. Write(String.Format(" {0}: got mutex\n", myName));
  62. Thread.Sleep(1000);
  63. Write(String.Format(" {0}: releasing mutex\n", myName));
  64. mutex.ReleaseMutex();
  65. Thread.Yield();
  66. }
  67. //
  68. // Tell other waiters we're done.
  69. //
  70. Write(String.Format(" {0}: signaling manual-reset event\n", myName));
  71. ((ManualResetEvent!)others[myIndex]).Set();
  72. //
  73. // Wait for other waiter.
  74. //
  75. Write(String.Format(" {0}: waiting for other waiters\n", myName));
  76. foreach (WaitHandle! other in others) {
  77. other.WaitOne();
  78. }
  79. Write(String.Format(" {0}: heard from other waiters\n", myName));
  80. Write(String.Format("Exit Thread {0}\n", myName));
  81. }
  82. }
  83. public static void Usage()
  84. {
  85. Console.WriteLine("\nUsage: godot [NumberOfWaitThreads]\n\n");
  86. }
  87. internal static int AppMain(Parameters! config)
  88. {
  89. uint numberOfWaiters = (uint) config.numberOfWaiters;
  90. debugMode = config.debugMode;
  91. Write(String.Format("\nStarting wait test with {0} wait threads\n\n",
  92. numberOfWaiters));
  93. names = new String[4];
  94. names[0] = "Estragon";
  95. names[1] = "Vladimir";
  96. names[2] = "Lucky";
  97. names[3] = "Pozzo";
  98. //
  99. // Create some synchronization primitives to test.
  100. //
  101. mutex = new Mutex(true);
  102. waiters = new WaitHandle[numberOfWaiters];
  103. others = new WaitHandle[numberOfWaiters];
  104. for (uint Loop = 0; Loop < numberOfWaiters; Loop++) {
  105. waiters[Loop] = new AutoResetEvent(false);
  106. others[Loop] = new ManualResetEvent(false);
  107. }
  108. Write("Created synchronization primitives\n\n");
  109. //
  110. // Fire up the waiters.
  111. //
  112. threads = new Thread[numberOfWaiters];
  113. threadDetails = new WaiterThread[numberOfWaiters];
  114. for (uint Loop = 0; Loop < numberOfWaiters; Loop++) {
  115. threadDetails[Loop] = new WaiterThread(Loop);
  116. threads[Loop] = new Thread(
  117. new ThreadStart(threadDetails[Loop].Go));
  118. ((!)threads[Loop]).Start();
  119. }
  120. //
  121. // Wait for the waiters to tell us they're about to start waiting.
  122. //
  123. Write("Waiting for all waiters to start\n");
  124. foreach (WaitHandle! waiter in waiters) {
  125. waiter.WaitOne();
  126. }
  127. //
  128. // Release the Mutex to the wolves.
  129. //
  130. Write("About to release mutex\n");
  131. mutex.ReleaseMutex();
  132. Write("Mutex released\n");
  133. //
  134. // Wait for the threads to die.
  135. //
  136. #if false
  137. #if NOT_YET
  138. Write("Waiting for all waiters to terminate\n");
  139. for (uint Loop = 0; Loop < numberOfWaiters; Loop++) {
  140. threads[Loop].Join();
  141. }
  142. #else
  143. Write("Waiting for 30 sec while threads play\n");
  144. Thread.Sleep(30000);
  145. #endif
  146. #endif
  147. Write("Goodbye\n");
  148. return 0;
  149. }
  150. private static void Write(string s)
  151. {
  152. string msg = "Godot:" + s;
  153. Console.Write(msg);
  154. if (debugMode) {
  155. DebugStub.Write(msg);
  156. }
  157. }
  158. }
  159. }