From 3593cee083f1e994cfda99ba9873581d2e3fb6f5 Mon Sep 17 00:00:00 2001 From: Pent Ploompuu Date: Wed, 8 Jan 2025 11:48:28 +0200 Subject: [PATCH] Remove Interlocked -> Volatile changes --- .../PersistentStorage/DirectorySizeTracker.cs | 4 +-- .../Internal/InterlockedHelper.cs | 25 ++++++++++++++++--- .../Metrics/Exemplar/Exemplar.cs | 4 +-- .../Metrics/MetricPoint/MetricPoint.cs | 20 +++++++-------- .../MetricPointOptionalComponents.cs | 2 +- 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/DirectorySizeTracker.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/DirectorySizeTracker.cs index 26c607abb7f..2bbc352817d 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/DirectorySizeTracker.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/PersistentStorage/DirectorySizeTracker.cs @@ -36,14 +36,14 @@ public DirectorySizeTracker(long maxSizeInBytes, string path) /// True if space is available else false. public bool IsSpaceAvailable(out long currentSizeInBytes) { - currentSizeInBytes = Volatile.Read(ref this.directoryCurrentSizeInBytes); + currentSizeInBytes = Interlocked.Read(ref this.directoryCurrentSizeInBytes); return currentSizeInBytes < this.maxSizeInBytes; } public void RecountCurrentSize() { var size = CalculateFolderSize(this.path); - Volatile.Write(ref this.directoryCurrentSizeInBytes, size); + Interlocked.Exchange(ref this.directoryCurrentSizeInBytes, size); } internal static long CalculateFolderSize(string path) diff --git a/src/OpenTelemetry/Internal/InterlockedHelper.cs b/src/OpenTelemetry/Internal/InterlockedHelper.cs index 596c7eb89c8..98639d234a4 100644 --- a/src/OpenTelemetry/Internal/InterlockedHelper.cs +++ b/src/OpenTelemetry/Internal/InterlockedHelper.cs @@ -10,9 +10,30 @@ internal static class InterlockedHelper [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Add(ref double location, double value) { + // Note: Not calling InterlockedHelper.Read here on purpose because it + // is too expensive for fast/happy-path. If the first attempt fails + // we'll end up in an Interlocked.CompareExchange loop anyway. double currentValue = Volatile.Read(ref location); + + var returnedValue = Interlocked.CompareExchange(ref location, currentValue + value, currentValue); + if (returnedValue != currentValue) + { + AddRare(ref location, value, returnedValue); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Read(ref double location) + => Interlocked.CompareExchange(ref location, double.NaN, double.NaN); + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void AddRare(ref double location, double value, double currentValue) + { + var sw = default(SpinWait); while (true) { + sw.SpinOnce(); + var returnedValue = Interlocked.CompareExchange(ref location, currentValue + value, currentValue); if (returnedValue == currentValue) { @@ -22,8 +43,4 @@ public static void Add(ref double location, double value) currentValue = returnedValue; } } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Read(ref double location) - => Interlocked.CompareExchange(ref location, 0, 0); } diff --git a/src/OpenTelemetry/Metrics/Exemplar/Exemplar.cs b/src/OpenTelemetry/Metrics/Exemplar/Exemplar.cs index 6f32e43d1d3..d1801afdd39 100644 --- a/src/OpenTelemetry/Metrics/Exemplar/Exemplar.cs +++ b/src/OpenTelemetry/Metrics/Exemplar/Exemplar.cs @@ -135,7 +135,7 @@ internal void Update(in ExemplarMeasurement measurement) this.StoreRawTags(measurement.Tags); } - Volatile.Write(ref this.isCriticalSectionOccupied, 0); + Interlocked.Exchange(ref this.isCriticalSectionOccupied, 0); } internal void Reset() @@ -168,7 +168,7 @@ internal void Collect(ref Exemplar destination, bool reset) destination.Reset(); } - Volatile.Write(ref this.isCriticalSectionOccupied, 0); + Interlocked.Exchange(ref this.isCriticalSectionOccupied, 0); } internal readonly void Copy(ref Exemplar destination) diff --git a/src/OpenTelemetry/Metrics/MetricPoint/MetricPoint.cs b/src/OpenTelemetry/Metrics/MetricPoint/MetricPoint.cs index eea5c83bfa6..8c0ad5951fc 100644 --- a/src/OpenTelemetry/Metrics/MetricPoint/MetricPoint.cs +++ b/src/OpenTelemetry/Metrics/MetricPoint/MetricPoint.cs @@ -394,7 +394,7 @@ internal void Update(long number) case AggregationType.LongSumIncomingCumulative: case AggregationType.LongGauge: { - Volatile.Write(ref this.runningValue.AsLong, number); + Interlocked.Exchange(ref this.runningValue.AsLong, number); break; } @@ -451,7 +451,7 @@ internal void UpdateWithExemplar(long number, ReadOnlySpan