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
- PropertyValueUIItem.cs
- ToolStripDropDownButton.cs
- WasEndpointConfigContainer.cs
- Slider.cs
- Serializer.cs
- PerformanceCounterPermission.cs
- ProfileBuildProvider.cs
- PersistChildrenAttribute.cs
- XmlWellformedWriter.cs
- DerivedKeySecurityTokenStub.cs
- ValidatorCompatibilityHelper.cs
- DbConnectionOptions.cs
- CompilerScope.Storage.cs
- CustomTypeDescriptor.cs
- WorkflowIdleElement.cs
- XmlNavigatorStack.cs
- WebServiceBindingAttribute.cs
- TimeoutHelper.cs
- WebServiceParameterData.cs
- Transform3D.cs
- XmlSchemaExternal.cs
- figurelengthconverter.cs
- TableItemProviderWrapper.cs
- CompilerLocalReference.cs
- ElementFactory.cs
- DateTimeStorage.cs
- IndicFontClient.cs
- ContentElementCollection.cs
- CompiledRegexRunner.cs
- GraphicsContainer.cs
- BaseCodePageEncoding.cs
- DateTimeFormatInfo.cs
- GlyphRunDrawing.cs
- SByte.cs
- XmlCharCheckingReader.cs
- PropertyFilterAttribute.cs
- TreeViewHitTestInfo.cs
- DataSourceXmlElementAttribute.cs
- NotImplementedException.cs
- WebPartConnection.cs
- XmlUrlResolver.cs
- StyleTypedPropertyAttribute.cs
- StringFreezingAttribute.cs
- StandardOleMarshalObject.cs
- TextEditorSelection.cs
- ObjectPersistData.cs
- ToolBar.cs
- FutureFactory.cs
- ScrollData.cs
- DependencyPropertyValueSerializer.cs
- SequenceDesigner.cs
- TextDpi.cs
- VectorCollection.cs
- TextElement.cs
- PolyBezierSegment.cs
- Boolean.cs
- TaiwanCalendar.cs
- Int64Converter.cs
- FontDriver.cs
- HtmlContainerControl.cs
- InputMethodStateChangeEventArgs.cs
- Set.cs
- _Events.cs
- AlternationConverter.cs
- BitmapDownload.cs
- TypeListConverter.cs
- InvokeSchedule.cs
- ChannelPoolSettingsElement.cs
- DataRecordInternal.cs
- ActivitiesCollection.cs
- DoWorkEventArgs.cs
- StringAttributeCollection.cs
- PowerStatus.cs
- SafeCryptoHandles.cs
- CalendarDayButton.cs
- XmlBaseReader.cs
- DesignerOptionService.cs
- SchemaUtility.cs
- WebPartAddingEventArgs.cs
- SessionStateItemCollection.cs
- DataControlFieldHeaderCell.cs
- RightsManagementEncryptedStream.cs
- PopOutPanel.cs
- TreeNodeStyleCollection.cs
- IPAddressCollection.cs
- MimeObjectFactory.cs
- NegotiationTokenProvider.cs
- PrefixQName.cs
- SystemDiagnosticsSection.cs
- CheckBoxRenderer.cs
- ToolStripDropDownClosingEventArgs.cs
- BatchParser.cs
- TypeSystemProvider.cs
- DeclaredTypeElement.cs
- Table.cs
- XmlSchemaAny.cs
- ZipIORawDataFileBlock.cs
- DrawItemEvent.cs
- DataRelationPropertyDescriptor.cs
- ToolStripItemDesigner.cs