Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
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
@@ -0,0 +1,93 @@
// 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.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

internal static partial class Interop
{
internal partial class PerfCounter
{
[DllImport(Libraries.Advapi32, ExactSpelling = true)]
internal static extern unsafe uint PerfStopProvider(
IntPtr hProvider
);

internal unsafe delegate uint PERFLIBREQUEST(
uint RequestCode,
void* Buffer,
uint BufferSize
);

// Native PERFLIB V2 Provider APIs.
internal struct PerfCounterSetInfoStruct
{
// PERF_COUNTERSET_INFO structure defined in perflib.h
internal Guid CounterSetGuid;
internal Guid ProviderGuid;
internal uint NumCounters;
internal uint InstanceType;
}

internal struct PerfCounterInfoStruct
{
// PERF_COUNTER_INFO structure defined in perflib.h
internal uint CounterId;
internal uint CounterType;
internal long Attrib;
internal uint Size;
internal uint DetailLevel;
internal uint Scale;
internal uint Offset;
}

[StructLayout(LayoutKind.Sequential)]
internal struct PerfCounterSetInstanceStruct
{
// PERF_COUNTERSET_INSTANCE structure defined in perflib.h
internal Guid CounterSetGuid;
internal uint dwSize;
internal uint InstanceId;
internal uint InstanceNameOffset;
internal uint InstanceNameSize;
}

[DllImport(Libraries.Advapi32, ExactSpelling = true)]
internal static extern unsafe uint PerfStartProvider(
ref Guid ProviderGuid,
PERFLIBREQUEST ControlCallback,
out SafePerfProviderHandle phProvider
);

[DllImport(Libraries.Advapi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
internal static extern unsafe PerfCounterSetInstanceStruct* PerfCreateInstance(
SafePerfProviderHandle hProvider,
ref Guid CounterSetGuid,
string szInstanceName,
uint dwInstance
);

[DllImport(Libraries.Advapi32, ExactSpelling = true)]
internal static extern unsafe uint PerfSetCounterSetInfo(
SafePerfProviderHandle hProvider,
PerfCounterSetInfoStruct* pTemplate,
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i removed [In][Out] guideline says to use ref but on callsite i cannot pass a pointer to ref. Can you help me to understand how to resolve, i'm not so "fluent" with pinvoke.
/cc @jkotas @Anipik @JeremyKuhne

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NB. It works, maybe i don't need to use ref here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah sometimes we can get away with using the ref

uint dwTemplateSize
);

[DllImport(Libraries.Advapi32, ExactSpelling = true)]
internal static extern unsafe uint PerfDeleteInstance(
SafePerfProviderHandle hProvider,
PerfCounterSetInstanceStruct* InstanceBlock
);

[DllImport(Libraries.Advapi32, ExactSpelling = true)]
internal static extern unsafe uint PerfSetCounterRefValue(
SafePerfProviderHandle hProvider,
PerfCounterSetInstanceStruct* pInstance,
uint CounterId,
void* lpAddr
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 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.Diagnostics;
using System.Threading;

namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafePerfProviderHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafePerfProviderHandle() : base(true) { }

protected override bool ReleaseHandle()
{
uint Status = Interop.PerfCounter.PerfStopProvider(handle);
Debug.Assert(Status == (uint)Interop.Errors.ERROR_SUCCESS, "PerfStopProvider() fails");
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,88 @@ public enum PerformanceCounterType
Timer100NsInverse = 558957824,
}
}
namespace System.Diagnostics.PerformanceData
{
public sealed class CounterData
{
unsafe internal CounterData(long* pCounterData) { }
public void Decrement() { throw null; }
public void Increment() { throw null; }
public void IncrementBy(long value) { throw null; }
public long RawValue { get { throw null; } set { } }
public long Value { get { throw null; } set { } }
}
public class CounterSet : IDisposable
{
~CounterSet() { throw null; }
public void AddCounter(int counterId, CounterType counterType) { throw null; }
public void AddCounter(int counterId, CounterType counterType, string counterName) { throw null; }
public CounterSet(Guid providerGuid, Guid counterSetGuid, CounterSetInstanceType instanceType) { }
public CounterSetInstance CreateCounterSetInstance(string instanceName) { throw null; }
public void Dispose() { throw null; }
protected virtual void Dispose(bool disposing) { throw null; }
}
public sealed class CounterSetInstance : IDisposable
{
~CounterSetInstance() { throw null; }
internal CounterSetInstance(CounterSet counterSetDefined, string instanceName) { }
public void Dispose() { throw null; }
public CounterSetInstanceCounterDataSet Counters { get { throw null; } }
}
public sealed class CounterSetInstanceCounterDataSet : IDisposable
{
~CounterSetInstanceCounterDataSet() { throw null; }
internal CounterSetInstanceCounterDataSet(CounterSetInstance thisInst) { }
public void Dispose() { throw null; }
public CounterData this[int counterId] { get { throw null; } }
public CounterData this[string counterName] { get { throw null; } }
}
public enum CounterType
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How different are these from the ones listed in PerformanceCounterType.cs? Can we merge them?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are in different namespaces
System.Diagnostics.PerformanceData.CounterType https://referencesource.microsoft.com/#System.Core/System/Diagnostics/PerformanceData/CounterType.cs
System.Diagnostics.PerformanceCounterType https://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/PerformanceCounterType.cs,dbfac66e4bef3702

and some counters are not present.
I apologize maybe i don't understand well what you mean 😟

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think mostly, if they have identical values (ie AverageBase in PerformanceCounterType and AverageBase in PerformanceData/CounterType are the same, etc), then we should share them between the two, rather than have two copies, and put them in Common. If they are different, then having the two different enums in different namespaces is fine.

Copy link
Copy Markdown
Member Author

@MarcoRossignoli MarcoRossignoli Aug 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they are different, then having the two different enums in different namespaces is fine.

i did some check

PerformanceCounterType.cs PerformanceData/CounterType.cs
SampleFraction SampleFraction same
SampleCounter SampleCounter same
SampleBase SampleBase same
AverageTimer32 AverageTimer32 same
AverageBase AverageBase same
AverageCount64 AverageCount64 same
ElapsedTime ElapsedTime same
RateOfCountsPerSecond32 RateOfCountsPerSecond32 same
RateOfCountsPerSecond64 RateOfCountsPerSecond64 same
CountPerTimeInterval32 QueueLength different name
CountPerTimeInterval64 LargeQueueLength different name
NumberOfItems32 RawData32 differen tname
NumberOfItems64 RawData64 differentname
NumberOfItemsHEX32 RawDataHex32 different name
NumberOfItemsHEX64 RawDataHex64 different name
RawFraction RawFraction32 different name
RawBase RawBase32 different name
CounterTimer PercentageActive different name
CounterTimerInverse PercentageNotActive different name
Timer100Ns PercentageActive100Ns different name
Timer100NsInverse PercentageNotActive100Ns differen tname
CounterMultiTimer MultiTimerPercentageActive different name
CounterMultiTimerInverse MultiTimerPercentageNotActive different name
CounterMultiTimer100Ns MultiTimerPercentageActive100Ns different name
CounterMultiTimer100NsInverse MultiTimerPercentageNotActive100Ns different name
CounterMultiBase MultiTimerBase different name
CounterDelta32 Delta32 different name
CounterDelta64 Delta64 different name
ObjectSpecificTimer missing
PrecisionSystemTimer missing
PrecisionTimer100Ns missing
PrecisionObjectSpecificTimer missing
QueueLength100Ns missing
QueueLengthObjectTime missing
RawFraction64 missing
RawBase64 missing

They differ for name or missing counter.

then we should share them between the two, rather than have two copies, and put them in Common

Maybe a stupid question...how we can share enums values between two different enum name?

Copy link
Copy Markdown

@Anipik Anipik Aug 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a stupid question...how we can share enums values between two different enum name?

changing the definitions to use any of one enum should work.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thought was that we'd use what is already in Common, rather than have them explicitly defined in both classes.

Copy link
Copy Markdown
Member Author

@MarcoRossignoli MarcoRossignoli Aug 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you to avoid duplications...but i don't understand what you mean when you say "already in Common". Is there a file with enums definition already on "Common folder"?
If i search for AverageBase for instance i don't found anything on Common folder https://github.com/dotnet/corefx/search?utf8=%E2%9C%93&q=AverageBase+&type=
Or you meant create a file with 2 enums on common folder and add to src/ref projects to avoid duplication...is this your idea?
Sorry for all this question and thank's a lot for patience!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok. So what I was thinking is that you'd use https://github.com/dotnet/corefx/blob/master/src/Common/src/Interop/Windows/kernel32/Interop.PerformanceCounterOptions.cs like we do in PerformanceCounterType. So AverageBase = Interop.Kernel32.PerformanceCounterOptions.PERF_AVERAGE_BASE, etc.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so "simply" reuse Interop.Kernel32.PerformanceCounterOptions!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

{
RawDataHex32 = 0,
RawDataHex64 = 256,
RawData32 = 65536,
RawData64 = 65792,
Delta32 = 4195328,
Delta64 = 4195584,
SampleCounter = 4260864,
QueueLength = 4523008,
LargeQueueLength = 4523264,
QueueLength100Ns = 5571840,
QueueLengthObjectTime = 6620416,
RateOfCountPerSecond32 = 272696320,
RateOfCountPerSecond64 = 272696576,
RawFraction32 = 537003008,
RawFraction64 = 537003264,
PercentageActive = 541132032,
PrecisionSystemTimer = 541525248,
PercentageActive100Ns = 542180608,
PrecisionTimer100Ns = 542573824,
ObjectSpecificTimer = 543229184,
PrecisionObjectSpecificTimer = 543622400,
SampleFraction = 549585920,
PercentageNotActive = 557909248,
PercentageNotActive100Ns = 558957824,
MultiTimerPercentageActive = 574686464,
MultiTimerPercentageActive100Ns = 575735040,
MultiTimerPercentageNotActive = 591463680,
MultiTimerPercentageNotActive100Ns = 592512256,
AverageTimer32 = 805438464,
ElapsedTime = 807666944,
AverageCount64 = 1073874176,
SampleBase = 1073939457,
AverageBase = 1073939458,
RawBase32 = 1073939459,
RawBase64 = 1073939712,
MultiTimerBase = 1107494144
}
public enum CounterSetInstanceType
{
Single = 0,
Multiple = 2,
GlobalAggregate = 4,
MultipleAggregate = 6,
GlobalAggregateWithHistory = 11,
InstanceAggregate = 22
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
<IsPartialFacadeAssembly Condition="'$(TargetsNetFx)' == 'true'">true</IsPartialFacadeAssembly>
<ProjectGuid>{5BDC8641-E3EE-47B5-BE7B-2D2275402412}</ProjectGuid>
<Configurations>net461-Debug;net461-Release;netfx-Debug;netfx-Release;netstandard-Debug;netstandard-Release</Configurations>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Include="System.Diagnostics.PerformanceCounter.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsNetFx)' == 'true'">
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -290,5 +290,53 @@
</data>
<data name="PlatformNotSupported_PerfCounters" xml:space="preserve">
<value>Performance Counters are not supported on this platform.</value>
</data>
<data name="Perflib_Argument_InvalidCounterSetInstanceType" xml:space="preserve">
<value>CounterSetInstanceType '{0}' is not a valid CounterSetInstanceType.</value>
</data>
<data name="Perflib_InvalidOperation_NoActiveProvider" xml:space="preserve">
<value>CounterSet provider '{0}' not active.</value>
</data>
<data name="Perflib_Argument_InvalidCounterType" xml:space="preserve">
<value>CounterType '{0}' is not a valid CounterType.</value>
</data>
<data name="Perflib_InvalidOperation_AddCounterAfterInstance" xml:space="preserve">
<value>Cannot AddCounter to CounterSet '{0}' after CreateCounterSetInstance.</value>
</data>
<data name="Perflib_Argument_CounterAlreadyExists" xml:space="preserve">
<value>CounterId '{0}' already added to CounterSet '{1}'.</value>
</data>
<data name="Perflib_Argument_EmptyInstanceName" xml:space="preserve">
<value>Non-empty instanceName required.</value>
</data>
<data name="Perflib_InvalidOperation_CounterSetNotInstalled" xml:space="preserve">
<value>CounterSet '{0}' not installed yet.</value>
</data>
<data name="Perflib_Argument_InvalidInstance" xml:space="preserve">
<value>Single instance type CounterSet '{0}' can only have 1 CounterSetInstance.</value>
</data>
<data name="Perflib_Argument_EmptyCounterName" xml:space="preserve">
<value>Non-empty counterName required.</value>
</data>
<data name="Perflib_Argument_CounterNameAlreadyExists" xml:space="preserve">
<value>CounterName '{0}' already added to CounterSet '{1}'.</value>
</data>
<data name="Perflib_Argument_ProviderNotFound" xml:space="preserve">
<value>CounterSet provider '{0}' not found.</value>
</data>
<data name="Perflib_InvalidOperation_CounterSetContainsNoCounter" xml:space="preserve">
<value>CounterSet '{0}' does not include any counters.</value>
</data>
<data name="Perflib_Argument_CounterSetAlreadyRegister" xml:space="preserve">
<value>CounterSet '{0}' already registered.</value>
</data>
<data name="Perflib_Argument_InstanceAlreadyExists" xml:space="preserve">
<value>Instance '{0}' already exists in CounterSet '{1}'.</value>
</data>
<data name="Perflib_InsufficientMemory_InstanceCounterBlock" xml:space="preserve">
<value>Cannot allocate raw counter data for CounterSet '{0}' Instance '{1}'.</value>
</data>
<data name="Perflib_InvalidOperation_CounterRefValue" xml:space="preserve">
<value>Cannot locate raw counter data location for CounterSet '{0}', Counter '{1}, in Instance '{2}'.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
<Compile Include="System\Diagnostics\SystemDiagnosticsSection.cs" />
<Compile Include="System\Diagnostics\TraceInternal.cs" />
<Compile Include="misc\EnvironmentHelpers.cs" />
<Compile Include="System\Diagnostics\PerformanceData\CounterSet.cs" />
<Compile Include="System\Diagnostics\PerformanceData\CounterSetInstance.cs" />
<Compile Include="System\Diagnostics\PerformanceData\CounterSetInstanceCounterDataSet.cs" />
<Compile Include="System\Diagnostics\PerformanceData\CounterSetInstanceType.cs" />
<Compile Include="System\Diagnostics\PerformanceData\CounterType.cs" />
<Compile Include="System\Diagnostics\PerformanceData\PerfProviderCollection.cs" />
<Compile Include="$(CommonPath)\CoreLib\Interop\Windows\Interop.BOOL.cs">
<Link>Common\CoreLib\Interop\Windows\Interop.BOOL.cs</Link>
</Compile>
Expand Down Expand Up @@ -132,16 +138,23 @@
<Compile Include="$(CommonPath)\Interop\Windows\perfcounter\Interop.FormatFromRawValue.cs">
<Link>Common\Interop\Windows\perfcounter\Interop.FormatFromRawValue.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\perfcounter\Interop.PerformanceData.cs">
<Link>Common\Interop\Windows\perfcounter\Interop.PerformanceData.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeLocalAllocHandle.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafeLocalAllocHandle.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeLocalMemHandle.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafeLocalMemHandle.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafePerfProviderHandle.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafePerfProviderHandle.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition="'$(TargetsNetFx)' == 'true'">
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsNetFx)' != 'true'">
<Reference Include="Microsoft.Win32.Registry" />
Expand Down
Loading