Skip to main content

nuclei/buf/
owned.rs

1//! The caller's own buffers that owned calls read into and write from
2//! ([`IoBuf`], [`IoBufMut`]), and the one form the runtime keeps them in
3//! while a call has them ([`OwnedBuf`]).
4//!
5//! An owned call takes the caller's buffer by value and gives it back with
6//! its result, so the kernel reads or writes the caller's memory and no
7//! byte is copied. While the call has the buffer, the runtime holds it as
8//! an [`OwnedBuf`]: a `Vec<u8>` or an [`AlignedBuf`] as it is, any other type
9//! boxed once. The call's code then works on that one type wherever the
10//! buffer goes (a ring operation, a job of the blocking pool, a side's lent
11//! read or write), and the buffer comes back as the caller's own type.
12//!
13//! A buffer that cannot come back (the call failed while the kernel still
14//! held it, so the runtime keeps it until the kernel is done) is answered
15//! with an empty one, its type's [`Default`].
16
17use core::any::{Any, TypeId};
18use core::mem::{ManuallyDrop, MaybeUninit};
19use core::panic::AssertUnwindSafe;
20
21use super::aligned::AlignedBuf;
22use super::vectored::Vectored;
23
24/// A buffer an owned write takes: memory at an address that does not move
25/// while the runtime holds the buffer, whose first
26/// [`bytes_init`](Self::bytes_init) bytes are written.
27///
28/// Implemented for `Vec<u8>` and [`AlignedBuf`]; a caller's own type (a
29/// shared byte buffer, memory of a registered region) may implement it too.
30/// It is `Send` and `Sync`, since the runtime may hand it to another thread
31/// and several zero-copy sends read it at once, and its [`Default`] is the
32/// empty buffer a call gives back when the caller's own cannot come back.
33///
34/// # Safety
35///
36/// [`stable_ptr`](Self::stable_ptr) is never null and points at
37/// [`bytes_total`](Self::bytes_total) bytes of memory, the first [`bytes_init`](Self::bytes_init) of them
38/// initialized, which stay valid and in place while the value is not used
39/// through `&mut` or dropped, even when the value itself moves: the kernel
40/// may read them after the value moved into the runtime.
41/// `bytes_init() <= bytes_total()`.
42pub unsafe trait IoBuf: Default + Send + Sync + 'static {
43    /// The address of the buffer's first byte.
44    fn stable_ptr(&self) -> *const u8;
45
46    /// How many bytes from the start hold data: what a write sends.
47    fn bytes_init(&self) -> usize;
48
49    /// How many bytes the buffer's memory holds in all.
50    fn bytes_total(&self) -> usize;
51}
52
53/// A buffer an owned read fills: an [`IoBuf`] whose memory past the bytes
54/// it holds may be written, and told how many hold data after a read.
55///
56/// # Safety
57///
58/// As [`IoBuf`]; and [`stable_mut_ptr`](Self::stable_mut_ptr) points at the
59/// same memory, writable for all [`bytes_total`](IoBuf::bytes_total) bytes.
60pub unsafe trait IoBufMut: IoBuf {
61    /// The address of the buffer's first byte, for writing.
62    fn stable_mut_ptr(&mut self) -> *mut u8;
63
64    /// Sets how many bytes from the start hold data to `pos` (the runtime
65    /// calls it with a smaller count too, never below what the caller
66    /// handed in).
67    ///
68    /// # Safety
69    ///
70    /// `pos <= bytes_total()`, and the first `pos` bytes are initialized.
71    unsafe fn set_init(&mut self, pos: usize);
72}
73
74// SAFETY: a vector's heap memory does not move with the vector, and its
75// first `len` bytes of `capacity` are initialized.
76unsafe impl IoBuf for Vec<u8> {
77    fn stable_ptr(&self) -> *const u8 {
78        self.as_ptr()
79    }
80
81    fn bytes_init(&self) -> usize {
82        self.len()
83    }
84
85    fn bytes_total(&self) -> usize {
86        self.capacity()
87    }
88}
89
90// SAFETY: as for `IoBuf`; the whole capacity is writable.
91unsafe impl IoBufMut for Vec<u8> {
92    fn stable_mut_ptr(&mut self) -> *mut u8 {
93        self.as_mut_ptr()
94    }
95
96    unsafe fn set_init(&mut self, pos: usize) {
97        // SAFETY: the caller's: `pos` is within the capacity and initialized.
98        unsafe { self.set_len(pos) }
99    }
100}
101
102/// `value` as a `U`, when `T` is `U`.
103fn cast<T, U>(value: T) -> Result<U, T>
104where
105    T: 'static,
106    U: 'static,
107{
108    if TypeId::of::<T>() != TypeId::of::<U>() {
109        return Err(value);
110    }
111    let value = ManuallyDrop::new(value);
112    // SAFETY: `T` and `U` are one type, and the value is never dropped as a
113    // `T`, so it is moved, not copied.
114    Ok(unsafe { core::ptr::read((&raw const *value).cast::<U>()) })
115}
116
117/// A caller's buffer of a type of its own, boxed while the runtime holds it.
118pub(crate) trait Kept: Any + Send + Sync {
119    fn ptr(&self) -> *const u8;
120    fn mut_ptr(&mut self) -> *mut u8;
121    fn init(&self) -> usize;
122    fn total(&self) -> usize;
123    /// # Safety
124    ///
125    /// As [`IoBufMut::set_init`].
126    unsafe fn set_init(&mut self, pos: usize);
127}
128
129/// The buffer of a write: nothing is ever read into it, so its room past
130/// the bytes it holds is none.
131struct Written<B>(B);
132
133impl<B> Kept for Written<B>
134where
135    B: IoBuf,
136{
137    fn ptr(&self) -> *const u8 {
138        self.0.stable_ptr()
139    }
140
141    fn mut_ptr(&mut self) -> *mut u8 {
142        // Never written through: the buffer has no room past its bytes.
143        self.0.stable_ptr().cast_mut()
144    }
145
146    fn init(&self) -> usize {
147        self.0.bytes_init()
148    }
149
150    fn total(&self) -> usize {
151        self.0.bytes_init()
152    }
153
154    unsafe fn set_init(&mut self, _pos: usize) {}
155}
156
157/// The buffer of a read.
158struct Filled<B>(B);
159
160impl<B> Kept for Filled<B>
161where
162    B: IoBufMut,
163{
164    fn ptr(&self) -> *const u8 {
165        self.0.stable_ptr()
166    }
167
168    fn mut_ptr(&mut self) -> *mut u8 {
169        self.0.stable_mut_ptr()
170    }
171
172    fn init(&self) -> usize {
173        self.0.bytes_init()
174    }
175
176    fn total(&self) -> usize {
177        self.0.bytes_total()
178    }
179
180    unsafe fn set_init(&mut self, pos: usize) {
181        // SAFETY: the caller's.
182        unsafe { self.0.set_init(pos) }
183    }
184}
185
186/// A caller's buffer while an owned call holds it: what the call reads into
187/// or writes from, in one type wherever the call goes. It reads as a `Vec<u8>`
188/// does: its bytes, its spare capacity, and the count of bytes it holds.
189///
190/// It is as large as a `Vec<u8>`, so the operations that carry it are no
191/// larger than they were for a vector: any other buffer is boxed.
192pub(crate) enum OwnedBuf {
193    Vec(Vec<u8>),
194    Boxed(BoxedBuf),
195}
196
197const _: () = assert!(size_of::<OwnedBuf>() == size_of::<Vec<u8>>());
198
199/// A buffer of another type than `Vec<u8>`, boxed, and dropped out of line:
200/// its drop reaches the buffers of a vectored call, each an [`OwnedBuf`], so
201/// inline it would make every drop of an `OwnedBuf` too large to inline.
202pub(crate) struct BoxedBuf(ManuallyDrop<Box<Boxed>>);
203
204impl BoxedBuf {
205    #[inline]
206    fn new(boxed: Boxed) -> Self {
207        Self(ManuallyDrop::new(Box::new(boxed)))
208    }
209
210    /// The buffer, out of its box.
211    fn into_inner(self) -> Boxed {
212        let mut this = ManuallyDrop::new(self);
213        // SAFETY: `this` is never dropped, so the box is taken once.
214        *unsafe { ManuallyDrop::take(&mut this.0) }
215    }
216}
217
218impl Drop for BoxedBuf {
219    #[inline(never)]
220    fn drop(&mut self) {
221        // SAFETY: dropped once, here; `into_inner` takes the box without it.
222        unsafe { ManuallyDrop::drop(&mut self.0) }
223    }
224}
225
226impl core::ops::Deref for BoxedBuf {
227    type Target = Boxed;
228
229    #[inline]
230    fn deref(&self) -> &Boxed {
231        &self.0
232    }
233}
234
235impl core::ops::DerefMut for BoxedBuf {
236    #[inline]
237    fn deref_mut(&mut self) -> &mut Boxed {
238        &mut self.0
239    }
240}
241
242/// A buffer of another type than `Vec<u8>`.
243pub(crate) enum Boxed {
244    Aligned(AlignedBuf),
245    /// Unwind safe as a `Vec<u8>` is, since a panic leaves no invariant of
246    /// the caller's buffer half made that the runtime relies on.
247    Kept(AssertUnwindSafe<Box<dyn Kept>>),
248    /// The buffers of a vectored call, written from or read into one after
249    /// the other: their bytes are not one slice, so its `Deref` is empty and
250    /// its users go through [`OwnedBuf::vectored_mut`].
251    Vectored(Vectored),
252}
253
254impl Default for OwnedBuf {
255    fn default() -> Self {
256        OwnedBuf::Vec(Vec::new())
257    }
258}
259
260impl OwnedBuf {
261    #[inline]
262    fn boxed(boxed: Boxed) -> Self {
263        OwnedBuf::Boxed(BoxedBuf::new(boxed))
264    }
265
266    /// The buffer of a write; a `Vec<u8>` as it is.
267    #[inline]
268    pub(crate) fn written<B>(buf: B) -> Self
269    where
270        B: IoBuf,
271    {
272        let buf = match cast::<B, Vec<u8>>(buf) {
273            Ok(vec) => return OwnedBuf::Vec(vec),
274            Err(buf) => buf,
275        };
276        let buf = match cast::<B, OwnedBuf>(buf) {
277            Ok(owned) => return owned,
278            Err(buf) => buf,
279        };
280        match cast::<B, AlignedBuf>(buf) {
281            Ok(aligned) => Self::boxed(Boxed::Aligned(aligned)),
282            Err(buf) => Self::boxed(Boxed::Kept(AssertUnwindSafe(Box::new(Written(buf))))),
283        }
284    }
285
286    /// The buffer of a read; a `Vec<u8>` as it is.
287    #[inline]
288    pub(crate) fn filled<B>(buf: B) -> Self
289    where
290        B: IoBufMut,
291    {
292        let buf = match cast::<B, Vec<u8>>(buf) {
293            Ok(vec) => return OwnedBuf::Vec(vec),
294            Err(buf) => buf,
295        };
296        let buf = match cast::<B, OwnedBuf>(buf) {
297            Ok(owned) => return owned,
298            Err(buf) => buf,
299        };
300        match cast::<B, AlignedBuf>(buf) {
301            Ok(aligned) => Self::boxed(Boxed::Aligned(aligned)),
302            Err(buf) => Self::boxed(Boxed::Kept(AssertUnwindSafe(Box::new(Filled(buf))))),
303        }
304    }
305
306    /// The caller's buffer of a write back, as the type it was handed in
307    /// as; an empty one if the call could not give it back.
308    #[inline]
309    pub(crate) fn into_written<B>(self) -> B
310    where
311        B: IoBuf,
312    {
313        match self {
314            OwnedBuf::Vec(vec) => match cast::<Vec<u8>, B>(vec) {
315                Ok(same) => same,
316                Err(vec) => OwnedBuf::Vec(vec).into_other::<B, Written<B>>(|kept| kept.0),
317            },
318            other => other.into_other::<B, Written<B>>(|kept| kept.0),
319        }
320    }
321
322    /// The caller's buffer of a read back, holding the bytes read into it.
323    #[inline]
324    pub(crate) fn into_filled<B>(self) -> B
325    where
326        B: IoBufMut,
327    {
328        match self {
329            OwnedBuf::Vec(vec) => match cast::<Vec<u8>, B>(vec) {
330                Ok(same) => same,
331                Err(vec) => OwnedBuf::Vec(vec).into_other::<B, Filled<B>>(|kept| kept.0),
332            },
333            other => other.into_other::<B, Filled<B>>(|kept| kept.0),
334        }
335    }
336
337    /// The caller's buffer back when it is not a `Vec<u8>`: the runtime's own
338    /// form as it is, a boxed one unboxed, or an empty one if it cannot.
339    #[inline(never)]
340    fn into_other<B, K>(self, unwrap: fn(K) -> B) -> B
341    where
342        B: IoBuf,
343        K: Kept,
344    {
345        let boxed = match cast::<OwnedBuf, B>(self) {
346            Ok(same) => return same,
347            Err(OwnedBuf::Boxed(boxed)) => boxed,
348            Err(OwnedBuf::Vec(_)) => return B::default(),
349        };
350        match boxed.into_inner() {
351            Boxed::Aligned(aligned) => cast::<AlignedBuf, B>(aligned).unwrap_or_default(),
352            Boxed::Kept(AssertUnwindSafe(kept)) => {
353                let kept: Box<dyn Any> = kept;
354                kept.downcast::<K>()
355                    .map_or_else(|_| B::default(), |k| unwrap(*k))
356            }
357            Boxed::Vectored(_) => B::default(),
358        }
359    }
360
361    /// The buffers of a vectored write, held as one.
362    pub(crate) fn vectored(bufs: Vec<OwnedBuf>) -> Self {
363        Self::boxed(Boxed::Vectored(Vectored::written(bufs)))
364    }
365
366    /// The buffers of a vectored read, held as one.
367    pub(crate) fn vectored_read(bufs: Vec<OwnedBuf>) -> Self {
368        Self::boxed(Boxed::Vectored(Vectored::filled(bufs)))
369    }
370
371    /// The buffers of a vectored call back; a buffer of one is its own.
372    pub(crate) fn into_segments(self) -> Vec<OwnedBuf> {
373        match self.into_vectored() {
374            Ok(vectored) => vectored.into_bufs(),
375            Err(one) => vec![one],
376        }
377    }
378
379    /// The buffers of a vectored call, or the buffer itself when it is one.
380    pub(crate) fn into_vectored(self) -> Result<Vectored, OwnedBuf> {
381        match self {
382            OwnedBuf::Boxed(boxed) => match boxed.into_inner() {
383                Boxed::Vectored(vectored) => Ok(vectored),
384                one => Err(OwnedBuf::boxed(one)),
385            },
386            one => Err(one),
387        }
388    }
389
390    /// The buffers of a vectored call, for a call that hands the kernel all
391    /// of them at once; `None` for one buffer.
392    #[inline]
393    pub(crate) fn vectored_mut(&mut self) -> Option<&mut Vectored> {
394        match self {
395            OwnedBuf::Vec(_) => None,
396            OwnedBuf::Boxed(boxed) => boxed.vectored_mut(),
397        }
398    }
399
400    /// The bytes from the `from`th of those it holds to the end of the slice
401    /// that byte is in: all the rest for one buffer, the rest of the buffer
402    /// it falls in for a vectored write. Empty past its end.
403    #[inline]
404    pub(crate) fn rest_from(&self, from: usize) -> &[u8] {
405        match self {
406            OwnedBuf::Vec(vec) => vec.get(from..).unwrap_or_default(),
407            OwnedBuf::Boxed(boxed) => boxed.rest_from(from),
408        }
409    }
410
411    /// How many bytes it holds.
412    #[inline]
413    pub(crate) fn len(&self) -> usize {
414        match self {
415            OwnedBuf::Vec(vec) => vec.len(),
416            OwnedBuf::Boxed(boxed) => boxed.len(),
417        }
418    }
419
420    #[inline]
421    pub(crate) fn is_empty(&self) -> bool {
422        self.len() == 0
423    }
424
425    /// How many bytes its memory holds in all (for a write's buffer, the
426    /// bytes it holds).
427    #[inline]
428    pub(crate) fn capacity(&self) -> usize {
429        match self {
430            OwnedBuf::Vec(vec) => vec.capacity(),
431            OwnedBuf::Boxed(boxed) => boxed.capacity(),
432        }
433    }
434
435    #[inline]
436    fn as_mut_ptr(&mut self) -> *mut u8 {
437        match self {
438            OwnedBuf::Vec(vec) => vec.as_mut_ptr(),
439            OwnedBuf::Boxed(boxed) => boxed.as_mut_ptr(),
440        }
441    }
442
443    /// Its memory past the bytes it holds.
444    #[inline]
445    pub(crate) fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
446        match self {
447            OwnedBuf::Vec(vec) => vec.spare_capacity_mut(),
448            OwnedBuf::Boxed(boxed) => boxed.spare_capacity_mut(),
449        }
450    }
451
452    /// Sets how many bytes it holds to `len`.
453    ///
454    /// # Safety
455    ///
456    /// `len <= capacity()`, and the first `len` bytes are initialized.
457    #[inline]
458    pub(crate) unsafe fn set_len(&mut self, len: usize) {
459        match self {
460            // SAFETY: the caller's.
461            OwnedBuf::Vec(vec) => unsafe { vec.set_len(len) },
462            // SAFETY: the caller's.
463            OwnedBuf::Boxed(boxed) => unsafe { boxed.set_len(len) },
464        }
465    }
466
467    /// Counts the `n` bytes after those it holds as held too.
468    ///
469    /// # Safety
470    ///
471    /// They are within its capacity and initialized (of a vectored read,
472    /// filling its buffers' rooms in order).
473    #[inline]
474    pub(crate) unsafe fn add_len(&mut self, n: usize) {
475        match self {
476            // SAFETY: the caller's.
477            OwnedBuf::Vec(vec) => unsafe { vec.set_len(vec.len() + n) },
478            OwnedBuf::Boxed(boxed) => {
479                let len = boxed.len() + n;
480                // SAFETY: the caller's.
481                unsafe { boxed.set_len(len) }
482            }
483        }
484    }
485
486    /// Keeps only its first `len` bytes.
487    #[inline]
488    pub(crate) fn truncate(&mut self, len: usize) {
489        if len < self.len() {
490            // SAFETY: fewer bytes than it holds, so all initialized.
491            unsafe { self.set_len(len) };
492        }
493    }
494
495    /// Copies as much of `bytes` as its spare capacity holds onto its end;
496    /// returns how many.
497    #[inline]
498    pub(crate) fn append(&mut self, bytes: &[u8]) -> usize {
499        if let Some(vectored) = self.vectored_mut() {
500            return vectored.append(bytes);
501        }
502        let len = self.len();
503        let spare = self.spare_capacity_mut();
504        let n = bytes.len().min(spare.len());
505        for (to, from) in spare.iter_mut().zip(&bytes[..n]) {
506            to.write(*from);
507        }
508        // SAFETY: the `n` bytes after the first `len` were just written.
509        unsafe { self.set_len(len + n) };
510        n
511    }
512
513    /// Zeroes its spare capacity and lends it as bytes; how many it holds is
514    /// left as it was.
515    pub(crate) fn spare_zeroed(&mut self) -> &mut [u8] {
516        if self.vectored_mut().is_some() {
517            return &mut [];
518        }
519        let len = self.len();
520        let room = self.capacity().saturating_sub(len);
521        if room == 0 {
522            return &mut [];
523        }
524        let ptr = self.as_mut_ptr();
525        // SAFETY: the `room` bytes past the first `len` are the buffer's own
526        // writable memory; zeroed, they are initialized.
527        unsafe {
528            core::ptr::write_bytes(ptr.add(len), 0, room);
529            core::slice::from_raw_parts_mut(ptr.add(len), room)
530        }
531    }
532}
533
534impl core::ops::Deref for OwnedBuf {
535    type Target = [u8];
536
537    #[inline]
538    fn deref(&self) -> &[u8] {
539        match self {
540            OwnedBuf::Vec(vec) => vec,
541            OwnedBuf::Boxed(boxed) => boxed.bytes(),
542        }
543    }
544}
545
546/// The buffers of other types than `Vec<u8>`, kept out of line so that a
547/// vector's accessors stay small enough to inline.
548impl Boxed {
549    #[inline(never)]
550    fn len(&self) -> usize {
551        match self {
552            Boxed::Aligned(aligned) => aligned.len(),
553            Boxed::Kept(kept) => kept.init(),
554            Boxed::Vectored(vectored) => vectored.len(),
555        }
556    }
557
558    #[inline(never)]
559    fn capacity(&self) -> usize {
560        match self {
561            Boxed::Aligned(aligned) => aligned.capacity(),
562            Boxed::Kept(kept) => kept.total(),
563            Boxed::Vectored(vectored) => vectored.capacity(),
564        }
565    }
566
567    #[inline(never)]
568    fn as_mut_ptr(&mut self) -> *mut u8 {
569        match self {
570            Boxed::Aligned(aligned) => aligned.as_mut_ptr(),
571            Boxed::Kept(kept) => kept.mut_ptr(),
572            Boxed::Vectored(_) => core::ptr::NonNull::dangling().as_ptr(),
573        }
574    }
575
576    #[inline(never)]
577    fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>] {
578        match self {
579            Boxed::Aligned(aligned) => aligned.spare_capacity_mut(),
580            Boxed::Kept(kept) => {
581                let (len, total) = (kept.init(), kept.total());
582                if len >= total {
583                    return &mut [];
584                }
585                // SAFETY: the buffer's memory holds `total` bytes, writable
586                // past the `len` that hold data (a write's has none).
587                unsafe {
588                    core::slice::from_raw_parts_mut(
589                        kept.mut_ptr().add(len).cast::<MaybeUninit<u8>>(),
590                        total - len,
591                    )
592                }
593            }
594            Boxed::Vectored(vectored) => vectored.spare_capacity_mut(),
595        }
596    }
597
598    /// # Safety
599    ///
600    /// As [`OwnedBuf::set_len`].
601    #[inline(never)]
602    unsafe fn set_len(&mut self, len: usize) {
603        match self {
604            // SAFETY: the caller's.
605            Boxed::Aligned(aligned) => unsafe { aligned.set_len(len) },
606            // SAFETY: the caller's.
607            Boxed::Kept(kept) => unsafe { kept.set_init(len) },
608            // SAFETY: the caller's.
609            Boxed::Vectored(vectored) => unsafe { vectored.set_len(len) },
610        }
611    }
612
613    #[inline(never)]
614    fn bytes(&self) -> &[u8] {
615        match self {
616            Boxed::Aligned(aligned) => aligned,
617            Boxed::Kept(kept) if kept.init() == 0 => &[],
618            // SAFETY: the first `init` bytes of the buffer's memory hold
619            // data.
620            Boxed::Kept(kept) => unsafe { core::slice::from_raw_parts(kept.ptr(), kept.init()) },
621            Boxed::Vectored(_) => &[],
622        }
623    }
624
625    #[inline(never)]
626    fn rest_from(&self, from: usize) -> &[u8] {
627        match self {
628            Boxed::Vectored(vectored) => vectored.rest_from(from),
629            other => other.bytes().get(from..).unwrap_or_default(),
630        }
631    }
632
633    #[inline(never)]
634    fn vectored_mut(&mut self) -> Option<&mut Vectored> {
635        match self {
636            Boxed::Vectored(vectored) => Some(vectored),
637            _ => None,
638        }
639    }
640}
641
642impl core::fmt::Debug for OwnedBuf {
643    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
644        f.debug_struct("OwnedBuf")
645            .field("len", &self.len())
646            .field("capacity", &self.capacity())
647            .finish()
648    }
649}
650
651// SAFETY: the runtime's own form of a caller's buffer, passed through the
652// owned calls as it is (never through these methods but by the runtime's
653// own code, which reads a vectored write through `rest_from`).
654unsafe impl IoBuf for OwnedBuf {
655    fn stable_ptr(&self) -> *const u8 {
656        self.as_ptr()
657    }
658
659    fn bytes_init(&self) -> usize {
660        self.len()
661    }
662
663    fn bytes_total(&self) -> usize {
664        self.capacity()
665    }
666}
667
668// SAFETY: as for `IoBuf`.
669unsafe impl IoBufMut for OwnedBuf {
670    fn stable_mut_ptr(&mut self) -> *mut u8 {
671        self.as_mut_ptr()
672    }
673
674    unsafe fn set_init(&mut self, pos: usize) {
675        // SAFETY: the caller's.
676        unsafe { self.set_len(pos) }
677    }
678}