We need you! We're working hard on the next version of Developer Fusion -
Let us know what you think we should be up to!
- namespace System.Diagnostics
- {
- using System.Threading;
- using System;
- using System.ComponentModel;
- using Microsoft.Win32;
- using System.Text;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Security.Permissions;
- using System.Globalization;
- using System.Runtime.Versioning;
-
- /// <devdoc>
- /// Set of utility functions for interpreting the counter data
- /// NOTE: most of this code was taken and ported from counters.c (PerfMon source code)
- /// </devdoc>
- public static class CounterSampleCalculator
- {
- static bool perfCounterDllLoaded = false;
-
- /// <devdoc>
- /// Converts 100NS elapsed time to fractional seconds
- /// </devdoc>
- /// <internalonly/>
- private static float GetElapsedTime(CounterSample oldSample, CounterSample newSample)
- {
- float eSeconds;
- float eDifference;
-
- if (newSample.RawValue == 0) {
-
- return 0f;
- }
- else {
- float eFreq;
- eFreq = (float)(ulong)oldSample.CounterFrequency;
-
- if (oldSample.UnsignedRawValue >= (ulong)newSample.CounterTimeStamp || eFreq <= 0f)
- return 0f;
-
-
- eDifference = (float)((ulong)newSample.CounterTimeStamp - oldSample.UnsignedRawValue);
-
-
- eSeconds = eDifference / eFreq;
-
- return eSeconds;
- }
- }
-
- /// <devdoc>
- /// Computes the calculated value given a raw counter sample.
- /// </devdoc>
- public static float ComputeCounterValue(CounterSample newSample)
- {
- return ComputeCounterValue(CounterSample.Empty, newSample);
- }
-
- /// <devdoc>
- /// Computes the calculated value given a raw counter sample.
- /// </devdoc>
- public static float ComputeCounterValue(CounterSample oldSample, CounterSample newSample)
- {
- int newCounterType = (int)newSample.CounterType;
- if (oldSample.SystemFrequency == 0) {
- if ((newCounterType != NativeMethods.PERF_RAW_FRACTION) && (newCounterType != NativeMethods.PERF_COUNTER_RAWCOUNT) && (newCounterType != NativeMethods.PERF_COUNTER_RAWCOUNT_HEX) && (newCounterType != NativeMethods.PERF_COUNTER_LARGE_RAWCOUNT) && (newCounterType != NativeMethods.PERF_COUNTER_LARGE_RAWCOUNT_HEX) && (newCounterType != NativeMethods.PERF_COUNTER_MULTI_BASE)) {
-
-
-
- return 0f;
- }
- }
- else if (oldSample.CounterType != newSample.CounterType) {
- throw new InvalidOperationException(SR.GetString(SR.MismatchedCounterTypes));
- }
-
- if (newCounterType == NativeMethods.PERF_ELAPSED_TIME)
- return (float)GetElapsedTime(oldSample, newSample);
-
- NativeMethods.PDH_RAW_COUNTER newPdhValue = new NativeMethods.PDH_RAW_COUNTER();
- NativeMethods.PDH_RAW_COUNTER oldPdhValue = new NativeMethods.PDH_RAW_COUNTER();
-
- FillInValues(oldSample, newSample, oldPdhValue, newPdhValue);
-
- LoadPerfCounterDll();
-
- NativeMethods.PDH_FMT_COUNTERVALUE pdhFormattedValue = new NativeMethods.PDH_FMT_COUNTERVALUE();
- long timeBase = newSample.SystemFrequency;
- int result = SafeNativeMethods.FormatFromRawValue((uint)newCounterType, NativeMethods.PDH_FMT_DOUBLE | NativeMethods.PDH_FMT_NOSCALE | NativeMethods.PDH_FMT_NOCAP100, ref timeBase, newPdhValue, oldPdhValue, pdhFormattedValue);
-
- if (result != NativeMethods.ERROR_SUCCESS) {
-
- if (result == NativeMethods.PDH_CALC_NEGATIVE_VALUE || result == NativeMethods.PDH_CALC_NEGATIVE_DENOMINATOR || result == NativeMethods.PDH_NO_DATA)
- return 0;
- else
- throw new Win32Exception(result, SR.GetString(SR.PerfCounterPdhError, result.ToString("x", CultureInfo.InvariantCulture)));
- }
-
- return (float)pdhFormattedValue.data;
-
- }
-
-
-
-
- private static void FillInValues(CounterSample oldSample, CounterSample newSample, NativeMethods.PDH_RAW_COUNTER oldPdhValue, NativeMethods.PDH_RAW_COUNTER newPdhValue)
- {
- int newCounterType = (int)newSample.CounterType;
-
- switch (newCounterType) {
- case NativeMethods.PERF_COUNTER_COUNTER:
- case NativeMethods.PERF_COUNTER_QUEUELEN_TYPE:
- case NativeMethods.PERF_SAMPLE_COUNTER:
- case NativeMethods.PERF_OBJ_TIME_TIMER:
- case NativeMethods.PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE:
- newPdhValue.FirstValue = newSample.RawValue;
- newPdhValue.SecondValue = newSample.TimeStamp;
-
- oldPdhValue.FirstValue = oldSample.RawValue;
- oldPdhValue.SecondValue = oldSample.TimeStamp;
- break;
- case NativeMethods.PERF_COUNTER_100NS_QUEUELEN_TYPE:
-
- newPdhValue.FirstValue = newSample.RawValue;
- newPdhValue.SecondValue = newSample.TimeStamp100nSec;
-
- oldPdhValue.FirstValue = oldSample.RawValue;
- oldPdhValue.SecondValue = oldSample.TimeStamp100nSec;
- break;
- case NativeMethods.PERF_COUNTER_TIMER:
- case NativeMethods.PERF_COUNTER_TIMER_INV:
- case NativeMethods.PERF_COUNTER_BULK_COUNT:
- case NativeMethods.PERF_COUNTER_LARGE_QUEUELEN_TYPE:
- case NativeMethods.PERF_COUNTER_MULTI_TIMER:
- case NativeMethods.PERF_COUNTER_MULTI_TIMER_INV:
-
- newPdhValue.FirstValue = newSample.RawValue;
- newPdhValue.SecondValue = newSample.TimeStamp;
-
- oldPdhValue.FirstValue = oldSample.RawValue;
- oldPdhValue.SecondValue = oldSample.TimeStamp;
- if (newCounterType == NativeMethods.PERF_COUNTER_MULTI_TIMER || newCounterType == NativeMethods.PERF_COUNTER_MULTI_TIMER_INV) {
-
-
- newPdhValue.FirstValue *= (uint)newSample.CounterFrequency;
- if (oldSample.CounterFrequency != 0) {
- oldPdhValue.FirstValue *= (uint)oldSample.CounterFrequency;
- }
- }
-
- if ((newCounterType & NativeMethods.PERF_MULTI_COUNTER) == NativeMethods.PERF_MULTI_COUNTER) {
- newPdhValue.MultiCount = (int)newSample.BaseValue;
- oldPdhValue.MultiCount = (int)oldSample.BaseValue;
- }
-
-
- break;
- case NativeMethods.PERF_COUNTER_RAWCOUNT:
- case NativeMethods.PERF_COUNTER_RAWCOUNT_HEX:
- case NativeMethods.PERF_COUNTER_DELTA:
- case NativeMethods.PERF_COUNTER_LARGE_RAWCOUNT:
- case NativeMethods.PERF_COUNTER_LARGE_RAWCOUNT_HEX:
- case NativeMethods.PERF_COUNTER_LARGE_DELTA:
-
-
-
- newPdhValue.FirstValue = newSample.RawValue;
- newPdhValue.SecondValue = 0;
-
- oldPdhValue.FirstValue = oldSample.RawValue;
- oldPdhValue.SecondValue = 0;
- break;
- case NativeMethods.PERF_100NSEC_TIMER:
- case NativeMethods.PERF_100NSEC_TIMER_INV:
- case NativeMethods.PERF_100NSEC_MULTI_TIMER:
- case NativeMethods.PERF_100NSEC_MULTI_TIMER_INV:
-
-
-
- newPdhValue.FirstValue = newSample.RawValue;
- newPdhValue.SecondValue = newSample.TimeStamp100nSec;
-
- oldPdhValue.FirstValue = oldSample.RawValue;
- oldPdhValue.SecondValue = oldSample.TimeStamp100nSec;
- if ((newCounterType & NativeMethods.PERF_MULTI_COUNTER) == NativeMethods.PERF_MULTI_COUNTER) {
- newPdhValue.MultiCount = (int)newSample.BaseValue;
- oldPdhValue.MultiCount = (int)oldSample.BaseValue;
- }
- break;
- case NativeMethods.PERF_SAMPLE_FRACTION:
- case NativeMethods.PERF_RAW_FRACTION:
- case NativeMethods.PERF_LARGE_RAW_FRACTION:
- case NativeMethods.PERF_PRECISION_SYSTEM_TIMER:
- case NativeMethods.PERF_PRECISION_100NS_TIMER:
- case NativeMethods.PERF_PRECISION_OBJECT_TIMER:
- case NativeMethods.PERF_AVERAGE_TIMER:
- case NativeMethods.PERF_AVERAGE_BULK:
-
-
-
- newPdhValue.FirstValue = newSample.RawValue;
- newPdhValue.SecondValue = newSample.BaseValue;
-
- oldPdhValue.FirstValue = oldSample.RawValue;
- oldPdhValue.SecondValue = oldSample.BaseValue;
- break;
- default:
-
-
- newPdhValue.FirstValue = 0;
- newPdhValue.SecondValue = 0;
-
- oldPdhValue.FirstValue = 0;
- oldPdhValue.SecondValue = 0;
- break;
- }
- }
-
- [ResourceExposure(ResourceScope.None)]
- [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
- private static void LoadPerfCounterDll()
- {
- if (perfCounterDllLoaded)
- return;
-
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
-
-
- IntPtr mscorwksHandle = NativeMethods.GetModuleHandle("mscorwks.dll");
- if (mscorwksHandle == IntPtr.Zero)
- throw new Win32Exception();
-
- int size = 132;
- StringBuilder filename;
- using (Process currentProc = Process.GetCurrentProcess()) {
- HandleRef procHandleRef = new HandleRef(null, currentProc.Handle);
- HandleRef mscorwksHandleRef = new HandleRef(null, mscorwksHandle);
- do {
- size *= 2;
- filename = new StringBuilder(size);
- size = NativeMethods.GetModuleFileNameEx(procHandleRef, mscorwksHandleRef, filename, size);
- if (size == 0)
- throw new Win32Exception();
- }
- while (size == filename.Capacity);
- }
-
- string installPath = Path.GetDirectoryName(filename.ToString());
- string perfcounterPath = Path.Combine(installPath, "perfcounter.dll");
- if (SafeNativeMethods.LoadLibrary(perfcounterPath) == IntPtr.Zero)
- throw new Win32Exception();
-
- perfCounterDllLoaded = true;
- }
- }
- }