1 use std::{ 2 sync::{Arc, Barrier}, 3 thread, 4 time::{Duration, Instant}, 5 }; 6 use tracing::dispatcher::Dispatch; 7 8 #[derive(Clone)] 9 pub(super) struct MultithreadedBench { 10 start: Arc<Barrier>, 11 end: Arc<Barrier>, 12 dispatch: Dispatch, 13 } 14 15 impl MultithreadedBench { new(dispatch: Dispatch) -> Self16 pub(super) fn new(dispatch: Dispatch) -> Self { 17 Self { 18 start: Arc::new(Barrier::new(5)), 19 end: Arc::new(Barrier::new(5)), 20 dispatch, 21 } 22 } 23 thread(&self, f: impl FnOnce() + Send + 'static) -> &Self24 pub(super) fn thread(&self, f: impl FnOnce() + Send + 'static) -> &Self { 25 self.thread_with_setup(|start| { 26 start.wait(); 27 f() 28 }) 29 } 30 thread_with_setup(&self, f: impl FnOnce(&Barrier) + Send + 'static) -> &Self31 pub(super) fn thread_with_setup(&self, f: impl FnOnce(&Barrier) + Send + 'static) -> &Self { 32 let this = self.clone(); 33 thread::spawn(move || { 34 let dispatch = this.dispatch.clone(); 35 tracing::dispatcher::with_default(&dispatch, move || { 36 f(&this.start); 37 this.end.wait(); 38 }) 39 }); 40 self 41 } 42 run(&self) -> Duration43 pub(super) fn run(&self) -> Duration { 44 self.start.wait(); 45 let t0 = Instant::now(); 46 self.end.wait(); 47 t0.elapsed() 48 } 49 } 50