Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Versioning;
using System.Threading;

Expand Down Expand Up @@ -92,7 +93,7 @@ private void OnEventSourceCommand(object? sender, EventCommandEventArgs e)

Debug.Assert((s_counterGroupEnabledList == null && !_eventSource.IsEnabled())
|| (_eventSource.IsEnabled() && s_counterGroupEnabledList!.Contains(this))
|| (_pollingIntervalInMilliseconds == 0 && !s_counterGroupEnabledList!.Contains(this))
|| (_pollingInterval == TimeSpan.Zero && !s_counterGroupEnabledList!.Contains(this))
|| (!_eventSource.IsEnabled() && !s_counterGroupEnabledList!.Contains(this)));
}
}
Expand Down Expand Up @@ -142,22 +143,24 @@ internal static CounterGroup GetCounterGroup(EventSource eventSource)

#region Timer Processing

private DateTime _timeStampSinceCollectionStarted;
private int _pollingIntervalInMilliseconds;
private DateTime _nextPollingTimeStamp;
private long _timeStampSinceCollectionStarted;
private TimeSpan _pollingInterval;
private long _nextPollingTimeStamp;

private void EnableTimer(float pollingIntervalInSeconds)
{
Debug.Assert(pollingIntervalInSeconds > 0);
Debug.Assert(Monitor.IsEntered(s_counterGroupLock));
if (_pollingIntervalInMilliseconds == 0 || pollingIntervalInSeconds * 1000 < _pollingIntervalInMilliseconds)
TimeSpan interval = TimeSpan.FromSeconds(pollingIntervalInSeconds);
if (_pollingInterval == TimeSpan.Zero || interval < _pollingInterval)
{
_pollingIntervalInMilliseconds = (int)(pollingIntervalInSeconds * 1000);
_pollingInterval = interval;
// Schedule IncrementingPollingCounter reset and synchronously reset other counters
HandleCountersReset();

_timeStampSinceCollectionStarted = DateTime.UtcNow;
_nextPollingTimeStamp = DateTime.UtcNow + new TimeSpan(0, 0, (int)pollingIntervalInSeconds);
long now = Stopwatch.GetTimestamp();
_timeStampSinceCollectionStarted = now;
_nextPollingTimeStamp = now + _pollingInterval.Ticks * Stopwatch.Frequency / TimeSpan.TicksPerSecond;

// Create the polling thread and init all the shared state if needed
if (s_pollingThread == null)
Expand Down Expand Up @@ -186,7 +189,7 @@ private void EnableTimer(float pollingIntervalInSeconds)
private void DisableTimer()
{
Debug.Assert(Monitor.IsEntered(s_counterGroupLock));
_pollingIntervalInMilliseconds = 0;
_pollingInterval = TimeSpan.Zero;
s_counterGroupEnabledList?.Remove(this);

if (s_needsResetIncrementingPollingCounters.Count > 0)
Expand Down Expand Up @@ -225,15 +228,15 @@ private void OnTimer()
{
if (_eventSource.IsEnabled())
{
DateTime now;
long now;
TimeSpan elapsed;
int pollingIntervalInMilliseconds;
TimeSpan pollingInterval;
DiagnosticCounter[] counters;
lock (s_counterGroupLock)
{
now = DateTime.UtcNow;
elapsed = now - _timeStampSinceCollectionStarted;
pollingIntervalInMilliseconds = _pollingIntervalInMilliseconds;
now = Stopwatch.GetTimestamp();
elapsed = Stopwatch.GetElapsedTime(_timeStampSinceCollectionStarted, now);
pollingInterval = _pollingInterval;
counters = new DiagnosticCounter[_counters.Count];
_counters.CopyTo(counters);
}
Expand All @@ -253,16 +256,22 @@ private void OnTimer()
// written to the old session or the new session. The behavior change is not being treated as a
// significant problem to address for now, but we can come back and address it if it turns out to
// be an actual issue.
counter.WritePayload((float)elapsed.TotalSeconds, pollingIntervalInMilliseconds);
counter.WritePayload((float)elapsed.TotalSeconds, (int)pollingInterval.TotalMilliseconds);
}

lock (s_counterGroupLock)
{
_timeStampSinceCollectionStarted = now;
TimeSpan delta = now - _nextPollingTimeStamp;
delta = _pollingIntervalInMilliseconds > delta.TotalMilliseconds ? TimeSpan.FromMilliseconds(_pollingIntervalInMilliseconds) : delta;
if (_pollingIntervalInMilliseconds > 0)
_nextPollingTimeStamp += TimeSpan.FromMilliseconds(_pollingIntervalInMilliseconds * Math.Ceiling(delta.TotalMilliseconds / _pollingIntervalInMilliseconds));
TimeSpan delta = Stopwatch.GetElapsedTime(_nextPollingTimeStamp, now);
if (delta < _pollingInterval)
{
delta = _pollingInterval;
}

if (_pollingInterval > TimeSpan.Zero)
{
_nextPollingTimeStamp += (long)Math.Ceiling(delta / _pollingInterval) * _pollingInterval.Ticks * Stopwatch.Frequency / TimeSpan.TicksPerSecond;
}
}
}
}
Expand Down Expand Up @@ -292,14 +301,14 @@ private static void PollForValues()
sleepEvent = s_pollingThreadSleepEvent;
foreach (CounterGroup counterGroup in s_counterGroupEnabledList!)
{
DateTime now = DateTime.UtcNow;
if (counterGroup._nextPollingTimeStamp < now + new TimeSpan(0, 0, 0, 0, 1))
long now = Stopwatch.GetTimestamp();
TimeSpan timeUntilNextPoll = Stopwatch.GetElapsedTime(now, counterGroup._nextPollingTimeStamp);
if (timeUntilNextPoll < TimeSpan.FromMilliseconds(1))
{
onTimers.Add(counterGroup);
}

int millisecondsTillNextPoll = (int)((counterGroup._nextPollingTimeStamp - now).TotalMilliseconds);
millisecondsTillNextPoll = Math.Max(1, millisecondsTillNextPoll);
int millisecondsTillNextPoll = Math.Max(1, (int)timeUntilNextPoll.TotalMilliseconds);
sleepDurationInMilliseconds = Math.Min(sleepDurationInMilliseconds, millisecondsTillNextPoll);
}

Expand Down
Loading