Skip to content

Commit 9546ac1

Browse files
authored
Merge pull request #270 from camelid/fix-rust-crate-add-delays
rust: Call _coz_add_delays() after counter increments
2 parents 481f460 + 7cb3c86 commit 9546ac1

1 file changed

Lines changed: 35 additions & 2 deletions

File tree

rust/src/lib.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use once_cell::sync::OnceCell;
1515
use std::ffi::{CStr, CString};
1616
use std::mem;
17-
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
17+
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
1818

1919
/// Equivalent of the `COZ_PROGRESS` and `COZ_PROGRESS_NAMED` macros
2020
///
@@ -158,7 +158,8 @@ impl Counter {
158158
mem::size_of_val(&counter.count),
159159
mem::size_of::<libc::size_t>()
160160
);
161-
counter.count.fetch_add(1, SeqCst);
161+
counter.count.fetch_add(1, Relaxed);
162+
coz_add_delays();
162163
}
163164
}
164165

@@ -203,6 +204,11 @@ struct coz_counter_t {
203204
/// `typedef coz_counter_t* (*coz_get_counter_t)(int, const char*);`
204205
type GetCounterFn = unsafe extern "C" fn(libc::c_int, *const libc::c_char) -> *mut coz_counter_t;
205206

207+
/// The type of `_coz_add_delays` as defined in `include/coz.h`
208+
///
209+
/// `typedef void (*coz_add_delays_t)(void);`
210+
type AddDelaysFn = unsafe extern "C" fn();
211+
206212
#[cfg(target_os = "linux")]
207213
fn coz_get_counter(ty: libc::c_int, name: &CStr) -> Option<*mut coz_counter_t> {
208214
static GET_COUNTER: OnceCell<Option<GetCounterFn>> = OnceCell::new();
@@ -226,7 +232,34 @@ fn coz_get_counter(ty: libc::c_int, name: &CStr) -> Option<*mut coz_counter_t> {
226232
func.map(|f| unsafe { f(ty, name.as_ptr()) })
227233
}
228234

235+
/// Calls `_coz_add_delays()` from libcoz.
236+
///
237+
/// This must be called after every counter increment to allow the profiler to
238+
/// inject virtual delays for causal profiling experiments. Without this call,
239+
/// the profiler cannot detect progress points and will report 0 experiments.
240+
#[cfg(target_os = "linux")]
241+
fn coz_add_delays() {
242+
static ADD_DELAYS: OnceCell<Option<AddDelaysFn>> = OnceCell::new();
243+
let func = ADD_DELAYS.get_or_init(|| {
244+
let name = CStr::from_bytes_with_nul(b"_coz_add_delays\0").unwrap();
245+
let func = unsafe { libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) };
246+
if func.is_null() {
247+
None
248+
} else {
249+
Some(unsafe { mem::transmute(func) })
250+
}
251+
});
252+
253+
if let Some(f) = func {
254+
// SAFETY: _coz_add_delays is a void->void function with no invariants.
255+
unsafe { f() };
256+
}
257+
}
258+
229259
#[cfg(not(target_os = "linux"))]
230260
fn coz_get_counter(_ty: libc::c_int, _name: &CStr) -> Option<*mut coz_counter_t> {
231261
None
232262
}
263+
264+
#[cfg(not(target_os = "linux"))]
265+
fn coz_add_delays() {}

0 commit comments

Comments
 (0)