Skip to content

Commit 8400cfa

Browse files
committed
Init host_time_to_ns_ratio with context
The current HOST_TIME_TO_NS_RATIO implemented with lazy_static is causing what appears to be false-positive TSAN errors. OnceLock and LazyLock exhibit similar errors under TSAN. It seemed easier to rewrite host_time_to_ns_ratio to be a init-once context member, rather than making the unstable `no_sanitize` attribute work. Being unstable it also needed to be included conditionally only when compiled with the nightly compiler. And trying the rustversion crate for this resulted in compilation failure due to TSAN reporting it doesn't work...
1 parent 187c0ba commit 8400cfa

File tree

3 files changed

+15
-20
lines changed

3 files changed

+15
-20
lines changed

Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ coreaudio-sys-utils = { path = "coreaudio-sys-utils" }
1414
cubeb-backend = "0.13"
1515
float-cmp = "0.6"
1616
libc = "0.2"
17-
lazy_static = "1.2"
1817
mach = "0.3"
1918
audio-mixer = "0.2"
2019
ringbuf = "0.2.6"

src/backend/mod.rs

+15-17
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
// accompanying file LICENSE for details.
55
#![allow(unused_assignments)]
66
#![allow(unused_must_use)]
7-
87
extern crate coreaudio_sys_utils;
98
extern crate libc;
109
extern crate ringbuf;
@@ -106,16 +105,6 @@ bitflags! {
106105
}
107106
}
108107

109-
lazy_static! {
110-
static ref HOST_TIME_TO_NS_RATIO: (u32, u32) = {
111-
let mut timebase_info = mach_timebase_info { numer: 0, denom: 0 };
112-
unsafe {
113-
mach_timebase_info(&mut timebase_info);
114-
}
115-
(timebase_info.numer, timebase_info.denom)
116-
};
117-
}
118-
119108
#[cfg(feature = "audio-dump")]
120109
fn dump_audio(stream: cubeb_audio_dump_stream_t, audio_samples: *mut c_void, count: u32) {
121110
unsafe {
@@ -682,10 +671,10 @@ extern "C" fn audiounit_input_callback(
682671
}
683672
}
684673

685-
fn host_time_to_ns(host_time: u64) -> u64 {
674+
fn host_time_to_ns(ctx: &AudioUnitContext, host_time: u64) -> u64 {
686675
let mut rv: f64 = host_time as f64;
687-
rv *= HOST_TIME_TO_NS_RATIO.0 as f64;
688-
rv /= HOST_TIME_TO_NS_RATIO.1 as f64;
676+
rv *= ctx.host_time_to_ns_ratio.0 as f64;
677+
rv /= ctx.host_time_to_ns_ratio.1 as f64;
689678
rv as u64
690679
}
691680

@@ -697,7 +686,7 @@ fn compute_output_latency(stm: &AudioUnitStream, audio_output_time: u64, now: u6
697686
// The total output latency is the timestamp difference + the stream latency + the hardware
698687
// latency.
699688
let total_output_latency_ns =
700-
fixed_latency_ns + host_time_to_ns(audio_output_time.saturating_sub(now));
689+
fixed_latency_ns + host_time_to_ns(stm.context, audio_output_time.saturating_sub(now));
701690

702691
(total_output_latency_ns * output_hw_rate / NS2S) as u32
703692
}
@@ -710,7 +699,7 @@ fn compute_input_latency(stm: &AudioUnitStream, audio_input_time: u64, now: u64)
710699
// The total input latency is the timestamp difference + the stream latency +
711700
// the hardware latency.
712701
let total_input_latency_ns =
713-
host_time_to_ns(now.saturating_sub(audio_input_time)) + fixed_latency_ns;
702+
host_time_to_ns(stm.context, now.saturating_sub(audio_input_time)) + fixed_latency_ns;
714703

715704
(total_input_latency_ns * input_hw_rate / NS2S) as u32
716705
}
@@ -2483,6 +2472,7 @@ pub struct AudioUnitContext {
24832472
serial_queue: Queue,
24842473
latency_controller: Mutex<LatencyController>,
24852474
devices: Mutex<SharedDevices>,
2475+
host_time_to_ns_ratio: (u32, u32),
24862476
// Storage for a context-global vpio unit. Duplex streams that need one will take this
24872477
// and return it when done.
24882478
shared_voice_processing_unit: SharedVoiceProcessingUnitManager,
@@ -2497,11 +2487,19 @@ impl AudioUnitContext {
24972487
format!("{}.context.shared_vpio", DISPATCH_QUEUE_LABEL).as_str(),
24982488
&serial_queue,
24992489
);
2490+
let host_time_to_ns_ratio = {
2491+
let mut timebase_info = mach_timebase_info { numer: 0, denom: 0 };
2492+
unsafe {
2493+
mach_timebase_info(&mut timebase_info);
2494+
}
2495+
(timebase_info.numer, timebase_info.denom)
2496+
};
25002497
Self {
25012498
_ops: &OPS as *const _,
25022499
serial_queue,
25032500
latency_controller: Mutex::new(LatencyController::default()),
25042501
devices: Mutex::new(SharedDevices::default()),
2502+
host_time_to_ns_ratio,
25052503
shared_voice_processing_unit: SharedVoiceProcessingUnitManager::new(shared_vp_queue),
25062504
}
25072505
}
@@ -4931,7 +4929,7 @@ impl<'ctx> StreamOps for AudioUnitStream<'ctx> {
49314929
let now = unsafe { mach_absolute_time() };
49324930
let diff = now - timestamp;
49334931
let interpolated_frames = cmp::min(
4934-
host_time_to_ns(diff)
4932+
host_time_to_ns(self.context, diff)
49354933
* self.core_stream_data.output_stream_params.rate() as u64
49364934
/ NS2S,
49374935
buffer_size,

src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ extern crate bitflags;
1010
extern crate cubeb_backend;
1111
#[macro_use]
1212
extern crate float_cmp;
13-
#[macro_use]
14-
extern crate lazy_static;
1513
extern crate mach;
1614

1715
mod backend;

0 commit comments

Comments
 (0)