Merge pull request #4015 from xmcclure/new-threads-collect-fix
authorAndi McClure <andi.mcclure@xamarin.com>
Mon, 28 Nov 2016 15:37:55 +0000 (10:37 -0500)
committerGitHub <noreply@github.com>
Mon, 28 Nov 2016 15:37:55 +0000 (10:37 -0500)
Possibly fix hang in sgen-new-threads-collect.exe

mono/tests/sgen-new-threads-collect.cs

index 5deee6bc2c36115d2191904ece8388e67ca4fb9c..c5d5e4aa26adab5eb928aa7a58f1bdfb5a015c89 100644 (file)
@@ -5,47 +5,60 @@ using System.Threading;
 
 class Driver
 {
+       static DateTime targetTime;
+       static bool finished() {
+               DateTime now = DateTime.UtcNow;
+               return now > targetTime;
+       }
+
        public static void Main ()
        {
-               BlockingCollection<Thread> threads = new BlockingCollection<Thread> (new ConcurrentQueue<Thread> (), 128);
-
-               bool finished = false;
+               int gcCount = 0;
+               int joinCount = 0;
+               targetTime = DateTime.UtcNow.AddSeconds(30);
 
                Thread gcThread = new Thread (() => {
-                       while (!finished) {
+                       while (!finished()) {
                                GC.Collect ();
-                               Thread.Yield ();
-                       }
-               });
-
-               Thread joinThread = new Thread (() => {
-                       for (int i = 0; ; ++i) {
-                               Thread t = threads.Take ();
-                               if (t == null)
-                                       break;
-                               t.Join ();
-                               if ((i + 1) % (50) == 0)
-                                       Console.Write (".");
-                               if ((i + 1) % (50 * 50) == 0)
-                                       Console.WriteLine ();
+                               gcCount++;
+                               Thread.Sleep (1);
                        }
                });
 
                gcThread.Start ();
-               joinThread.Start ();
 
-               for (int i = 0; i < 10 * 1000; ++i) {
-                       Thread t = new Thread (() => { Thread.Yield (); });
-                       t.Start ();
+               // Create threads then join them for 30 seconds nonstop while GCs occur once per ms
+               while (!finished()) {
+                       BlockingCollection<Thread> threads = new BlockingCollection<Thread> (new ConcurrentQueue<Thread> (), 128);
 
-                       threads.Add (t);
-               }
+                       Thread joinThread = new Thread (() => {
+                               for (int i = 0; ; ++i) {
+                                       Thread t = threads.Take ();
+                                       if (t == null)
+                                               break;
+                                       t.Join ();
 
-               threads.Add (null);
+                                       // Uncomment this and run with MONO_LOG_LEVEL=info MONO_LOG_MASK=gc
+                                       // to see GC/join balance in real time
+                                       //Console.Write ("*");
+                               }
+                       });
+                       joinThread.Start ();
+                       
+                       const int makeThreads = 10*1000;
+                       for (int i = 0; i < makeThreads; ++i) {
+                               Thread t = new Thread (() => { Thread.Yield (); });
+                               t.Start ();
 
-               joinThread.Join ();
+                               threads.Add (t);
+                       }
 
-               finished = true;
+                       threads.Add (null);
+                       joinThread.Join ();
+
+                       joinCount += makeThreads;
+                       Console.WriteLine("Performed {0} GCs, created {1} threads. Finished? {2}", gcCount, joinCount, finished());
+               }
                gcThread.Join ();
        }
-}
\ No newline at end of file
+}