vhost-device/vhost-device-vsock/src/rxqueue.rs
Manos Pitsidianakis a1e013286f Move all crates to workspace root
Having all the workspace crates under the crates/ directory is
unnecessary. Rust documentation itself recommends all crates to be in
the root directory:

https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html#creating-the-second-package-in-the-workspace

I paste the text content here, in case the online page ever changes or
becomes unavailable:

    ## Creating the Second Package in the Workspace

    Next, let’s create another member package in the workspace and call it add_one. Change the top-level Cargo.toml to specify the add_one path in the members list:

    Filename: Cargo.toml

    [workspace]

    members = [
        "adder",
        "add_one",
    ]

    Then generate a new library crate named add_one:

    $ cargo new add_one --lib
         Created library `add_one` package

    Your add directory should now have these directories and files:

    ├── Cargo.lock
    ├── Cargo.toml
    ├── add_one
    │   ├── Cargo.toml
    │   └── src
    │       └── lib.rs
    ├── adder
    │   ├── Cargo.toml
    │   └── src
    │       └── main.rs
    └── target

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
2023-10-16 12:03:57 +05:30

158 lines
4.4 KiB
Rust

// 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());
}
}