diff --git a/src/coverlet.template/ModuleTrackerTemplate.cs b/src/coverlet.template/ModuleTrackerTemplate.cs index d55a6174b..52cb332f8 100644 --- a/src/coverlet.template/ModuleTrackerTemplate.cs +++ b/src/coverlet.template/ModuleTrackerTemplate.cs @@ -20,24 +20,17 @@ public static class ModuleTrackerTemplate public static string HitsFilePath; public static int[] HitsArray; - // Special case when instrumenting CoreLib, the thread static below prevents infinite loop in CoreLib + // Special case when instrumenting CoreLib, the static below prevents infinite loop in CoreLib // while allowing the tracker template to call any of its types and functions. - [ThreadStatic] - private static bool t_isTracking; - - [ThreadStatic] - private static int[] t_threadHits; - - private static List _threads; + private static bool s_isTracking; static ModuleTrackerTemplate() { - t_isTracking = true; - _threads = new List(2 * Environment.ProcessorCount); - + s_isTracking = true; AppDomain.CurrentDomain.ProcessExit += new EventHandler(UnloadModule); AppDomain.CurrentDomain.DomainUnload += new EventHandler(UnloadModule); - t_isTracking = false; + s_isTracking = false; + // At the end of the instrumentation of a module, the instrumenter needs to add code here // to initialize the static fields according to the values derived from the instrumentation of // the module. @@ -45,43 +38,15 @@ static ModuleTrackerTemplate() public static void RecordHit(int hitLocationIndex) { - if (t_isTracking) + if (s_isTracking) return; - if (t_threadHits == null) - { - t_isTracking = true; - lock (_threads) - { - if (t_threadHits == null) - { - t_threadHits = new int[HitsArray.Length]; - _threads.Add(t_threadHits); - } - } - t_isTracking = false; - } - - ++t_threadHits[hitLocationIndex]; + Interlocked.Increment(ref HitsArray[hitLocationIndex]); } public static void UnloadModule(object sender, EventArgs e) { - t_isTracking = true; - - // Update the global hits array from data from all the threads - lock (_threads) - { - foreach (var threadHits in _threads) - { - for (int i = 0; i < HitsArray.Length; ++i) - HitsArray[i] += threadHits[i]; - } - - // Prevent any double counting scenario, i.e.: UnloadModule called twice (not sure if this can happen in practice ...) - // Only an issue if DomainUnload and ProcessExit can both happens, perhaps can be removed... - _threads.Clear(); - } + s_isTracking = true; // The same module can be unloaded multiple times in the same process via different app domains. // Use a global mutex to ensure no concurrent access.