Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit b4e920d

Browse files
authored
Merge pull request #23661 from jorive/dev/issue-23562
[release/2.2][Port] Fix EventPipe EventHandle Caching for TraceLogging (#18355)
2 parents 6a34c83 + bc72777 commit b4e920d

File tree

4 files changed

+74
-13
lines changed

4 files changed

+74
-13
lines changed

src/mscorlib/System.Private.CoreLib.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@
531531
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventPipeEventDispatcher.cs" />
532532
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventPipeEventProvider.cs" />
533533
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventPipeMetadataGenerator.cs" />
534+
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingEventHandleTable.cs" />
534535
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventPipePayloadDecoder.cs" />
535536
</ItemGroup>
536537
<ItemGroup>

src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ internal static void ReserveEventIDsBelow(int eventId)
4242
internal readonly int identity;
4343
internal readonly byte[] nameMetadata;
4444

45-
#if FEATURE_PERFTRACING
46-
private readonly object eventHandleCreationLock = new object();
47-
#endif
4845

4946
public NameInfo(string name, EventTags tags, int typeMetadataSize)
5047
{
@@ -82,14 +79,14 @@ private int Compare(string otherName, EventTags otherTags)
8279
}
8380

8481
#if FEATURE_PERFTRACING
85-
public IntPtr GetOrCreateEventHandle(EventProvider provider, ConcurrentDictionary<int, IntPtr> eventHandleMap, EventDescriptor descriptor, TraceLoggingEventTypes eventTypes)
82+
public IntPtr GetOrCreateEventHandle(EventProvider provider, TraceLoggingEventHandleTable eventHandleTable, EventDescriptor descriptor, TraceLoggingEventTypes eventTypes)
8683
{
87-
IntPtr eventHandle = IntPtr.Zero;
88-
if(!eventHandleMap.TryGetValue(descriptor.EventId, out eventHandle))
84+
IntPtr eventHandle;
85+
if ((eventHandle = eventHandleTable[descriptor.EventId]) == IntPtr.Zero)
8986
{
90-
lock (eventHandleCreationLock)
87+
lock (eventHandleTable)
9188
{
92-
if (!eventHandleMap.TryGetValue(descriptor.EventId, out eventHandle))
89+
if ((eventHandle = eventHandleTable[descriptor.EventId]) == IntPtr.Zero)
9390
{
9491
byte[] metadataBlob = EventPipeMetadataGenerator.Instance.GenerateEventMetadata(
9592
descriptor.EventId,
@@ -115,6 +112,9 @@ public IntPtr GetOrCreateEventHandle(EventProvider provider, ConcurrentDictionar
115112
metadataLength);
116113
}
117114
}
115+
116+
// Cache the event handle.
117+
eventHandleTable.SetEventHandle(descriptor.EventId, eventHandle);
118118
}
119119
}
120120
}

src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
using System.Runtime.InteropServices;
2525
using System.Security;
2626
using System.Collections.ObjectModel;
27-
using System.Collections.Concurrent;
2827

2928
#if !ES_BUILD_AGAINST_DOTNET_V35
3029
using Contract = System.Diagnostics.Contracts.Contract;
@@ -49,7 +48,7 @@ public partial class EventSource
4948
#endif
5049

5150
#if FEATURE_PERFTRACING
52-
private ConcurrentDictionary<int, IntPtr> m_eventHandleMap = new ConcurrentDictionary<int, IntPtr>();
51+
private readonly TraceLoggingEventHandleTable m_eventHandleTable = new TraceLoggingEventHandleTable();
5352
#endif
5453

5554
/// <summary>
@@ -437,7 +436,7 @@ private unsafe void WriteMultiMergeInner(
437436
EventDescriptor descriptor = new EventDescriptor(identity, level, opcode, (long)keywords);
438437

439438
#if FEATURE_PERFTRACING
440-
IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes);
439+
IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleTable, descriptor, eventTypes);
441440
Debug.Assert(eventHandle != IntPtr.Zero);
442441
#else
443442
IntPtr eventHandle = IntPtr.Zero;
@@ -552,7 +551,7 @@ internal unsafe void WriteMultiMerge(
552551
}
553552

554553
#if FEATURE_PERFTRACING
555-
IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes);
554+
IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleTable, descriptor, eventTypes);
556555
Debug.Assert(eventHandle != IntPtr.Zero);
557556
#else
558557
IntPtr eventHandle = IntPtr.Zero;
@@ -621,7 +620,7 @@ private unsafe void WriteImpl(
621620
}
622621

623622
#if FEATURE_PERFTRACING
624-
IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes);
623+
IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleTable, descriptor, eventTypes);
625624
Debug.Assert(eventHandle != IntPtr.Zero);
626625
#else
627626
IntPtr eventHandle = IntPtr.Zero;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Threading;
6+
7+
namespace System.Diagnostics.Tracing
8+
{
9+
#if FEATURE_PERFTRACING
10+
/// <summary>
11+
/// Per-EventSource data structure for caching EventPipe EventHandles associated with TraceLogging events.
12+
/// </summary>
13+
internal sealed class TraceLoggingEventHandleTable
14+
{
15+
private const int DefaultLength = 10;
16+
private IntPtr[] m_innerTable;
17+
18+
internal TraceLoggingEventHandleTable()
19+
{
20+
m_innerTable = new IntPtr[DefaultLength];
21+
}
22+
23+
internal IntPtr this[int eventID]
24+
{
25+
get
26+
{
27+
IntPtr ret = IntPtr.Zero;
28+
IntPtr[] innerTable = Volatile.Read(ref m_innerTable);
29+
30+
if (eventID >= 0 && eventID < innerTable.Length)
31+
{
32+
ret = innerTable[eventID];
33+
}
34+
35+
return ret;
36+
}
37+
}
38+
39+
internal void SetEventHandle(int eventID, IntPtr eventHandle)
40+
{
41+
// Set operations must be serialized to ensure that re-size operations don't lose concurrent writes.
42+
Debug.Assert(Monitor.IsEntered(this));
43+
44+
if (eventID >= m_innerTable.Length)
45+
{
46+
int newSize = m_innerTable.Length * 2;
47+
if (newSize <= eventID)
48+
{
49+
newSize = eventID + 1;
50+
}
51+
52+
IntPtr[] newTable = new IntPtr[newSize];
53+
Array.Copy(m_innerTable, 0, newTable, 0, m_innerTable.Length);
54+
Volatile.Write(ref m_innerTable, newTable);
55+
}
56+
57+
m_innerTable[eventID] = eventHandle;
58+
}
59+
}
60+
#endif
61+
}

0 commit comments

Comments
 (0)