diff --git a/tokio/src/runtime/scheduler/multi_thread/counters.rs b/tokio/src/runtime/scheduler/multi_thread/counters.rs index 8bd550f9f..2284b5ffc 100644 --- a/tokio/src/runtime/scheduler/multi_thread/counters.rs +++ b/tokio/src/runtime/scheduler/multi_thread/counters.rs @@ -5,27 +5,42 @@ mod imp { static NUM_MAINTENANCE: AtomicUsize = AtomicUsize::new(0); static NUM_NOTIFY_LOCAL: AtomicUsize = AtomicUsize::new(0); + static NUM_NOTIFY_REMOTE: AtomicUsize = AtomicUsize::new(0); static NUM_UNPARKS_LOCAL: AtomicUsize = AtomicUsize::new(0); static NUM_LIFO_SCHEDULES: AtomicUsize = AtomicUsize::new(0); static NUM_LIFO_CAPPED: AtomicUsize = AtomicUsize::new(0); static NUM_STEALS: AtomicUsize = AtomicUsize::new(0); + static NUM_OVERFLOW: AtomicUsize = AtomicUsize::new(0); + static NUM_PARK: AtomicUsize = AtomicUsize::new(0); + static NUM_POLLS: AtomicUsize = AtomicUsize::new(0); + static NUM_LIFO_POLLS: AtomicUsize = AtomicUsize::new(0); impl Drop for super::Counters { fn drop(&mut self) { let notifies_local = NUM_NOTIFY_LOCAL.load(Relaxed); + let notifies_remote = NUM_NOTIFY_REMOTE.load(Relaxed); let unparks_local = NUM_UNPARKS_LOCAL.load(Relaxed); let maintenance = NUM_MAINTENANCE.load(Relaxed); let lifo_scheds = NUM_LIFO_SCHEDULES.load(Relaxed); let lifo_capped = NUM_LIFO_CAPPED.load(Relaxed); let num_steals = NUM_STEALS.load(Relaxed); + let num_overflow = NUM_OVERFLOW.load(Relaxed); + let num_park = NUM_PARK.load(Relaxed); + let num_polls = NUM_POLLS.load(Relaxed); + let num_lifo_polls = NUM_LIFO_POLLS.load(Relaxed); println!("---"); - println!("notifies (local): {}", notifies_local); - println!(" unparks (local): {}", unparks_local); - println!(" maintenance: {}", maintenance); - println!(" LIFO schedules: {}", lifo_scheds); - println!(" LIFO capped: {}", lifo_capped); - println!(" steals: {}", num_steals); + println!("notifies (remote): {}", notifies_remote); + println!(" notifies (local): {}", notifies_local); + println!(" unparks (local): {}", unparks_local); + println!(" maintenance: {}", maintenance); + println!(" LIFO schedules: {}", lifo_scheds); + println!(" LIFO capped: {}", lifo_capped); + println!(" steals: {}", num_steals); + println!(" queue overflows: {}", num_overflow); + println!(" parks: {}", num_park); + println!(" polls: {}", num_polls); + println!(" polls (LIFO): {}", num_lifo_polls); } } @@ -33,6 +48,10 @@ mod imp { NUM_NOTIFY_LOCAL.fetch_add(1, Relaxed); } + pub(crate) fn inc_num_notify_remote() { + NUM_NOTIFY_REMOTE.fetch_add(1, Relaxed); + } + pub(crate) fn inc_num_unparks_local() { NUM_UNPARKS_LOCAL.fetch_add(1, Relaxed); } @@ -52,16 +71,37 @@ mod imp { pub(crate) fn inc_num_steals() { NUM_STEALS.fetch_add(1, Relaxed); } + + pub(crate) fn inc_num_overflows() { + NUM_OVERFLOW.fetch_add(1, Relaxed); + } + + pub(crate) fn inc_num_parks() { + NUM_PARK.fetch_add(1, Relaxed); + } + + pub(crate) fn inc_num_polls() { + NUM_POLLS.fetch_add(1, Relaxed); + } + + pub(crate) fn inc_num_lifo_polls() { + NUM_LIFO_POLLS.fetch_add(1, Relaxed); + } } #[cfg(not(tokio_internal_mt_counters))] mod imp { pub(crate) fn inc_num_inc_notify_local() {} + pub(crate) fn inc_num_notify_remote() {} pub(crate) fn inc_num_unparks_local() {} pub(crate) fn inc_num_maintenance() {} pub(crate) fn inc_lifo_schedules() {} pub(crate) fn inc_lifo_capped() {} pub(crate) fn inc_num_steals() {} + pub(crate) fn inc_num_overflows() {} + pub(crate) fn inc_num_parks() {} + pub(crate) fn inc_num_polls() {} + pub(crate) fn inc_num_lifo_polls() {} } #[derive(Debug)] diff --git a/tokio/src/runtime/scheduler/multi_thread/queue.rs b/tokio/src/runtime/scheduler/multi_thread/queue.rs index 100a63361..6dd9096f0 100644 --- a/tokio/src/runtime/scheduler/multi_thread/queue.rs +++ b/tokio/src/runtime/scheduler/multi_thread/queue.rs @@ -204,11 +204,13 @@ impl Local { // There is capacity for the task break tail; } else if steal != real { + super::counters::inc_num_overflows(); // Concurrently stealing, this will free up capacity, so only // push the task onto the inject queue overflow.push(task); return; } else { + super::counters::inc_num_overflows(); // Push the current task and half of the queue into the // inject queue. match self.push_overflow(task, real, tail, overflow, stats) { diff --git a/tokio/src/runtime/scheduler/multi_thread/worker.rs b/tokio/src/runtime/scheduler/multi_thread/worker.rs index 2007c16da..c9efa663b 100644 --- a/tokio/src/runtime/scheduler/multi_thread/worker.rs +++ b/tokio/src/runtime/scheduler/multi_thread/worker.rs @@ -696,6 +696,7 @@ impl Worker { if !cx.defer.borrow().is_empty() { core = n!(self.park_yield(cx, core)); } else { + super::counters::inc_num_parks(); core = n!(self.park(cx, core)); } } @@ -789,7 +790,8 @@ impl Worker { .take_local() .or_else(|| core.run_queue.pop()) */ - self.next_lifo_task(cx, core).or_else(|| core.run_queue.pop()) + self.next_lifo_task(cx, core) + .or_else(|| core.run_queue.pop()) } fn next_lifo_task(&self, cx: &Context, core: &mut Core) -> Option { @@ -896,6 +898,7 @@ impl Worker { // Run the task coop::budget(|| { + super::counters::inc_num_polls(); task.run(); let mut lifo_polls = 0; @@ -956,6 +959,7 @@ impl Worker { // Run the LIFO task, then loop *cx.core.borrow_mut() = Some(core); let task = cx.shared().owned.assert_owner(task); + super::counters::inc_num_lifo_polls(); task.run(); } }) @@ -1383,6 +1387,7 @@ impl Shared { } fn schedule_remote(&self, task: Notified) { + super::counters::inc_num_notify_remote(); self.scheduler_metrics.inc_remote_schedule_count(); let mut synced = self.synced.lock();