|
|
@ -2,7 +2,7 @@ use std::cell::Cell;
|
|
|
|
use std::io;
|
|
|
|
use std::io;
|
|
|
|
use std::iter;
|
|
|
|
use std::iter;
|
|
|
|
use std::sync::atomic::{self, Ordering};
|
|
|
|
use std::sync::atomic::{self, Ordering};
|
|
|
|
use std::sync::Arc;
|
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
use std::thread;
|
|
|
|
use std::thread;
|
|
|
|
use std::time::Duration;
|
|
|
|
use std::time::Duration;
|
|
|
|
|
|
|
|
|
|
|
@ -22,6 +22,11 @@ thread_local! {
|
|
|
|
static YIELD_NOW: Cell<bool> = Cell::new(false);
|
|
|
|
static YIELD_NOW: Cell<bool> = Cell::new(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct Scheduler {
|
|
|
|
|
|
|
|
/// Set to `true` while a machine is polling the reactor.
|
|
|
|
|
|
|
|
polling: bool,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// An async runtime.
|
|
|
|
/// An async runtime.
|
|
|
|
pub struct Runtime {
|
|
|
|
pub struct Runtime {
|
|
|
|
/// The reactor.
|
|
|
|
/// The reactor.
|
|
|
@ -33,7 +38,11 @@ pub struct Runtime {
|
|
|
|
/// Handles to local queues for stealing work.
|
|
|
|
/// Handles to local queues for stealing work.
|
|
|
|
stealers: Vec<Stealer<Runnable>>,
|
|
|
|
stealers: Vec<Stealer<Runnable>>,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Machines to start
|
|
|
|
machines: Vec<Arc<Machine>>,
|
|
|
|
machines: Vec<Arc<Machine>>,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// The scheduler state.
|
|
|
|
|
|
|
|
sched: Mutex<Scheduler>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Runtime {
|
|
|
|
impl Runtime {
|
|
|
@ -57,6 +66,7 @@ impl Runtime {
|
|
|
|
injector: Injector::new(),
|
|
|
|
injector: Injector::new(),
|
|
|
|
stealers,
|
|
|
|
stealers,
|
|
|
|
machines,
|
|
|
|
machines,
|
|
|
|
|
|
|
|
sched: Mutex::new(Scheduler { polling: false }),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -116,9 +126,27 @@ impl Runtime {
|
|
|
|
/// This function might not poll the reactor at all so do not rely on it doing anything. Only
|
|
|
|
/// This function might not poll the reactor at all so do not rely on it doing anything. Only
|
|
|
|
/// use for optimization.
|
|
|
|
/// use for optimization.
|
|
|
|
fn quick_poll(&self) -> io::Result<bool> {
|
|
|
|
fn quick_poll(&self) -> io::Result<bool> {
|
|
|
|
|
|
|
|
if let Ok(sched) = self.sched.try_lock() {
|
|
|
|
|
|
|
|
if !sched.polling {
|
|
|
|
return self.reactor.poll(Some(Duration::from_secs(0)));
|
|
|
|
return self.reactor.poll(Some(Duration::from_secs(0)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(false)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn poll(&self) -> io::Result<bool> {
|
|
|
|
|
|
|
|
let mut sched = self.sched.lock().unwrap();
|
|
|
|
|
|
|
|
sched.polling = true;
|
|
|
|
|
|
|
|
drop(sched);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let result = self.reactor.poll(None);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut sched = self.sched.lock().unwrap();
|
|
|
|
|
|
|
|
sched.polling = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// A thread running a processor.
|
|
|
|
/// A thread running a processor.
|
|
|
|
struct Machine {
|
|
|
|
struct Machine {
|
|
|
@ -242,7 +270,7 @@ impl Machine {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rt.reactor.poll(None).unwrap();
|
|
|
|
rt.poll().unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
runs = 0;
|
|
|
|
runs = 0;
|
|
|
|
fails = 0;
|
|
|
|
fails = 0;
|
|
|
|