use std::io;
use io_uring::IoUring;
use crate::driver::{Driver, FixedBufGuard, ProvidedBuf};
use crate::sys::Cpu;
use dope_core::driver as caps;
pub fn new_driver(cfg: crate::DriverConfig) -> io::Result<Driver> {
tracing::info!("dope: io-uring driver");
if let Some(cpu) = cfg.cpu_id {
Cpu::pin(cpu)?;
}
let uring = open_uring(&cfg)?;
if !uring.params().is_feature_ext_arg() {
return Err(io::Error::new(
io::ErrorKind::Unsupported,
"dope: io_uring IORING_FEAT_EXT_ARG is required",
));
}
let ring = crate::driver::Ring::new(uring);
let hot_cap = (cfg.ring_entries as usize).saturating_mul(8).max(4096);
Driver::new(ring, cfg, hot_cap)
}
fn open_uring(cfg: &crate::DriverConfig) -> io::Result<IoUring> {
let mut builder = IoUring::builder();
builder.setup_single_issuer();
builder.setup_submit_all();
if cfg.defer_taskrun {
builder.setup_defer_taskrun();
}
builder.build(cfg.ring_entries)
}
impl caps::DriverLifecycle for Driver {
#[inline(always)]
fn drive(&mut self) -> io::Result<bool> {
Self::drive(self)
}
#[inline(always)]
fn has_pending(&mut self) -> bool {
Self::has_pending(self)
}
#[inline(always)]
fn park(&mut self) -> io::Result<()> {
Self::park(self)
}
#[inline(always)]
fn park_for(&mut self, duration: std::time::Duration) -> io::Result<()> {
Self::park_for(self, duration)
}
#[inline(always)]
fn submit_only(&mut self) -> io::Result<()> {
Self::submit_only(self)
}
}
impl caps::FixedBuffers for Driver {
type Guard = FixedBufGuard;
#[inline(always)]
fn fixed_guard(&mut self) -> Option<Self::Guard> {
self.resources.fixed_guard()
}
#[inline(always)]
fn register_fixed(&mut self, fd: crate::Fd) -> io::Result<Option<u32>> {
self.resources.register_fixed(&self.ring, fd)
}
#[inline(always)]
fn unregister_fixed(&mut self, idx: u32) {
self.resources.unregister_fixed(&self.ring, idx);
}
}
impl caps::ProvidedBufRing for Driver {
type Provided = ProvidedBuf;
#[inline(always)]
fn provided_group(&mut self) -> Option<(u16, u32)> {
Some(self.provided.group())
}
#[inline(always)]
fn provided(&mut self, bid: u16, len: usize) -> Option<Self::Provided> {
Some(self.provided.make_buf(bid, len))
}
}