Skip to content

Commit db5c90d

Browse files
committed
Reset counters on Timer thread
1 parent 991ae97 commit db5c90d

File tree

1 file changed

+33
-25
lines changed
  • src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing

1 file changed

+33
-25
lines changed

src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/CounterGroup.cs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ private void EnableTimer(float pollingIntervalInSeconds)
155155
if (_pollingIntervalInMilliseconds == 0 || pollingIntervalInSeconds * 1000 < _pollingIntervalInMilliseconds)
156156
{
157157
_pollingIntervalInMilliseconds = (int)(pollingIntervalInSeconds * 1000);
158-
ResetCounters(); // Reset statistics for counters before we start the thread.
159-
160158
_timeStampSinceCollectionStarted = DateTime.UtcNow;
161159
_nextPollingTimeStamp = DateTime.UtcNow + new TimeSpan(0, 0, (int)pollingIntervalInSeconds);
162160

@@ -165,6 +163,7 @@ private void EnableTimer(float pollingIntervalInSeconds)
165163
{
166164
s_pollingThreadSleepEvent = new AutoResetEvent(false);
167165
s_counterGroupEnabledList = new List<CounterGroup>();
166+
s_needsResetCounterGroup = [];
168167
s_pollingThread = new Thread(PollForValues)
169168
{
170169
IsBackground = true,
@@ -178,6 +177,11 @@ private void EnableTimer(float pollingIntervalInSeconds)
178177
s_counterGroupEnabledList.Add(this);
179178
}
180179

180+
if (!s_needsResetCounterGroup!.Contains(this))
181+
{
182+
s_needsResetCounterGroup.Add(this);
183+
}
184+
181185
// notify the polling thread that the polling interval may have changed and the sleep should
182186
// be recomputed
183187
s_pollingThreadSleepEvent!.Set();
@@ -189,28 +193,7 @@ private void DisableTimer()
189193
Debug.Assert(Monitor.IsEntered(s_counterGroupLock));
190194
_pollingIntervalInMilliseconds = 0;
191195
s_counterGroupEnabledList?.Remove(this);
192-
}
193-
194-
private void ResetCounters()
195-
{
196-
lock (s_counterGroupLock) // Lock the CounterGroup
197-
{
198-
foreach (DiagnosticCounter counter in _counters)
199-
{
200-
if (counter is IncrementingEventCounter ieCounter)
201-
{
202-
ieCounter.UpdateMetric();
203-
}
204-
else if (counter is IncrementingPollingCounter ipCounter)
205-
{
206-
ipCounter.UpdateMetric();
207-
}
208-
else if (counter is EventCounter eCounter)
209-
{
210-
eCounter.ResetStatistics();
211-
}
212-
}
213-
}
196+
s_needsResetCounterGroup?.Remove(this);
214197
}
215198

216199
private void OnTimer()
@@ -264,7 +247,7 @@ private void OnTimer()
264247
private static AutoResetEvent? s_pollingThreadSleepEvent;
265248

266249
private static List<CounterGroup>? s_counterGroupEnabledList;
267-
250+
private static List<CounterGroup>? s_needsResetCounterGroup;
268251
private static void PollForValues()
269252
{
270253
AutoResetEvent? sleepEvent = null;
@@ -274,11 +257,18 @@ private static void PollForValues()
274257
// calling into the callbacks can cause a re-entrancy into CounterGroup.Enable()
275258
// and result in a deadlock. (See https://github.com/dotnet/runtime/issues/40190 for details)
276259
var onTimers = new List<CounterGroup>();
260+
var countersToReset = new List<DiagnosticCounter>();
277261
while (true)
278262
{
279263
int sleepDurationInMilliseconds = int.MaxValue;
280264
lock (s_counterGroupLock)
281265
{
266+
foreach (CounterGroup counterGroup in s_needsResetCounterGroup!)
267+
{
268+
countersToReset.AddRange(counterGroup._counters);
269+
}
270+
s_needsResetCounterGroup.Clear();
271+
282272
sleepEvent = s_pollingThreadSleepEvent;
283273
foreach (CounterGroup counterGroup in s_counterGroupEnabledList!)
284274
{
@@ -293,6 +283,24 @@ private static void PollForValues()
293283
sleepDurationInMilliseconds = Math.Min(sleepDurationInMilliseconds, millisecondsTillNextPoll);
294284
}
295285
}
286+
287+
foreach (DiagnosticCounter counter in countersToReset)
288+
{
289+
if (counter is IncrementingEventCounter ieCounter)
290+
{
291+
ieCounter.UpdateMetric();
292+
}
293+
else if (counter is IncrementingPollingCounter ipCounter)
294+
{
295+
ipCounter.UpdateMetric();
296+
}
297+
else if (counter is EventCounter eCounter)
298+
{
299+
eCounter.ResetStatistics();
300+
}
301+
}
302+
countersToReset.Clear();
303+
296304
foreach (CounterGroup onTimer in onTimers)
297305
{
298306
onTimer.OnTimer();

0 commit comments

Comments
 (0)