1 //! Multi-threaded runtime
2 
3 mod counters;
4 use counters::Counters;
5 
6 mod handle;
7 pub(crate) use handle::Handle;
8 
9 mod overflow;
10 pub(crate) use overflow::Overflow;
11 
12 mod idle;
13 use self::idle::Idle;
14 
15 mod stats;
16 pub(crate) use stats::Stats;
17 
18 pub(crate) mod queue;
19 
20 mod worker;
21 use worker::Core;
22 pub(crate) use worker::{Context, Shared};
23 
24 // TODO: implement task dump
25 mod trace_mock;
26 use trace_mock::TraceStatus;
27 
28 pub(crate) use worker::block_in_place;
29 
30 use crate::runtime::{
31     self, blocking,
32     driver::{self, Driver},
33     scheduler, Config,
34 };
35 use crate::util::RngSeedGenerator;
36 
37 use std::fmt;
38 use std::future::Future;
39 
40 /// Work-stealing based thread pool for executing futures.
41 pub(crate) struct MultiThread;
42 
43 // ===== impl MultiThread =====
44 
45 impl MultiThread {
new( size: usize, driver: Driver, driver_handle: driver::Handle, blocking_spawner: blocking::Spawner, seed_generator: RngSeedGenerator, config: Config, ) -> (MultiThread, runtime::Handle)46     pub(crate) fn new(
47         size: usize,
48         driver: Driver,
49         driver_handle: driver::Handle,
50         blocking_spawner: blocking::Spawner,
51         seed_generator: RngSeedGenerator,
52         config: Config,
53     ) -> (MultiThread, runtime::Handle) {
54         let handle = worker::create(
55             size,
56             driver,
57             driver_handle,
58             blocking_spawner,
59             seed_generator,
60             config,
61         );
62 
63         (MultiThread, handle)
64     }
65 
66     /// Blocks the current thread waiting for the future to complete.
67     ///
68     /// The future will execute on the current thread, but all spawned tasks
69     /// will be executed on the thread pool.
block_on<F>(&self, handle: &scheduler::Handle, future: F) -> F::Output where F: Future,70     pub(crate) fn block_on<F>(&self, handle: &scheduler::Handle, future: F) -> F::Output
71     where
72         F: Future,
73     {
74         crate::runtime::context::enter_runtime(handle, true, |blocking| {
75             blocking.block_on(future).expect("failed to park thread")
76         })
77     }
78 
shutdown(&mut self, handle: &scheduler::Handle)79     pub(crate) fn shutdown(&mut self, handle: &scheduler::Handle) {
80         match handle {
81             scheduler::Handle::MultiThreadAlt(handle) => handle.shutdown(),
82             _ => panic!("expected MultiThread scheduler"),
83         }
84     }
85 }
86 
87 impl fmt::Debug for MultiThread {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result88     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
89         fmt.debug_struct("MultiThread").finish()
90     }
91 }
92