From a337c0cceaf16628988a9456295c39ed6c0af645 Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Thu, 26 Feb 2026 23:48:41 +0100 Subject: [PATCH] [fix](trx-backend-soapysdr): throttle MockIqSource to avoid 100% CPU load Add sleep proportional to block duration in iq_read_loop to simulate real hardware timing. MockIqSource immediately returns samples without any delay, causing busy-looping. Throttling prevents excessive CPU usage when using the mock source. Co-Authored-By: Claude Opus 4.6 --- .../trx-backend/trx-backend-soapysdr/src/dsp.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp.rs b/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp.rs index 19a9ce1..1366cc2 100644 --- a/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp.rs +++ b/src/trx-server/trx-backend/trx-backend-soapysdr/src/dsp.rs @@ -377,11 +377,18 @@ const IQ_BLOCK_SIZE: usize = 4096; /// subscribers. fn iq_read_loop( mut source: Box, - _sdr_sample_rate: u32, + sdr_sample_rate: u32, channel_dsps: Vec>>, iq_tx: broadcast::Sender>>, ) { let mut block = vec![Complex::new(0.0_f32, 0.0_f32); IQ_BLOCK_SIZE]; + // Estimate time per block: IQ_BLOCK_SIZE samples at sdr_sample_rate Hz. + // This is used to throttle MockIqSource to avoid busy-looping. + let block_duration_ms = if sdr_sample_rate > 0 { + (IQ_BLOCK_SIZE as f64 / sdr_sample_rate as f64 * 1000.0) as u64 + } else { + 1 + }; loop { let n = match source.read_into(&mut block) { @@ -414,6 +421,11 @@ fn iq_read_loop( } } } + + // Throttle to avoid busy-looping when using MockIqSource. + // Real hardware would naturally have this timing; + // the mock needs artificial throttling. + std::thread::sleep(std::time::Duration::from_millis(block_duration_ms)); } }