try_tick() method for st swactor runtimes
This commit is contained in:
parent
e8a44c3666
commit
17491c5247
2 changed files with 44 additions and 17 deletions
|
|
@ -438,18 +438,42 @@ impl Runtime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return whether the single-threaded runtime currently has schedulable work.
|
||||||
|
///
|
||||||
|
/// Panics if called on a multi-threaded runtime — use `run()` instead.
|
||||||
|
pub fn has_work(&self) -> bool {
|
||||||
|
assert!(
|
||||||
|
self.config.num_threads < 2,
|
||||||
|
"has_work() is only valid for single-threaded runtimes; use run() for multi-threaded"
|
||||||
|
);
|
||||||
|
|
||||||
|
self.tick_workers.borrow().iter().any(Worker::has_work)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Try to drive one tick of the single-threaded runtime.
|
||||||
|
///
|
||||||
|
/// Returns `false` if no worker performed work.
|
||||||
|
/// Returns `true` if at least one worker performed work.
|
||||||
|
///
|
||||||
|
/// Panics if called on a multi-threaded runtime — use `run()` instead.
|
||||||
|
pub fn try_tick(&self) -> bool {
|
||||||
|
assert!(
|
||||||
|
self.config.num_threads < 2,
|
||||||
|
"try_tick() is only valid for single-threaded runtimes; use run() for multi-threaded"
|
||||||
|
);
|
||||||
|
|
||||||
|
let tc = self.make_tick_context();
|
||||||
|
self.tick_workers
|
||||||
|
.borrow_mut()
|
||||||
|
.iter_mut()
|
||||||
|
.fold(false, |did_work, worker| worker.tick_once(&tc) || did_work)
|
||||||
|
}
|
||||||
|
|
||||||
/// Drive one tick of the single-threaded worker.
|
/// Drive one tick of the single-threaded worker.
|
||||||
///
|
///
|
||||||
/// Panics if called on a multi-threaded runtime — use `run()` instead.
|
/// Panics if called on a multi-threaded runtime — use `run()` instead.
|
||||||
pub fn tick(&self) {
|
pub fn tick(&self) {
|
||||||
assert!(
|
let _ = self.try_tick();
|
||||||
self.config.num_threads < 2,
|
|
||||||
"tick() is only valid for single-threaded runtimes; use run() for multi-threaded"
|
|
||||||
);
|
|
||||||
let tc = self.make_tick_context();
|
|
||||||
for worker in self.tick_workers.borrow_mut().iter_mut() {
|
|
||||||
worker.tick_once(&tc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawn worker threads and start processing, returning a handle
|
/// Spawn worker threads and start processing, returning a handle
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,17 @@ impl Worker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn has_work(&self) -> bool {
|
||||||
|
self.has_backlog
|
||||||
|
|| !self.spawn_rx.is_empty()
|
||||||
|
|| !self.transfer_rx.is_empty()
|
||||||
|
|| !self.admin_rx.is_empty()
|
||||||
|
|| self
|
||||||
|
.worker_ext
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |e| e.has_pending_work())
|
||||||
|
}
|
||||||
|
|
||||||
/// Run one iteration of the worker loop. Returns `true` if any work was done.
|
/// Run one iteration of the worker loop. Returns `true` if any work was done.
|
||||||
/// Drain the spawn queue, inserting new actors into the pool.
|
/// Drain the spawn queue, inserting new actors into the pool.
|
||||||
/// Used in phases 1 and 4 of tick_once.
|
/// Used in phases 1 and 4 of tick_once.
|
||||||
|
|
@ -283,15 +294,7 @@ impl Worker {
|
||||||
|
|
||||||
// Fast idle path: skip the entire tick when nothing could have changed.
|
// Fast idle path: skip the entire tick when nothing could have changed.
|
||||||
// Cost: ~3 atomic loads, zero syscalls, zero actor iteration.
|
// Cost: ~3 atomic loads, zero syscalls, zero actor iteration.
|
||||||
if !self.has_backlog
|
if !self.has_work() {
|
||||||
&& self.spawn_rx.is_empty()
|
|
||||||
&& self.transfer_rx.is_empty()
|
|
||||||
&& self.admin_rx.is_empty()
|
|
||||||
&& !self
|
|
||||||
.worker_ext
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |e| e.has_pending_work())
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue