Skip to content

Commit 7c919d7

Browse files
committed
Reduce overhead when FAILPOINTS is empty
Reduce fail_point! overhead with empty FAILPOINTS from about 9ns to 0.3ns. This could be useful when the failpoints feature is enabled but FAILPOINTS are not set most of the time. Signed-off-by: Jun Wu <[email protected]>
1 parent 5bc95a1 commit 7c919d7

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

src/lib.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ use std::collections::HashMap;
229229
use std::env::VarError;
230230
use std::fmt::Debug;
231231
use std::str::FromStr;
232-
use std::sync::atomic::{AtomicUsize, Ordering};
232+
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
233233
use std::sync::{Arc, Condvar, Mutex, MutexGuard, RwLock, TryLockError};
234234
use std::time::{Duration, Instant};
235235
use std::{env, thread};
@@ -528,6 +528,9 @@ use once_cell::sync::Lazy;
528528
static REGISTRY: Lazy<FailPointRegistry> = Lazy::new(FailPointRegistry::default);
529529
static SCENARIO: Lazy<Mutex<&'static FailPointRegistry>> = Lazy::new(|| Mutex::new(&REGISTRY));
530530

531+
#[doc(hidden)]
532+
pub static REGISTRY_IS_EMPTY: AtomicBool = AtomicBool::new(true);
533+
531534
/// Test scenario with configured fail points.
532535
#[derive(Debug)]
533536
pub struct FailScenario<'a> {
@@ -580,6 +583,7 @@ impl<'a> FailScenario<'a> {
580583
}
581584
}
582585
}
586+
update_registry_is_empty(&registry);
583587
Self { scenario_guard }
584588
}
585589

@@ -601,6 +605,7 @@ impl<'a> FailScenario<'a> {
601605
p.set_actions("", vec![]);
602606
}
603607
registry.clear();
608+
update_registry_is_empty(registry);
604609
}
605610
}
606611

@@ -675,7 +680,9 @@ pub fn eval<R, F: FnOnce(Option<String>) -> R>(name: &str, f: F) -> Option<R> {
675680
/// that fail point, including those set via the `FAILPOINTS` environment variable.
676681
pub fn cfg<S: Into<String>>(name: S, actions: &str) -> Result<(), String> {
677682
let mut registry = REGISTRY.registry.write().unwrap();
678-
set(&mut registry, name.into(), actions)
683+
set(&mut registry, name.into(), actions)?;
684+
update_registry_is_empty(&registry);
685+
Ok(())
679686
}
680687

681688
/// Configure the actions for a fail point at runtime.
@@ -694,6 +701,7 @@ where
694701
let action = Action::from_callback(f);
695702
let actions = vec![action];
696703
p.set_actions("callback", actions);
704+
update_registry_is_empty(&registry);
697705
Ok(())
698706
}
699707

@@ -762,6 +770,10 @@ fn set(
762770
Ok(())
763771
}
764772

773+
fn update_registry_is_empty(registry: &HashMap<String, Arc<FailPoint>>) {
774+
REGISTRY_IS_EMPTY.store(registry.is_empty(), Ordering::Release);
775+
}
776+
765777
/// Define a fail point (requires `failpoints` feature).
766778
///
767779
/// The `fail_point!` macro has three forms, and they all take a name as the
@@ -827,13 +839,17 @@ fn set(
827839
#[cfg(feature = "failpoints")]
828840
macro_rules! fail_point {
829841
($name:expr) => {{
830-
$crate::eval($name, |_| {
831-
panic!("Return is not supported for the fail point \"{}\"", $name);
832-
});
842+
if !$crate::REGISTRY_IS_EMPTY.load(::std::sync::atomic::Ordering::Acquire) {
843+
$crate::eval($name, |_| {
844+
panic!("Return is not supported for the fail point \"{}\"", $name);
845+
});
846+
}
833847
}};
834848
($name:expr, $e:expr) => {{
835-
if let Some(res) = $crate::eval($name, $e) {
836-
return res;
849+
if !$crate::REGISTRY_IS_EMPTY.load(::std::sync::atomic::Ordering::Acquire) {
850+
if let Some(res) = $crate::eval($name, $e) {
851+
return res;
852+
}
837853
}
838854
}};
839855
($name:expr, $cond:expr, $e:expr) => {{

0 commit comments

Comments
 (0)