use std::sync::atomic::Ordering;
use crate::blk_worker::GuestMemWriter;
pub fn read_used_idx(guest_mem: &GuestMemWriter, used_gpa: u64) -> u16 {
guest_mem.read_u16(used_gpa as usize + 2)
}
pub fn write_used_entry(
guest_mem: &GuestMemWriter,
used_gpa: u64,
queue_size: u16,
head_idx: u16,
total_bytes: u32,
) {
let used_idx = read_used_idx(guest_mem, used_gpa);
let entry_off = used_gpa as usize + 4 + ((used_idx as usize) % (queue_size as usize)) * 8;
guest_mem.write_u32(entry_off, head_idx as u32);
guest_mem.write_u32(entry_off + 4, total_bytes);
std::sync::atomic::fence(Ordering::Release);
guest_mem.write_u16(used_gpa as usize + 2, used_idx.wrapping_add(1));
}
pub fn should_notify(
guest_mem: &GuestMemWriter,
avail_gpa: u64,
queue_size: u16,
old_used: u16,
new_used: u16,
) -> bool {
if old_used == new_used {
return false;
}
let used_event_off = avail_gpa as usize + 4 + 2 * (queue_size as usize);
let used_event = guest_mem.read_u16(used_event_off);
new_used.wrapping_sub(used_event).wrapping_sub(1) < new_used.wrapping_sub(old_used)
}