aboutsummaryrefslogtreecommitdiff
path: root/src/rxqueue.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/rxqueue.rs')
-rw-r--r--src/rxqueue.rs157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/rxqueue.rs b/src/rxqueue.rs
new file mode 100644
index 0000000..4b76727
--- /dev/null
+++ b/src/rxqueue.rs
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause
+
+use crate::rxops::RxOps;
+
+#[derive(Debug, Eq, PartialEq)]
+pub(crate) struct RxQueue {
+ /// Bitmap of rx operations.
+ queue: u8,
+}
+
+impl RxQueue {
+ /// New instance of RxQueue.
+ pub fn new() -> Self {
+ RxQueue { queue: 0_u8 }
+ }
+
+ /// Enqueue a new rx operation into the queue.
+ pub fn enqueue(&mut self, op: RxOps) {
+ self.queue |= op.bitmask();
+ }
+
+ /// Dequeue an rx operation from the queue.
+ pub fn dequeue(&mut self) -> Option<RxOps> {
+ match self.peek() {
+ Some(req) => {
+ self.queue &= !req.bitmask();
+ Some(req)
+ }
+ None => None,
+ }
+ }
+
+ /// Peek into the queue to check if it contains an rx operation.
+ pub fn peek(&self) -> Option<RxOps> {
+ if self.contains(RxOps::Request.bitmask()) {
+ return Some(RxOps::Request);
+ }
+ if self.contains(RxOps::Rw.bitmask()) {
+ return Some(RxOps::Rw);
+ }
+ if self.contains(RxOps::Response.bitmask()) {
+ return Some(RxOps::Response);
+ }
+ if self.contains(RxOps::CreditUpdate.bitmask()) {
+ return Some(RxOps::CreditUpdate);
+ }
+ if self.contains(RxOps::Reset.bitmask()) {
+ Some(RxOps::Reset)
+ } else {
+ None
+ }
+ }
+
+ /// Check if the queue contains a particular rx operation.
+ pub fn contains(&self, op: u8) -> bool {
+ (self.queue & op) != 0
+ }
+
+ /// Check if there are any pending rx operations in the queue.
+ pub fn pending_rx(&self) -> bool {
+ self.queue != 0
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_contains() {
+ let mut rxqueue = RxQueue::new();
+ rxqueue.queue = 31;
+
+ assert!(rxqueue.contains(RxOps::Request.bitmask()));
+ assert!(rxqueue.contains(RxOps::Rw.bitmask()));
+ assert!(rxqueue.contains(RxOps::Response.bitmask()));
+ assert!(rxqueue.contains(RxOps::CreditUpdate.bitmask()));
+ assert!(rxqueue.contains(RxOps::Reset.bitmask()));
+
+ rxqueue.queue = 0;
+ assert!(!rxqueue.contains(RxOps::Request.bitmask()));
+ assert!(!rxqueue.contains(RxOps::Rw.bitmask()));
+ assert!(!rxqueue.contains(RxOps::Response.bitmask()));
+ assert!(!rxqueue.contains(RxOps::CreditUpdate.bitmask()));
+ assert!(!rxqueue.contains(RxOps::Reset.bitmask()));
+ }
+
+ #[test]
+ fn test_enqueue() {
+ let mut rxqueue = RxQueue::new();
+
+ rxqueue.enqueue(RxOps::Request);
+ assert!(rxqueue.contains(RxOps::Request.bitmask()));
+
+ rxqueue.enqueue(RxOps::Rw);
+ assert!(rxqueue.contains(RxOps::Rw.bitmask()));
+
+ rxqueue.enqueue(RxOps::Response);
+ assert!(rxqueue.contains(RxOps::Response.bitmask()));
+
+ rxqueue.enqueue(RxOps::CreditUpdate);
+ assert!(rxqueue.contains(RxOps::CreditUpdate.bitmask()));
+
+ rxqueue.enqueue(RxOps::Reset);
+ assert!(rxqueue.contains(RxOps::Reset.bitmask()));
+ }
+
+ #[test]
+ fn test_peek() {
+ let mut rxqueue = RxQueue::new();
+
+ rxqueue.queue = 31;
+ assert_eq!(rxqueue.peek(), Some(RxOps::Request));
+
+ rxqueue.queue = 30;
+ assert_eq!(rxqueue.peek(), Some(RxOps::Rw));
+
+ rxqueue.queue = 28;
+ assert_eq!(rxqueue.peek(), Some(RxOps::Response));
+
+ rxqueue.queue = 24;
+ assert_eq!(rxqueue.peek(), Some(RxOps::CreditUpdate));
+
+ rxqueue.queue = 16;
+ assert_eq!(rxqueue.peek(), Some(RxOps::Reset));
+ }
+
+ #[test]
+ fn test_dequeue() {
+ let mut rxqueue = RxQueue::new();
+ rxqueue.queue = 31;
+
+ assert_eq!(rxqueue.dequeue(), Some(RxOps::Request));
+ assert!(!rxqueue.contains(RxOps::Request.bitmask()));
+
+ assert_eq!(rxqueue.dequeue(), Some(RxOps::Rw));
+ assert!(!rxqueue.contains(RxOps::Rw.bitmask()));
+
+ assert_eq!(rxqueue.dequeue(), Some(RxOps::Response));
+ assert!(!rxqueue.contains(RxOps::Response.bitmask()));
+
+ assert_eq!(rxqueue.dequeue(), Some(RxOps::CreditUpdate));
+ assert!(!rxqueue.contains(RxOps::CreditUpdate.bitmask()));
+
+ assert_eq!(rxqueue.dequeue(), Some(RxOps::Reset));
+ assert!(!rxqueue.contains(RxOps::Reset.bitmask()));
+ }
+
+ #[test]
+ fn test_pending_rx() {
+ let mut rxqueue = RxQueue::new();
+ assert!(!rxqueue.pending_rx());
+
+ rxqueue.queue = 1;
+ assert!(rxqueue.pending_rx());
+ }
+}