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 { new( size: usize, driver: Driver, driver_handle: driver::Handle, blocking_spawner: blocking::Spawner, seed_generator: RngSeedGenerator, config: Config, ) -> (MultiThread, Arc<Handle>, Launch)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. block_on<F>(&self, handle: &scheduler::Handle, future: F) -> F::Output where F: Future,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 shutdown(&mut self, handle: &scheduler::Handle)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 { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result100 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 101 fmt.debug_struct("MultiThread").finish() 102 } 103 } 104