#![cfg(mlnx4)]
use super::*;
use std::{io, mem};
#[derive(Clone, Copy, Default)]
#[repr(transparent)]
pub struct ExpWc(pub ibv_exp_wc);
impl ExpWc {
#[inline]
pub fn wr_id(&self) -> u64 {
self.0.wr_id
}
#[inline]
pub fn status(&self) -> WcStatus {
unsafe { WcStatus::from_unsafe(self.0.status) }
}
pub fn timestamp(&self) -> Option<u64> {
(self.0.exp_wc_flags & IBV_EXP_WC_WITH_TIMESTAMP != 0).then(|| self.0.timestamp)
}
}
pub trait ExpCq {
fn exp_poll_into(&self, wc: &mut [ExpWc]) -> io::Result<u32>;
}
impl ExpCq for Cq {
fn exp_poll_into(&self, wc: &mut [ExpWc]) -> io::Result<u32> {
if wc.is_empty() {
return Ok(0);
}
let num = unsafe {
ibv_exp_poll_cq(
self.as_raw(),
wc.len() as i32,
wc.as_mut_ptr().cast(),
mem::size_of::<ExpWc>() as _,
)
};
if num >= 0 {
for i in 0..num as usize {
if wc[i].0.exp_wc_flags & IBV_EXP_WC_WITH_TIMESTAMP != 0 {
wc[i].0.timestamp = unsafe {
ibv_exp_cqe_ts_to_ns(self.context().clock_info(), wc[i].0.timestamp)
};
}
}
Ok(num as u32)
} else {
Err(io::Error::from_raw_os_error(num))
}
}
}