From d40eb92721b766b91163b8af99514e92904c32af Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 8 Jan 2021 20:14:27 -0500 Subject: [PATCH] [mbr] Extend console sample Add a busy thread to demonstrate that interp frames since the last managed frame are visible to the metadata update mechanism and the active method bodies are copied before being invalidated. --- .../netcore/sample/mbr/console/Program.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/mono/netcore/sample/mbr/console/Program.cs b/src/mono/netcore/sample/mbr/console/Program.cs index 70bc11bb8c8f6..01fba0d8e4ee1 100644 --- a/src/mono/netcore/sample/mbr/console/Program.cs +++ b/src/mono/netcore/sample/mbr/console/Program.cs @@ -14,11 +14,24 @@ internal class Program class State { public readonly ManualResetEventSlim mreIn; public readonly ManualResetEventSlim mreOut; + public readonly ManualResetEventSlim mreBusy; public string res; + private volatile bool busyChanged; + public State() { mreIn = new ManualResetEventSlim (); mreOut = new ManualResetEventSlim (); + mreBusy = new ManualResetEventSlim (); res = ""; + busyChanged = false; + } + + + public bool BusyChanged {get => busyChanged ; set { busyChanged = value; mreBusy.Set ();} } + + public void WaitForBusy () { + mreBusy.Wait (); + mreBusy.Reset (); } public string ConsumerStep () { @@ -50,6 +63,8 @@ private static int Main(string[] args) var st = new State (); var t = new Thread (MutatorThread); t.Start (st); + var t2 = new Thread (BusyThread) { IsBackground = true }; + t2.Start (st); string res = st.ConsumerStep (); if (res != "OLD STRING") @@ -61,6 +76,9 @@ private static int Main(string[] args) if (res != "NEW STRING") return 2; + st.WaitForBusy (); + Console.WriteLine ("BusyChanged: {0}", st.BusyChanged); + return 0; } @@ -70,6 +88,28 @@ private static void MutatorThread (object o) static string Step () => TestClass.TargetMethod (); st.ProducerStep (Step); st.ProducerStep (Step); + } + + // This method is not affected by the update, but it calls the target + // method which is. Still we expect to see "BusyThread" and its + // callees show up in the trace output when it safepoints during an + // update. + private static void BusyThread (object o) + { + State st = (State)o; + string prev = TestClass.TargetMethod (); + while (true) { + Thread.Sleep (0); + for (int i = 0; i < 5000; ++i) { + if (i % 1000 == 0) { + string cur = TestClass.TargetMethod (); + if (cur != prev) { + st.BusyChanged = true; + prev = cur; + } + } + } + } } }