• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / alioth / 17114644709

21 Aug 2025 01:34AM UTC coverage: 10.411%. Remained the same
17114644709

Pull #273

github

web-flow
Merge 13942e21e into 7925c9625
Pull Request #273: feat: virtio packed queue

26 of 57 new or added lines in 9 files covered. (45.61%)

2 existing lines in 2 files now uncovered.

714 of 6858 relevant lines covered (10.41%)

16.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.18
/alioth/src/virtio/queue/queue.rs
1
// Copyright 2024 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
pub mod split;
16
#[cfg(test)]
17
#[path = "queue_test.rs"]
18
mod tests;
19

20
use std::io::{ErrorKind, IoSlice, IoSliceMut, Read, Write};
21
use std::sync::atomic::{AtomicBool, AtomicU16, AtomicU64, Ordering, fence};
22

23
use crate::virtio::{IrqSender, Result};
24

25
pub const QUEUE_SIZE_MAX: u16 = 256;
26

27
#[derive(Debug, Default)]
28
pub struct QueueReg {
29
    pub size: AtomicU16,
30
    pub desc: AtomicU64,
31
    pub driver: AtomicU64,
32
    pub device: AtomicU64,
33
    pub enabled: AtomicBool,
34
}
35

36
#[derive(Debug)]
37
pub struct DescChain<'m> {
38
    pub id: u16,
39
    pub readable: Vec<IoSlice<'m>>,
40
    pub writable: Vec<IoSliceMut<'m>>,
41
}
42

43
pub trait VirtQueue<'m> {
44
    fn reg(&self) -> &QueueReg;
45
    fn size(&self) -> u16;
46
    fn next_desc_chain(&self) -> Option<Result<DescChain<'m>>>;
47
    fn avail_index(&self) -> u16;
48
    fn get_desc_chain(&self, index: u16) -> Result<DescChain<'m>>;
49
    fn has_next_desc(&self) -> bool;
50
    fn push_used(&mut self, desc: DescChain, len: usize) -> u16;
51
    fn enable_notification(&self, enabled: bool);
52
    fn interrupt_enabled(&self) -> bool;
53

54
    fn handle_desc(
34✔
55
        &mut self,
56
        q_index: u16,
57
        irq_sender: &impl IrqSender,
58
        mut op: impl FnMut(&mut DescChain) -> Result<Option<usize>>,
59
    ) -> Result<()> {
60
        let mut send_irq = false;
66✔
61
        let mut ret = Ok(());
66✔
62
        'out: loop {
×
63
            if !self.has_next_desc() {
48✔
64
                break;
20✔
65
            }
66
            self.enable_notification(false);
50✔
67
            while let Some(chain) = self.next_desc_chain() {
64✔
68
                let mut chain = chain?;
28✔
NEW
69
                match op(&mut chain) {
6✔
70
                    Err(e) => {
6✔
71
                        ret = Err(e);
10✔
72
                        self.enable_notification(true);
10✔
73
                        break 'out;
4✔
74
                    }
75
                    Ok(None) => break 'out,
8✔
76
                    Ok(Some(len)) => {
14✔
NEW
77
                        self.push_used(chain, len);
2✔
78
                        send_irq = send_irq || self.interrupt_enabled();
14✔
79
                    }
80
                }
81
            }
82
            self.enable_notification(true);
14✔
83
            fence(Ordering::SeqCst);
2✔
84
        }
85
        if send_irq {
34✔
86
            fence(Ordering::SeqCst);
26✔
87
            irq_sender.queue_irq(q_index)
38✔
88
        }
89
        ret
2✔
90
    }
91
}
92

93
pub fn copy_from_reader(
20✔
94
    mut reader: impl Read,
95
) -> impl FnMut(&mut DescChain) -> Result<Option<usize>> {
96
    move |chain| {
16✔
97
        let ret = reader.read_vectored(&mut chain.writable);
58✔
98
        match ret {
8✔
NEW
99
            Ok(0) => {
×
100
                let size: usize = chain.writable.iter().map(|s| s.len()).sum();
12✔
101
                if size == 0 { Ok(Some(0)) } else { Ok(None) }
5✔
102
            }
103
            Ok(len) => Ok(Some(len)),
14✔
104
            Err(e) if e.kind() == ErrorKind::WouldBlock => Ok(None),
13✔
105
            Err(e) => Err(e)?,
6✔
106
        }
107
    }
108
}
109

110
pub fn copy_to_writer(
20✔
111
    mut writer: impl Write,
112
) -> impl FnMut(&mut DescChain) -> Result<Option<usize>> {
113
    move |chain| {
16✔
114
        let ret = writer.write_vectored(&chain.readable);
58✔
115
        match ret {
8✔
NEW
116
            Ok(0) => {
×
117
                let size: usize = chain.readable.iter().map(|s| s.len()).sum();
12✔
118
                if size == 0 { Ok(Some(0)) } else { Ok(None) }
5✔
119
            }
120
            Ok(_) => Ok(Some(0)),
8✔
121
            Err(e) if e.kind() == ErrorKind::WouldBlock => Ok(None),
13✔
122
            Err(e) => Err(e)?,
6✔
123
        }
124
    }
125
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc