1 use crate::loom::sync::atomic::Ordering::Relaxed; 2 use crate::loom::sync::atomic::{AtomicU64, AtomicUsize}; 3 use crate::runtime::metrics::Histogram; 4 use crate::runtime::Config; 5 6 /// Retrieve runtime worker metrics. 7 /// 8 /// **Note**: This is an [unstable API][unstable]. The public API of this type 9 /// may break in 1.x releases. See [the documentation on unstable 10 /// features][unstable] for details. 11 /// 12 /// [unstable]: crate#unstable-features 13 #[derive(Debug)] 14 #[repr(align(128))] 15 pub(crate) struct WorkerMetrics { 16 /// Number of times the worker parked. 17 pub(crate) park_count: AtomicU64, 18 19 /// Number of times the worker woke then parked again without doing work. 20 pub(crate) noop_count: AtomicU64, 21 22 /// Number of tasks the worker stole. 23 pub(crate) steal_count: AtomicU64, 24 25 /// Number of times the worker stole 26 pub(crate) steal_operations: AtomicU64, 27 28 /// Number of tasks the worker polled. 29 pub(crate) poll_count: AtomicU64, 30 31 /// EWMA task poll time, in nanoseconds. 32 pub(crate) mean_poll_time: AtomicU64, 33 34 /// Amount of time the worker spent doing work vs. parking. 35 pub(crate) busy_duration_total: AtomicU64, 36 37 /// Number of tasks scheduled for execution on the worker's local queue. 38 pub(crate) local_schedule_count: AtomicU64, 39 40 /// Number of tasks moved from the local queue to the global queue to free space. 41 pub(crate) overflow_count: AtomicU64, 42 43 /// Number of tasks currently in the local queue. Used only by the 44 /// current-thread scheduler. 45 pub(crate) queue_depth: AtomicUsize, 46 47 /// If `Some`, tracks the the number of polls by duration range. 48 pub(super) poll_count_histogram: Option<Histogram>, 49 } 50 51 impl WorkerMetrics { from_config(config: &Config) -> WorkerMetrics52 pub(crate) fn from_config(config: &Config) -> WorkerMetrics { 53 let mut worker_metrics = WorkerMetrics::new(); 54 worker_metrics.poll_count_histogram = config 55 .metrics_poll_count_histogram 56 .as_ref() 57 .map(|histogram_builder| histogram_builder.build()); 58 worker_metrics 59 } 60 new() -> WorkerMetrics61 pub(crate) fn new() -> WorkerMetrics { 62 WorkerMetrics { 63 park_count: AtomicU64::new(0), 64 noop_count: AtomicU64::new(0), 65 steal_count: AtomicU64::new(0), 66 steal_operations: AtomicU64::new(0), 67 poll_count: AtomicU64::new(0), 68 mean_poll_time: AtomicU64::new(0), 69 overflow_count: AtomicU64::new(0), 70 busy_duration_total: AtomicU64::new(0), 71 local_schedule_count: AtomicU64::new(0), 72 queue_depth: AtomicUsize::new(0), 73 poll_count_histogram: None, 74 } 75 } 76 queue_depth(&self) -> usize77 pub(crate) fn queue_depth(&self) -> usize { 78 self.queue_depth.load(Relaxed) 79 } 80 set_queue_depth(&self, len: usize)81 pub(crate) fn set_queue_depth(&self, len: usize) { 82 self.queue_depth.store(len, Relaxed); 83 } 84 } 85