-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathThreadLocalSampleCollector.cs
88 lines (71 loc) · 2.26 KB
/
ThreadLocalSampleCollector.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System;
using System.Collections.Generic;
using System.Threading;
namespace PostSharp.Samples.Profiling
{
internal class ThreadLocalSampleCollector
{
private readonly Thread _ownerThread = Thread.CurrentThread;
private MetricAccessor[] _metrics = new MetricAccessor[1024];
private readonly SampleCollector _parent;
private readonly Stack<MetricAccessor> _contextStack = new Stack<MetricAccessor>();
public ThreadLocalSampleCollector(SampleCollector parent)
{
this._parent = parent;
}
public void EnterMethod(MetricMetadata method)
{
this._contextStack.Push(this.GetAccessor(method));
}
public void ExitMethod(MetricMetadata method, in ExcludedTimeData excludedData)
{
if (this._contextStack.Pop().Metadata != method)
{
throw new InvalidOperationException();
}
if (_contextStack.Count > 0)
{
var parentContext = _contextStack.Peek();
parentContext.AddExclusion(excludedData);
}
}
public bool GetSample(MetricMetadata method, out MetricData data)
{
MetricAccessor metric;
if (this._metrics.Length <= method.Index || (metric = this._metrics[method.Index]) == null)
{
data = default;
return false;
}
else
{
metric.GetData(out data);
return true;
}
}
public void AddSample(MetricMetadata method, in MetricData data)
{
var sampleAccessor = GetAccessor(method);
sampleAccessor.AddData(data);
}
private MetricAccessor GetAccessor(MetricMetadata method)
{
#if DEBUG
if (this._ownerThread != Thread.CurrentThread)
{
throw new InvalidOperationException("Cannot get a mutable MetricAccessor from a different thread than the owner thread.");
}
#endif
if (this._metrics.Length <= method.Index)
{
Array.Resize(ref this._metrics, ((this._parent.ProfiledMethodCount / 1024) + 1) * 1024);
}
var sampleAccessor = this._metrics[method.Index];
if (sampleAccessor == null)
{
this._metrics[method.Index] = sampleAccessor = new MetricAccessor(method);
}
return sampleAccessor;
}
}
}