Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for EventListener consuming ThreadPool events #48487

Merged
Merged
Show file tree
Hide file tree
Changes from 14 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
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
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ internal unsafe void ProcessEvent(uint eventID, uint osThreadID, DateTime timeSt
}

// Decode the payload.
Debug.WriteLine($"Decoding payload: {eventID}");
davmason marked this conversation as resolved.
Show resolved Hide resolved
object[] decodedPayloadFields = EventPipePayloadDecoder.DecodePayload(ref m_eventData[eventID], payload);

var eventCallbackArgs = new EventWrittenEventArgs(this, (int)eventID, &activityId, &childActivityId)
Expand Down
3 changes: 3 additions & 0 deletions src/tests/issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,9 @@
<ExcludeList Include="$(XunitTestBinBase)/Regressions/coreclr/22021/consumer/**">
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/tracing/eventlistener/**">
<Issue>needs triage</Issue>
</ExcludeList>
davmason marked this conversation as resolved.
Show resolved Hide resolved
<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));
davmason marked this conversation as resolved.
Show resolved Hide resolved

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>