use io_uring_owner::{Owner, TakeError};
use std::marker::PhantomPinned;
use std::pin::Pin;
#[derive(Clone, Debug)]
pub struct BuffersRec {
pub(crate) owner: Owner,
all_bufs: Vec<u8>,
len_per_buf: i32,
num_bufs: u16,
_pin: PhantomPinned,
}
impl BuffersRec {
pub(crate) unsafe fn take_for_filling(&mut self) -> Pin<&mut Vec<u8>> {
Pin::new(&mut self.all_bufs)
}
pub(crate) fn force_owner_kernel(&mut self) {
self.owner = Owner::Kernel;
}
pub fn owner(&self) -> Owner {
self.owner.clone()
}
pub fn len_per_buf(&self) -> i32 {
self.len_per_buf
}
pub fn num_bufs(&self) -> u16 {
self.num_bufs
}
pub unsafe fn all_bufs(&self) -> &Vec<u8> {
&self.all_bufs
}
}
#[inline]
pub(crate) fn construct_buffer(owner: Owner, len_per_buf: i32, num_bufs: u16) -> BuffersRec {
assert!(len_per_buf > 0);
assert!(num_bufs > 0);
let total_siz: usize = len_per_buf as usize * num_bufs as usize;
let v: Vec<u8> = vec![0; total_siz];
BuffersRec {
owner,
len_per_buf,
num_bufs,
all_bufs: v,
_pin: PhantomPinned,
}
}
#[derive(Clone, Debug)]
pub struct ProvideBuffersRec {
slab_idx: Option<usize>,
buf: *mut u8,
len_per_buf: i32,
num_bufs: u16,
bgid: u16,
bid: u16,
}
impl ProvideBuffersRec {
pub fn slab_idx(&self) -> Option<usize> {
self.slab_idx
}
}
#[derive(Clone, Debug)]
pub(crate) struct TakenMutableBuffer {
pub(crate) buf_idx: usize,
pub(crate) buf_mut_u8: *mut u8,
pub(crate) buf_size: u32,
}
#[inline]
pub(crate) fn take_one_mutable_buffer_raw(
buf_idx: usize,
buf_rec: &mut BuffersRec,
) -> Result<TakenMutableBuffer, TakeError> {
if buf_rec.num_bufs() != 1 {
return Err(TakeError::OnlyOneTakeable);
}
buf_rec.owner.take()?;
Ok(TakenMutableBuffer {
buf_idx,
buf_size: buf_rec.len_per_buf as u32,
buf_mut_u8: &raw mut buf_rec.all_bufs as *mut u8,
})
}
#[derive(Clone, Debug)]
pub(crate) struct TakenImmutableBuffer {
pub(crate) buf_idx: usize,
pub(crate) buf_const_u8: *const u8,
pub(crate) buf_size: u32,
pub(crate) buf_kernel_index: u16,
}
#[inline]
pub(crate) fn take_one_immutable_buffer_raw(
buf_idx: usize,
buf_kernel_index: u16,
buf_rec: &mut BuffersRec,
) -> Result<TakenImmutableBuffer, TakeError> {
if buf_rec.num_bufs() != 1 {
return Err(TakeError::OnlyOneTakeable);
}
buf_rec.owner.take()?;
Ok(TakenImmutableBuffer {
buf_idx,
buf_size: buf_rec.len_per_buf as u32,
buf_const_u8: buf_rec.all_bufs.as_ptr(),
buf_kernel_index,
})
}
#[inline]
pub(crate) fn provide_buffer_rec(
bgid: u16,
bid: u16,
buf: &mut BuffersRec,
slab_idx: Option<usize>,
) -> ProvideBuffersRec {
ProvideBuffersRec {
slab_idx,
buf: buf.all_bufs.as_mut_ptr(),
len_per_buf: buf.len_per_buf,
num_bufs: buf.num_bufs,
bgid,
bid,
}
}
#[inline]
pub(crate) fn entry(rec: &ProvideBuffersRec) -> io_uring::squeue::Entry {
io_uring::opcode::ProvideBuffers::new(
rec.buf,
rec.len_per_buf, rec.num_bufs, rec.bgid, rec.bid, )
.build()
}