use crate::ffi;
const DEFAULT_NUM_MBUFS: u32 = 8192;
const MBUF_CACHE_SIZE: u32 = 256;
pub struct Mempool {
raw: *mut ffi::rte_mempool,
}
unsafe impl Send for Mempool {}
impl Mempool {
pub fn create(name: &str, socket_id: i32) -> Result<Self, MempoolError> {
Self::create_with_size(name, DEFAULT_NUM_MBUFS, socket_id)
}
pub fn create_with_size(
name: &str,
num_mbufs: u32,
socket_id: i32,
) -> Result<Self, MempoolError> {
let buf_size = unsafe { ffi::dpdk_mbuf_default_buf_size() };
Self::create_full(name, num_mbufs, buf_size, socket_id)
}
pub fn create_for_mtu(
name: &str,
num_mbufs: u32,
mtu: u16,
socket_id: i32,
) -> Result<Self, MempoolError> {
let buf_size = mtu + 14 + 4 + 128;
Self::create_full(name, num_mbufs, buf_size, socket_id)
}
fn create_full(
name: &str,
num_mbufs: u32,
buf_size: u16,
socket_id: i32,
) -> Result<Self, MempoolError> {
let c_name = std::ffi::CString::new(name).map_err(|_| MempoolError::InvalidName)?;
let raw = unsafe {
ffi::rte_pktmbuf_pool_create(
c_name.as_ptr(),
num_mbufs,
MBUF_CACHE_SIZE,
0, buf_size,
socket_id,
)
};
if raw.is_null() {
return Err(MempoolError::CreateFailed);
}
tracing::info!(name, num_mbufs, socket_id, "created DPDK mempool");
Ok(Mempool { raw })
}
pub fn as_raw(&self) -> *mut ffi::rte_mempool {
self.raw
}
}
impl Drop for Mempool {
fn drop(&mut self) {
unsafe {
ffi::dpdk_mempool_free(self.raw);
}
}
}
#[derive(Debug)]
pub enum MempoolError {
InvalidName,
CreateFailed,
}
impl std::fmt::Display for MempoolError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MempoolError::InvalidName => write!(f, "mempool name contains null byte"),
MempoolError::CreateFailed => write!(f, "rte_pktmbuf_pool_create failed"),
}
}
}
impl std::error::Error for MempoolError {}