cpu/io/
pollq.rs

1use std::fmt::Debug;
2use std::time::Duration;
3
4use tracing::{Level, event};
5
6use base::collections::pq::KeyedReversePriorityQueue;
7use base::prelude::*;
8
9#[derive(Debug)]
10pub(crate) struct PollQueue {
11    items: KeyedReversePriorityQueue<SequenceNumber, Duration>,
12}
13
14#[derive(Debug)]
15pub(crate) enum PollQueueUpdateFailure {
16    // UnknownSequence rises when we try to update the poll time for a
17    // sequence with no attached hardware.  This is a normal thing for
18    // software-only sequences.
19    UnknownSequence(SequenceNumber),
20}
21
22impl PollQueue {
23    pub(crate) fn new() -> PollQueue {
24        PollQueue {
25            items: KeyedReversePriorityQueue::new(),
26        }
27    }
28
29    pub(crate) fn peek(&self) -> Option<(&SequenceNumber, &Duration)> {
30        self.items.peek()
31    }
32
33    pub(crate) fn pop(&mut self) -> Option<(SequenceNumber, Duration)> {
34        self.items.pop()
35    }
36
37    pub(crate) fn push(&mut self, key: SequenceNumber, priority: Duration) -> Option<Duration> {
38        let old_pri = self.items.push(key, priority);
39        if let Some(prev) = old_pri
40            && prev < priority
41        {
42            event!(
43                Level::WARN,
44                "unit {:o} poll time pushed back from {:?} to {:?}",
45                key,
46                prev,
47                priority
48            );
49        }
50        old_pri
51    }
52
53    pub(crate) fn update(
54        &mut self,
55        key: SequenceNumber,
56        priority: Duration,
57    ) -> Result<Duration, PollQueueUpdateFailure> {
58        match self.items.set_priority(&key, priority) {
59            Ok(old_pri) => {
60                if old_pri < priority {
61                    event!(
62                        Level::WARN,
63                        "unit {:o} poll time pushed back from {:?} to {:?}",
64                        key,
65                        old_pri,
66                        priority
67                    );
68                }
69                Ok(old_pri)
70            }
71            Err(_) => Err(PollQueueUpdateFailure::UnknownSequence(key)),
72        }
73    }
74
75    #[cfg(test)]
76    pub(crate) fn len(&self) -> usize {
77        self.items.len()
78    }
79
80    #[cfg(test)]
81    pub(crate) fn is_empty(&self) -> bool {
82        self.items.is_empty()
83    }
84}
85
86#[test]
87fn test_pollqueue_empty() {
88    let mut q = PollQueue::new();
89    assert!(q.is_empty());
90    assert_eq!(0, q.len());
91    assert_eq!(q.peek(), None);
92    assert_eq!(q.pop(), None);
93}
94
95#[test]
96fn test_pollqueue_repeat_push() {
97    let mut q = PollQueue::new();
98    assert_eq!(
99        q.push(SequenceNumber::ZERO, Duration::from_micros(200)),
100        None
101    );
102    assert_eq!(
103        q.push(SequenceNumber::ZERO, Duration::from_micros(400)),
104        Some(Duration::from_micros(200))
105    );
106    assert_eq!(
107        q.push(SequenceNumber::ZERO, Duration::from_micros(300)),
108        Some(Duration::from_micros(400))
109    );
110    assert_eq!(
111        q.pop(),
112        Some((SequenceNumber::ZERO, Duration::from_micros(300)))
113    );
114    assert!(q.is_empty());
115}