On Sun, Mar 16, 2025 at 7:17?AM Andrew Ballance <andrewjballance at gmail.com> wrote:> > implement the equivalent of the rust std's Vec::resize > on the kernel's Vec type. > > Signed-off-by: Andrew Ballance <andrewjballance at gmail.com> > --- > rust/kernel/alloc/kvec.rs | 26 ++++++++++++++++++++++++++ > 1 file changed, 26 insertions(+) > > diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs > index 18bcc59f0b38..eb6d40a1bf8b 100644 > --- a/rust/kernel/alloc/kvec.rs > +++ b/rust/kernel/alloc/kvec.rs > @@ -554,6 +554,32 @@ pub fn from_elem(value: T, n: usize, flags: Flags) -> Result<Self, AllocError> { > > Ok(v) > } > + > + /// Resizes the [`Vec`] so that `len` is equal to `new_len`. > + /// > + /// If `new_len` is smaller than `len`, the `Vec` is [`Vec::truncate`]d. > + /// If `new_len` is larger, each new slot is filled with clones of `value`. > + /// > + /// # Examples > + /// > + /// ``` > + /// let mut v = kernel::kvec![1, 2, 3]?; > + /// v.resize(1, 42, GFP_KERNEL)?; > + /// assert_eq!(&v, &[1]); > + /// > + /// v.resize(3, 42, GFP_KERNEL)?; > + /// assert_eq!(&v, &[1, 42, 42]); > + /// > + /// # Ok::<(), Error>(()) > + /// ``` > + pub fn resize(&mut self, new_len: usize, value: T, flags: Flags) -> Result<(), AllocError> { > + if new_len > self.len() { > + self.extend_with(new_len - self.len(), value, flags) > + } else { > + self.truncate(new_len); > + Ok(()) > + } > + }You can avoid underflow checking in debug builds by using `checked_sub`: match new_len.checked_sub(self.len()) { Some(n) => self.extend_with(n, value, flags), None => { self.truncate(new_len); Ok(()) } }> } > > impl<T, A> Drop for Vec<T, A> > -- > 2.48.1 > >Either way: Reviewed-by: Tamir Duberstein <tamird at gmail.com>
On Tue Mar 18, 2025 at 9:12 PM CET, Tamir Duberstein wrote:> On Sun, Mar 16, 2025 at 7:17?AM Andrew Ballance > <andrewjballance at gmail.com> wrote: >> + pub fn resize(&mut self, new_len: usize, value: T, flags: Flags) -> Result<(), AllocError> { >> + if new_len > self.len() { >> + self.extend_with(new_len - self.len(), value, flags) >> + } else { >> + self.truncate(new_len); >> + Ok(()) >> + } >> + } > > You can avoid underflow checking in debug builds by using `checked_sub`:`checked_sub` doesn't only avoid underflow in debug builds, but rather in all builds. But the code below is a good suggestion. --- Cheers, Benno> match new_len.checked_sub(self.len()) { > Some(n) => self.extend_with(n, value, flags), > None => { > self.truncate(new_len); > Ok(()) > } > } > >> } >> >> impl<T, A> Drop for Vec<T, A> >> -- >> 2.48.1 >> >> > > Either way: > > Reviewed-by: Tamir Duberstein <tamird at gmail.com>
On Tue, Mar 18, 2025 at 8:50?PM Benno Lossin <benno.lossin at proton.me> wrote:> > On Tue Mar 18, 2025 at 9:12 PM CET, Tamir Duberstein wrote: > > On Sun, Mar 16, 2025 at 7:17?AM Andrew Ballance > > <andrewjballance at gmail.com> wrote: > >> + pub fn resize(&mut self, new_len: usize, value: T, flags: Flags) -> Result<(), AllocError> { > >> + if new_len > self.len() { > >> + self.extend_with(new_len - self.len(), value, flags) > >> + } else { > >> + self.truncate(new_len); > >> + Ok(()) > >> + } > >> + } > > > > You can avoid underflow checking in debug builds by using `checked_sub`: > > `checked_sub` doesn't only avoid underflow in debug builds, but rather > in all builds. But the code below is a good suggestion.Yes, I know :) I included that language because the underflow check is likely optimized away in release builds. Tamir