* [sgen] Add stress test
This hope to suspend a thread while it is in the process of attaching or detaching.
* [sgen] Fix unified suspend
This would cause a crash with unified suspend: if a thread would be suspended at mono-threads.c:1168, the stack_start would be greater than the stack_end, triggering the g_error at sgen-stw.c:351. The stack_end would initially be initialized in `sgen_client_thread_register`, but it would be overriden in start_wrapper at threads.c:893.
{
volatile gsize dummy;
- /* Avoid scanning the frames above this frame during a GC */
- mono_gc_set_stack_end ((void*)&dummy);
-
return start_wrapper_internal ((StartInfo*) data, (gsize*) &dummy);
}
@$(MCS) -r:TestDriver.dll $(srcdir)/debug-casts.cs
@$(RUNTIME) --debug=casts debug-casts.exe
-EXTRA_DIST += sgen-bridge.cs sgen-descriptors.cs sgen-gshared-vtype.cs sgen-bridge-major-fragmentation.cs sgen-domain-unload.cs sgen-weakref-stress.cs sgen-cementing-stress.cs sgen-case-23400.cs finalizer-wait.cs critical-finalizers.cs sgen-domain-unload-2.cs sgen-suspend.cs sgen-new-threads-dont-join-stw.cs sgen-new-threads-dont-join-stw-2.cs sgen-bridge-xref.cs bug-17590.cs sgen-toggleref.cs sgen-bridge-gchandle.cs
+EXTRA_DIST += sgen-bridge.cs sgen-descriptors.cs sgen-gshared-vtype.cs sgen-bridge-major-fragmentation.cs sgen-domain-unload.cs sgen-weakref-stress.cs sgen-cementing-stress.cs sgen-case-23400.cs finalizer-wait.cs critical-finalizers.cs sgen-domain-unload-2.cs sgen-suspend.cs sgen-new-threads-dont-join-stw.cs sgen-new-threads-dont-join-stw-2.cs sgen-new-threads-collect.cs sgen-bridge-xref.cs bug-17590.cs sgen-toggleref.cs sgen-bridge-gchandle.cs
sgen-tests:
sgen-case-23400.exe \
sgen-new-threads-dont-join-stw.exe \
sgen-new-threads-dont-join-stw-2.exe \
+ sgen-new-threads-collect.exe \
gc-graystack-stress.exe \
bug-17590.exe
--- /dev/null
+
+using System;
+using System.Collections.Concurrent;
+using System.Threading;
+
+class Driver
+{
+ public static void Main ()
+ {
+ BlockingCollection<Thread> threads = new BlockingCollection<Thread> (new ConcurrentQueue<Thread> (), 128);
+
+ bool finished = false;
+
+ Thread gcThread = new Thread (() => {
+ 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 ();
+ }
+ });
+
+ gcThread.Start ();
+ joinThread.Start ();
+
+ for (int i = 0; i < 10 * 1000; ++i) {
+ Thread t = new Thread (() => { Thread.Yield (); });
+ t.Start ();
+
+ threads.Add (t);
+ }
+
+ threads.Add (null);
+
+ joinThread.Join ();
+
+ finished = true;
+ gcThread.Join ();
+ }
+}
\ No newline at end of file