From 0a9fc7aaa6957790fdb4835b9834f0ed0580c33a Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 8 May 2026 07:41:56 +0000 Subject: [PATCH] Yield collect-thread spin loops to unblock preempted recorders Both spin loops in DeltaSynchronousMetricStorage burned the collect thread's core while waiting for a recorder that may have been preempted mid-section. On constrained CPU (single-CPU containers, pinned cores), the recorder could not be rescheduled until the OS forced a quantum, multiplied per stuck handle. Add Thread.yield() in both loops so the collect thread releases its core. Matches the existing yield in acquireHandleForRecord. Signed-off-by: Gregor Zeitlinger --- .../internal/state/DeltaSynchronousMetricStorage.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DeltaSynchronousMetricStorage.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DeltaSynchronousMetricStorage.java index 18007dc28a3..2b3e3d9ff43 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DeltaSynchronousMetricStorage.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/state/DeltaSynchronousMetricStorage.java @@ -291,9 +291,11 @@ boolean isLockedForCollect() { } /** Locks new-series creation and waits for any in-flight new-series operations to complete. */ + @SuppressWarnings("ThreadPriorityCheck") void lockForCollectAndAwait() { int s = newSeriesGate.addAndGet(1); while (s != 1) { + Thread.yield(); s = newSeriesGate.get(); } } @@ -350,8 +352,11 @@ void lockForCollect() { } /** Waits for all in-flight recorders to finish, then clears the collection lock. */ + @SuppressWarnings("ThreadPriorityCheck") void awaitRecordersAndUnlock() { - while (state.get() > 1) {} + while (state.get() > 1) { + Thread.yield(); + } state.addAndGet(-1); } }