diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 4b8511ce1ed..ef6dcfff080 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -2,9 +2,13 @@ ## Unreleased -* Make `IResourceDetector` public to allow custom implementations of resource detectors. +* Make `IResourceDetector` public to allow custom implementations of resource + detectors. ([2897](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2897)) +* Perf improvement for Histogram, by implementing lock-free updates. + ([2951](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2951)) + ## 1.2.0-rc2 Released 2022-Feb-02 diff --git a/src/OpenTelemetry/Metrics/HistogramBuckets.cs b/src/OpenTelemetry/Metrics/HistogramBuckets.cs index a68033d4300..71e1b52eb21 100644 --- a/src/OpenTelemetry/Metrics/HistogramBuckets.cs +++ b/src/OpenTelemetry/Metrics/HistogramBuckets.cs @@ -32,6 +32,8 @@ public class HistogramBuckets internal double SnapshotSum; + internal int IsCriticalSectionOccupied = 0; + internal HistogramBuckets(double[] explicitBounds) { this.ExplicitBounds = explicitBounds; diff --git a/src/OpenTelemetry/Metrics/MetricPoint.cs b/src/OpenTelemetry/Metrics/MetricPoint.cs index 4d8ce31036e..f27219af55c 100644 --- a/src/OpenTelemetry/Metrics/MetricPoint.cs +++ b/src/OpenTelemetry/Metrics/MetricPoint.cs @@ -323,11 +323,23 @@ internal void Update(double number) } } - lock (this.histogramBuckets.LockObject) + var sw = default(SpinWait); + while (true) { - this.runningValue.AsLong++; - this.histogramBuckets.RunningSum += number; - this.histogramBuckets.RunningBucketCounts[i]++; + if (Interlocked.Exchange(ref this.histogramBuckets.IsCriticalSectionOccupied, 1) == 0) + { + unchecked + { + this.runningValue.AsLong++; + this.histogramBuckets.RunningSum += number; + this.histogramBuckets.RunningBucketCounts[i]++; + } + + this.histogramBuckets.IsCriticalSectionOccupied = 0; + break; + } + + sw.SpinOnce(); } break;