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