From: Brian Robbins Date: Mon, 17 Apr 2017 23:16:22 +0000 (-0700) Subject: Remove EventCounter from System.Private.CoreLib. X-Git-Tag: accepted/tizen/base/20180629.140029~1386^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fd36b69455103228074ca2fdbebb2d1f2770bf61;p=platform%2Fupstream%2Fcoreclr.git Remove EventCounter from System.Private.CoreLib. --- diff --git a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems index 6ef7fc1..d44e288 100644 --- a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems +++ b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems @@ -404,7 +404,6 @@ - diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/EventCounter.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventCounter.cs deleted file mode 100644 index b1f9464..0000000 --- a/src/mscorlib/shared/System/Diagnostics/Tracing/EventCounter.cs +++ /dev/null @@ -1,436 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Threading; -#if ES_BUILD_PCL - using System.Threading.Tasks; -#endif - -#if ES_BUILD_STANDALONE -namespace Microsoft.Diagnostics.Tracing -#else -namespace System.Diagnostics.Tracing -#endif -{ - /// - /// Provides the ability to collect statistics through EventSource - /// - public class EventCounter - { - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The event source. - public EventCounter(string name, EventSource eventSource) - { - if (name == null) - { - throw new ArgumentNullException(nameof(name)); - } - - if (eventSource == null) - { - throw new ArgumentNullException(nameof(eventSource)); - } - - InitializeBuffer(); - _name = name; - EventCounterGroup.AddEventCounter(eventSource, this); - } - - /// - /// Writes the metric. - /// - /// The value. - public void WriteMetric(float value) - { - Enqueue(value); - } - - #region private implementation - - private readonly string _name; - - #region Buffer Management - - // Values buffering - private const int BufferedSize = 10; - private const float UnusedBufferSlotValue = float.NegativeInfinity; - private const int UnsetIndex = -1; - private volatile float[] _bufferedValues; - private volatile int _bufferedValuesIndex; - - private void InitializeBuffer() - { - _bufferedValues = new float[BufferedSize]; - for (int i = 0; i < _bufferedValues.Length; i++) - { - _bufferedValues[i] = UnusedBufferSlotValue; - } - } - - private void Enqueue(float value) - { - // It is possible that two threads read the same bufferedValuesIndex, but only one will be able to write the slot, so that is okay. - int i = _bufferedValuesIndex; - while (true) - { - float result = Interlocked.CompareExchange(ref _bufferedValues[i], value, UnusedBufferSlotValue); - i++; - if (_bufferedValues.Length <= i) - { - // It is possible that two threads both think the buffer is full, but only one get to actually flush it, the other - // will eventually enter this code path and potentially calling Flushing on a buffer that is not full, and that's okay too. - lock (_bufferedValues) - { - Flush(); - } - i = 0; - } - - if (result == UnusedBufferSlotValue) - { - // CompareExchange succeeded - _bufferedValuesIndex = i; - return; - } - } - } - - private void Flush() - { - for (int i = 0; i < _bufferedValues.Length; i++) - { - var value = Interlocked.Exchange(ref _bufferedValues[i], UnusedBufferSlotValue); - if (value != UnusedBufferSlotValue) - { - OnMetricWritten(value); - } - } - - _bufferedValuesIndex = 0; - } - - #endregion // Buffer Management - - #region Statistics Calculation - - // Statistics - private int _count; - private float _sum; - private float _sumSquared; - private float _min; - private float _max; - - private void OnMetricWritten(float value) - { - _sum += value; - _sumSquared += value * value; - if (_count == 0 || value > _max) - { - _max = value; - } - - if (_count == 0 || value < _min) - { - _min = value; - } - - _count++; - } - - internal EventCounterPayload GetEventCounterPayload() - { - lock (_bufferedValues) - { - Flush(); - EventCounterPayload result = new EventCounterPayload(); - result.Name = _name; - result.Count = _count; - result.Mean = _sum / _count; - result.StandardDerivation = (float)Math.Sqrt(_sumSquared / _count - _sum * _sum / _count / _count); - result.Min = _min; - result.Max = _max; - ResetStatistics(); - return result; - } - } - - private void ResetStatistics() - { - _count = 0; - _sum = 0; - _sumSquared = 0; - _min = 0; - _max = 0; - } - - #endregion // Statistics Calculation - - #endregion // private implementation - } - - #region internal supporting classes - - [EventData] - internal class EventCounterPayload : IEnumerable> - { - public string Name { get; set; } - - public float Mean { get; set; } - - public float StandardDerivation { get; set; } - - public int Count { get; set; } - - public float Min { get; set; } - - public float Max { get; set; } - - public float IntervalSec { get; internal set; } - - #region Implementation of the IEnumerable interface - - public IEnumerator> GetEnumerator() - { - return ForEnumeration.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return ForEnumeration.GetEnumerator(); - } - - private IEnumerable> ForEnumeration - { - get - { - yield return new KeyValuePair("Name", Name); - yield return new KeyValuePair("Mean", Mean); - yield return new KeyValuePair("StandardDerivation", StandardDerivation); - yield return new KeyValuePair("Count", Count); - yield return new KeyValuePair("Min", Min); - yield return new KeyValuePair("Max", Max); - } - } - - #endregion // Implementation of the IEnumerable interface - } - - internal class EventCounterGroup : IDisposable - { - private readonly EventSource _eventSource; - private readonly int _eventSourceIndex; - private readonly List _eventCounters; - - internal EventCounterGroup(EventSource eventSource, int eventSourceIndex) - { - _eventSource = eventSource; - _eventSourceIndex = eventSourceIndex; - _eventCounters = new List(); - RegisterCommandCallback(); - } - - private void Add(EventCounter eventCounter) - { - _eventCounters.Add(eventCounter); - } - - #region EventSource Command Processing - - private void RegisterCommandCallback() - { - _eventSource.EventCommandExecuted += OnEventSourceCommand; - } - - private void OnEventSourceCommand(object sender, EventCommandEventArgs e) - { - if (e.Command == EventCommand.Enable || e.Command == EventCommand.Update) - { - string valueStr; - float value; - if (e.Arguments.TryGetValue("EventCounterIntervalSec", out valueStr) && float.TryParse(valueStr, out value)) - { - EnableTimer(value); - } - } - } - - #endregion // EventSource Command Processing - - #region Global EventCounterGroup Array management - - private static EventCounterGroup[] s_eventCounterGroups; - - internal static void AddEventCounter(EventSource eventSource, EventCounter eventCounter) - { - int eventSourceIndex = EventListener.EventSourceIndex(eventSource); - - EventCounterGroup.EnsureEventSourceIndexAvailable(eventSourceIndex); - EventCounterGroup eventCounterGroup = GetEventCounterGroup(eventSource); - eventCounterGroup.Add(eventCounter); - } - - private static void EnsureEventSourceIndexAvailable(int eventSourceIndex) - { - if (EventCounterGroup.s_eventCounterGroups == null) - { - EventCounterGroup.s_eventCounterGroups = new EventCounterGroup[eventSourceIndex + 1]; - } - else if (eventSourceIndex >= EventCounterGroup.s_eventCounterGroups.Length) - { - EventCounterGroup[] newEventCounterGroups = new EventCounterGroup[eventSourceIndex + 1]; - Array.Copy(EventCounterGroup.s_eventCounterGroups, 0, newEventCounterGroups, 0, EventCounterGroup.s_eventCounterGroups.Length); - EventCounterGroup.s_eventCounterGroups = newEventCounterGroups; - } - } - - private static EventCounterGroup GetEventCounterGroup(EventSource eventSource) - { - int eventSourceIndex = EventListener.EventSourceIndex(eventSource); - EventCounterGroup result = EventCounterGroup.s_eventCounterGroups[eventSourceIndex]; - if (result == null) - { - result = new EventCounterGroup(eventSource, eventSourceIndex); - EventCounterGroup.s_eventCounterGroups[eventSourceIndex] = result; - } - - return result; - } - - #endregion // Global EventCounterGroup Array management - - #region Timer Processing - - private DateTime _timeStampSinceCollectionStarted; - private int _pollingIntervalInMilliseconds; - private Timer _pollingTimer; - - private void EnableTimer(float pollingIntervalInSeconds) - { - if (pollingIntervalInSeconds == 0) - { - if (_pollingTimer != null) - { - _pollingTimer.Dispose(); - _pollingTimer = null; - } - - _pollingIntervalInMilliseconds = 0; - } - else if (_pollingIntervalInMilliseconds == 0 || pollingIntervalInSeconds < _pollingIntervalInMilliseconds) - { - _pollingIntervalInMilliseconds = (int)(pollingIntervalInSeconds * 1000); - if (_pollingTimer != null) - { - _pollingTimer.Dispose(); - _pollingTimer = null; - } - - _timeStampSinceCollectionStarted = DateTime.Now; - _pollingTimer = new Timer(OnTimer, null, _pollingIntervalInMilliseconds, _pollingIntervalInMilliseconds); - } - } - - private void OnTimer(object state) - { - if (_eventSource.IsEnabled()) - { - DateTime now = DateTime.Now; - TimeSpan elapsed = now - _timeStampSinceCollectionStarted; - lock (_pollingTimer) - { - foreach (var eventCounter in _eventCounters) - { - EventCounterPayload payload = eventCounter.GetEventCounterPayload(); - payload.IntervalSec = (float)elapsed.TotalSeconds; - _eventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new { Payload = payload }); - } - - - _timeStampSinceCollectionStarted = now; - } - } - else - { - _pollingTimer.Dispose(); - _pollingTimer = null; - EventCounterGroup.s_eventCounterGroups[_eventSourceIndex] = null; - } - } - - #region PCL timer hack - -#if ES_BUILD_PCL - internal delegate void TimerCallback(object state); - - internal sealed class Timer : CancellationTokenSource, IDisposable - { - private int _period; - private TimerCallback _callback; - private object _state; - - internal Timer(TimerCallback callback, object state, int dueTime, int period) - { - _callback = callback; - _state = state; - _period = period; - Schedule(dueTime); - } - - private void Schedule(int dueTime) - { - Task.Delay(dueTime, Token).ContinueWith(OnTimer, null, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default); - } - - private void OnTimer(Task t, object s) - { - Schedule(_period); - _callback(_state); - } - - public new void Dispose() { base.Cancel(); } - } -#endif - #endregion // PCL timer hack - - #endregion // Timer Processing - - #region Implementation of the IDisposable interface - - private bool _disposed = false; - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool disposing) - { - if (_disposed) - { - return; - } - - if (disposing) - { - if (_pollingTimer != null) - { - _pollingTimer.Dispose(); - _pollingTimer = null; - } - } - - _disposed = true; - } - - #endregion // Implementation of the IDisposable interface - } - - #endregion // internal supporting classes -}