Skip to content

Commit

Permalink
Add test for EventListener consuming ThreadPool events (#48487)
Browse files Browse the repository at this point in the history
  • Loading branch information
sywhang authored Jun 2, 2021
1 parent 1755fc2 commit 0f79fe3
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, R
}

Type parameterType = parameters[i].ParameterType;
Type? enumType = parameterType.IsEnum ? Enum.GetUnderlyingType(parameterType) : null;
if (parameterType == typeof(IntPtr))
{
if (IntPtr.Size == 8)
Expand All @@ -40,42 +41,42 @@ internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, R
}
payload = payload.Slice(IntPtr.Size);
}
else if (parameterType == typeof(int))
else if (parameterType == typeof(int) || enumType == typeof(int))
{
decodedFields[i] = BinaryPrimitives.ReadInt32LittleEndian(payload);
payload = payload.Slice(sizeof(int));
}
else if (parameterType == typeof(uint))
else if (parameterType == typeof(uint) || enumType == typeof(uint))
{
decodedFields[i] = BinaryPrimitives.ReadUInt32LittleEndian(payload);
payload = payload.Slice(sizeof(uint));
}
else if (parameterType == typeof(long))
else if (parameterType == typeof(long) || enumType == typeof(long))
{
decodedFields[i] = BinaryPrimitives.ReadInt64LittleEndian(payload);
payload = payload.Slice(sizeof(long));
}
else if (parameterType == typeof(ulong))
else if (parameterType == typeof(ulong) || enumType == typeof(ulong))
{
decodedFields[i] = BinaryPrimitives.ReadUInt64LittleEndian(payload);
payload = payload.Slice(sizeof(ulong));
}
else if (parameterType == typeof(byte))
else if (parameterType == typeof(byte) || enumType == typeof(byte))
{
decodedFields[i] = MemoryMarshal.Read<byte>(payload);
payload = payload.Slice(sizeof(byte));
}
else if (parameterType == typeof(sbyte))
else if (parameterType == typeof(sbyte) || enumType == typeof(sbyte))
{
decodedFields[i] = MemoryMarshal.Read<sbyte>(payload);
payload = payload.Slice(sizeof(sbyte));
}
else if (parameterType == typeof(short))
else if (parameterType == typeof(short) || enumType == typeof(short))
{
decodedFields[i] = BinaryPrimitives.ReadInt16LittleEndian(payload);
payload = payload.Slice(sizeof(short));
}
else if (parameterType == typeof(ushort))
else if (parameterType == typeof(ushort) || enumType == typeof(ushort))
{
decodedFields[i] = BinaryPrimitives.ReadUInt16LittleEndian(payload);
payload = payload.Slice(sizeof(ushort));
Expand Down Expand Up @@ -137,7 +138,7 @@ internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, R
}
else
{
Debug.Fail("Unsupported type encountered.");
Debug.Fail($"Unsupported type \"{parameterType}\" encountered.");
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/tests/issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -1729,6 +1729,9 @@
<ExcludeList Include="$(XunitTestBinBase)/Regressions/coreclr/22021/consumer/**">
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/tracing/eventlistener/**">
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/tracing/tracevalidation/jittingstarted/JittingStarted/**">
<Issue>needs triage</Issue>
</ExcludeList>
Expand Down
80 changes: 80 additions & 0 deletions src/tests/tracing/eventlistener/EventListenerThreadPool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics.Tracing;
using System.Threading;
using System.Threading.Tasks;

namespace Tracing.Tests
{
internal sealed class RuntimeEventListener : EventListener
{
public volatile int TPWorkerThreadStartCount = 0;
public volatile int TPWorkerThreadStopCount = 0;
public volatile int TPWorkerThreadWaitCount = 0;

public ManualResetEvent TPWaitEvent = new ManualResetEvent(false);

protected override void OnEventSourceCreated(EventSource source)
{
if (source.Name.Equals("Microsoft-Windows-DotNETRuntime"))
{
EnableEvents(source, EventLevel.Informational, (EventKeywords)0x10000);
}
}

protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
if (eventData.EventName.Equals("ThreadPoolWorkerThreadStart"))
{
Interlocked.Increment(ref TPWorkerThreadStartCount);
TPWaitEvent.Set();
}
else if (eventData.EventName.Equals("ThreadPoolWorkerThreadStop"))
{
Interlocked.Increment(ref TPWorkerThreadStopCount);
TPWaitEvent.Set();
}
else if (eventData.EventName.Equals("ThreadPoolWorkerThreadWait"))
{
Interlocked.Increment(ref TPWorkerThreadWaitCount);
TPWaitEvent.Set();
}
}
}

class EventListenerThreadPool
{
static int Main(string[] args)
{
using (RuntimeEventListener listener = new RuntimeEventListener())
{
int someNumber = 0;
Task[] tasks = new Task[100];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = Task.Run(() => { someNumber += 1; });
}

listener.TPWaitEvent.WaitOne(TimeSpan.FromMinutes(3));

if (listener.TPWorkerThreadStartCount > 0 ||
listener.TPWorkerThreadStopCount > 0 ||
listener.TPWorkerThreadWaitCount > 0)
{
Console.WriteLine("Test Passed.");
return 100;
}
else
{
Console.WriteLine("Test Failed: Did not see any of the expected events.");
Console.WriteLine($"ThreadPoolWorkerThreadStartCount: {listener.TPWorkerThreadStartCount}");
Console.WriteLine($"ThreadPoolWorkerThreadStopCount: {listener.TPWorkerThreadStopCount}");
Console.WriteLine($"ThreadPoolWorkerThreadWaitCount: {listener.TPWorkerThreadWaitCount}");
return -1;
}
}
}
}
}
13 changes: 13 additions & 0 deletions src/tests/tracing/eventlistener/EventListenerThreadPool.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<CLRTestKind>BuildAndRun</CLRTestKind>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CLRTestPriority>0</CLRTestPriority>
<DisableProjectBuild Condition="'$(RuntimeFlavor)' == 'mono'">true</DisableProjectBuild>
</PropertyGroup>
<ItemGroup>
<Compile Include="EventListenerThreadPool.cs" />
<ProjectReference Include="../common/common.csproj" />
</ItemGroup>
</Project>

0 comments on commit 0f79fe3

Please sign in to comment.