Skip to content

Commit

Permalink
Support Concurrent Access to LinuxPerfScriptProcessNameBuilder (#2066)
Browse files Browse the repository at this point in the history
* Support concurrent access to LinuxPerfScriptProcessNameBuilder.

Required to support ParallelLinuxPerfScriptStackSource.

* Make lock name more descriptive.
  • Loading branch information
brianrob authored Jul 15, 2024
1 parent 4b1a648 commit 3ad5a8c
Showing 1 changed file with 21 additions and 11 deletions.
32 changes: 21 additions & 11 deletions src/TraceEvent/Stacks/Linux/LinuxPerfScriptProcessNameBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;

namespace Microsoft.Diagnostics.Tracing.StackSources
{
Expand All @@ -16,36 +17,45 @@ internal sealed class LinuxPerfScriptProcessNameBuilder
".NET Server GC"
};

private readonly object _dictionariesLock = new object();
private Dictionary<StackSourceFrameIndex, HashSet<string>> _candidateProcessNames = new Dictionary<StackSourceFrameIndex, HashSet<string>>();
private Dictionary<StackSourceFrameIndex, string> _cachedProcessNames = new Dictionary<StackSourceFrameIndex, string>();
private Dictionary<StackSourceFrameIndex, int> _processIds = new Dictionary<StackSourceFrameIndex, int>();

internal void SaveProcessName(StackSourceFrameIndex frameIndex, string processName, int processId)
{
if (!_candidateProcessNames.TryGetValue(frameIndex, out HashSet<string> processNames))
lock (_dictionariesLock)
{
processNames = new HashSet<string>();
_candidateProcessNames.Add(frameIndex, processNames);
}
if (!_candidateProcessNames.TryGetValue(frameIndex, out HashSet<string> processNames))
{
processNames = new HashSet<string>();
_candidateProcessNames.Add(frameIndex, processNames);
}

processNames.Add(processName);
processNames.Add(processName);

_processIds[frameIndex] = processId;
_processIds[frameIndex] = processId;
}
}

internal string GetProcessName(StackSourceFrameIndex frameIndex)
{
if (!_cachedProcessNames.TryGetValue(frameIndex, out string processName))
lock (_dictionariesLock)
{
processName = BuildProcessName(frameIndex);
_cachedProcessNames.Add(frameIndex, processName);
}
if (!_cachedProcessNames.TryGetValue(frameIndex, out string processName))
{
processName = BuildProcessName(frameIndex);
_cachedProcessNames.Add(frameIndex, processName);
}

return processName;
return processName;
}
}

private string BuildProcessName(StackSourceFrameIndex frameIndex)
{
Debug.Assert(Monitor.IsEntered(_dictionariesLock));

if (_candidateProcessNames.TryGetValue(frameIndex, out HashSet<string> processNames))
{
int processId = _processIds[frameIndex];
Expand Down

0 comments on commit 3ad5a8c

Please sign in to comment.