1use std::{
2 sync::{Arc, Barrier},
3 thread,
4 time::{Duration, Instant},
5};
6use tracing::dispatcher::Dispatch;
7
8#[derive(Clone)]
9pub(super) struct MultithreadedBench {
10 start: Arc<Barrier>,
11 end: Arc<Barrier>,
12 dispatch: Dispatch,
13}
14
15impl MultithreadedBench {
16 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
24 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
31 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
43 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