Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Services / Monitoring / system / Diagnosticts / CounterSampleCalculator.cs / 2 / CounterSampleCalculator.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
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;
///
/// Set of utility functions for interpreting the counter data
/// NOTE: most of this code was taken and ported from counters.c (PerfMon source code)
///
public static class CounterSampleCalculator {
static bool perfCounterDllLoaded = false;
///
/// Converts 100NS elapsed time to fractional seconds
///
///
private static float GetElapsedTime(CounterSample oldSample, CounterSample newSample) {
float eSeconds;
float eDifference;
if (newSample.RawValue == 0) {
// no data [start time = 0] so return 0
return 0.0f;
}
else {
float eFreq;
eFreq = (float)(ulong)oldSample.CounterFrequency;
if (oldSample.UnsignedRawValue >= (ulong)newSample.CounterTimeStamp || eFreq <= 0.0f)
return 0.0f;
// otherwise compute difference between current time and start time
eDifference = (float)((ulong)newSample.CounterTimeStamp - oldSample.UnsignedRawValue);
// convert to fractional seconds using object counter
eSeconds = eDifference / eFreq;
return eSeconds;
}
}
///
/// Computes the calculated value given a raw counter sample.
///
public static float ComputeCounterValue(CounterSample newSample) {
return ComputeCounterValue(CounterSample.Empty, newSample);
}
///
/// Computes the calculated value given a raw counter sample.
///
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)) {
// Since oldSample has a system frequency of 0, this means the newSample is the first sample
// on a two sample calculation. Since we can't do anything with it, return 0.
return 0.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 the numbers go negative, just return 0. This better matches the old behavior.
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;
}
// This method figures out which values are supposed to go into which structures so that PDH can do the
// calculation for us. This was ported from Window's cutils.c
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) {
// this is to make PDH work like PERFMON for
// this counter type
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;
//
// These counters do not use any time reference
//
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;
//
// These counters use the 100 Ns time base in thier calculation
//
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;
//
// These counters use two data points
//
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:
// an unidentified counter was returned so
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();
// load perfcounter.dll manually, since it usually isn't on the path.
IntPtr mscorwksHandle = NativeMethods.GetModuleHandle("mscorwks.dll");
if (mscorwksHandle == IntPtr.Zero)
throw new Win32Exception();
int size = 132;
StringBuilder filename;
HandleRef mscorwksHandleRef = new HandleRef(null, mscorwksHandle);
do {
size *= 2;
filename = new StringBuilder(size);
size = UnsafeNativeMethods.GetModuleFileName(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;
}
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CounterSample.cs
- RangeBase.cs
- OrderedDictionaryStateHelper.cs
- XmlILAnnotation.cs
- UInt64.cs
- BulletChrome.cs
- WebHttpSecurity.cs
- TemplateBamlRecordReader.cs
- FlowDocumentView.cs
- DataGridViewAutoSizeModeEventArgs.cs
- PassportAuthentication.cs
- ipaddressinformationcollection.cs
- Axis.cs
- NotFiniteNumberException.cs
- ConfigurationValidatorBase.cs
- _Semaphore.cs
- BamlVersionHeader.cs
- Merger.cs
- SingleTagSectionHandler.cs
- MulticastOption.cs
- RegexCode.cs
- Pens.cs
- ToolBar.cs
- DomainConstraint.cs
- UInt16Converter.cs
- HyperLinkDesigner.cs
- ELinqQueryState.cs
- initElementDictionary.cs
- ELinqQueryState.cs
- Typeface.cs
- FlowDocumentPaginator.cs
- Transform3DGroup.cs
- WebPartConnection.cs
- InkCanvasAutomationPeer.cs
- DataGridViewCellStyleContentChangedEventArgs.cs
- ValueOfAction.cs
- Brushes.cs
- FileDialogCustomPlace.cs
- DataGridLength.cs
- ThemeDirectoryCompiler.cs
- Events.cs
- Timer.cs
- TypeSemantics.cs
- HttpApplication.cs
- FloaterBaseParagraph.cs
- Transform3D.cs
- CultureInfo.cs
- CaretElement.cs
- ModelToObjectValueConverter.cs
- ActivationWorker.cs
- ButtonFlatAdapter.cs
- DataReaderContainer.cs
- BindingElementExtensionElement.cs
- ExpressionBuilder.cs
- NumberFormatInfo.cs
- Annotation.cs
- Nodes.cs
- KeyGesture.cs
- PasswordPropertyTextAttribute.cs
- MailWebEventProvider.cs
- CompositeControl.cs
- SettingsAttributes.cs
- TagPrefixInfo.cs
- InfoCardSymmetricAlgorithm.cs
- HMACSHA1.cs
- TreeSet.cs
- FontStyle.cs
- AdornedElementPlaceholder.cs
- BigInt.cs
- RemoteWebConfigurationHost.cs
- PointConverter.cs
- WindowsRichEdit.cs
- ActionItem.cs
- CodeGeneratorOptions.cs
- ListViewItemEventArgs.cs
- EntityProviderServices.cs
- DataGridrowEditEndingEventArgs.cs
- DeclaredTypeElementCollection.cs
- BitmapEffectInput.cs
- SizeChangedInfo.cs
- ResourceContainer.cs
- BrowserCapabilitiesFactory35.cs
- CssStyleCollection.cs
- WindowsSspiNegotiation.cs
- DecoderExceptionFallback.cs
- DebugInfoExpression.cs
- NotifyCollectionChangedEventArgs.cs
- EncoderExceptionFallback.cs
- CodeDefaultValueExpression.cs
- ConfigurationValue.cs
- SafeNativeMemoryHandle.cs
- MSHTMLHost.cs
- RootAction.cs
- GeometryGroup.cs
- ImageInfo.cs
- Style.cs
- ProcessManager.cs
- BooleanFacetDescriptionElement.cs
- ValuePatternIdentifiers.cs
- Token.cs