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 | mod park; |
19 | pub(crate) use park::{Parker, Unparker}; |
20 | |
21 | pub(crate) mod queue; |
22 | |
23 | mod worker; |
24 | pub(crate) use worker::{Context, Launch, Shared}; |
25 | |
26 | cfg_taskdump! { |
27 | mod trace; |
28 | use trace::TraceStatus; |
29 | |
30 | pub(crate) use worker::Synced; |
31 | } |
32 | |
33 | cfg_not_taskdump! { |
34 | mod trace_mock; |
35 | use trace_mock::TraceStatus; |
36 | } |
37 | |
38 | pub(crate) use worker::block_in_place; |
39 | |
40 | use crate::loom::sync::Arc; |
41 | use crate::runtime::{ |
42 | blocking, |
43 | driver::{self, Driver}, |
44 | scheduler, Config, |
45 | }; |
46 | use crate::util::RngSeedGenerator; |
47 | |
48 | use std::fmt; |
49 | use std::future::Future; |
50 | |
51 | /// Work-stealing based thread pool for executing futures. |
52 | pub(crate) struct MultiThread; |
53 | |
54 | // ===== impl MultiThread ===== |
55 | |
56 | impl MultiThread { |
57 | pub(crate) fn new( |
58 | size: usize, |
59 | driver: Driver, |
60 | driver_handle: driver::Handle, |
61 | blocking_spawner: blocking::Spawner, |
62 | seed_generator: RngSeedGenerator, |
63 | config: Config, |
64 | ) -> (MultiThread, Arc<Handle>, Launch) { |
65 | let parker = Parker::new(driver); |
66 | let (handle, launch) = worker::create( |
67 | size, |
68 | parker, |
69 | driver_handle, |
70 | blocking_spawner, |
71 | seed_generator, |
72 | config, |
73 | ); |
74 | |
75 | (MultiThread, handle, launch) |
76 | } |
77 | |
78 | /// Blocks the current thread waiting for the future to complete. |
79 | /// |
80 | /// The future will execute on the current thread, but all spawned tasks |
81 | /// will be executed on the thread pool. |
82 | pub(crate) fn block_on<F>(&self, handle: &scheduler::Handle, future: F) -> F::Output |
83 | where |
84 | F: Future, |
85 | { |
86 | crate::runtime::context::enter_runtime(handle, true, |blocking| { |
87 | blocking.block_on(future).expect("failed to park thread" ) |
88 | }) |
89 | } |
90 | |
91 | pub(crate) fn shutdown(&mut self, handle: &scheduler::Handle) { |
92 | match handle { |
93 | scheduler::Handle::MultiThread(handle) => handle.shutdown(), |
94 | _ => panic!("expected MultiThread scheduler" ), |
95 | } |
96 | } |
97 | } |
98 | |
99 | impl fmt::Debug for MultiThread { |
100 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
101 | fmt.debug_struct(name:"MultiThread" ).finish() |
102 | } |
103 | } |
104 | |