Skip to content

Commit e4fd644

Browse files
committed
feat(virtq): add producer side batch API
Signed-off-by: Tomasz Andrzejak <andreiltd@gmail.com>
1 parent 2763ac0 commit e4fd644

4 files changed

Lines changed: 304 additions & 45 deletions

File tree

src/hyperlight_common/src/virtq/buffer.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,37 @@ impl<P: BufferProvider, M: MemOps> Drop for BufferOwner<P, M> {
117117
}
118118
}
119119

120+
impl<P: BufferProvider, M: MemOps> BufferOwner<P, M> {
121+
pub(crate) fn try_new(
122+
pool: P,
123+
mem: M,
124+
alloc: Allocation,
125+
written: usize,
126+
) -> Result<Self, M::Error> {
127+
// Pre check direct access before handing the owner to Bytes::from_owner
128+
let len = written.min(alloc.len);
129+
let _ = unsafe { mem.as_slice(alloc.addr, len) }?;
130+
131+
Ok(Self {
132+
pool,
133+
mem,
134+
alloc,
135+
written,
136+
})
137+
}
138+
}
139+
120140
impl<P: BufferProvider, M: MemOps> AsRef<[u8]> for BufferOwner<P, M> {
121141
fn as_ref(&self) -> &[u8] {
122142
let len = self.written.min(self.alloc.len);
123-
// Safety: BufferOwner keeps both the pool allocation and the M
124-
// alive, so the memory region is valid. Protocol-level descriptor
125-
// ownership transfer guarantees no concurrent writes.
143+
// Safety: BufferOwner keeps both the pool allocation and the M alive,
144+
// so the memory region is valid.
126145
match unsafe { self.mem.as_slice(self.alloc.addr, len) } {
127146
Ok(slice) => slice,
128-
Err(_) => &[],
147+
Err(_) => {
148+
debug_assert!(false, "BufferOwner direct slice failed");
149+
&[]
150+
}
129151
}
130152
}
131153
}

src/hyperlight_common/src/virtq/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,21 @@ limitations under the License.
7979
//!
8080
//! ## Multiple Entries
8181
//!
82-
//! Each submit checks event suppression and notifies independently:
82+
//! Each submit checks event suppression and notifies independently. Use
83+
//! [`VirtqProducer::batch`] when a higher-level protocol wants to publish
84+
//! multiple entries and kick the queue once.
8385
//!
8486
//! ```ignore
87+
//! let mut batch = producer.batch();
8588
//! for data in entries {
86-
//! let mut se = producer.chain()
89+
//! let mut se = batch.chain()
8790
//! .entry(data.len())
8891
//! .completion(64)
8992
//! .build()?;
9093
//! se.write_all(data)?;
91-
//! producer.submit(se)?;
94+
//! batch.submit(se)?;
9295
//! }
96+
//! batch.finish()?;
9397
//! ```
9498
//!
9599
//! ## Completion Batching with Event Suppression

0 commit comments

Comments
 (0)