From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA310C3DA64 for ; Thu, 1 Aug 2024 15:08:06 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 168106B009F; Thu, 1 Aug 2024 11:08:06 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 1181D6B00A0; Thu, 1 Aug 2024 11:08:06 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id F21FF6B00A2; Thu, 1 Aug 2024 11:08:05 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id D17496B009F for ; Thu, 1 Aug 2024 11:08:05 -0400 (EDT) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 66CD5C0938 for ; Thu, 1 Aug 2024 15:08:05 +0000 (UTC) X-FDA: 82404006930.05.174B3A9 Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) by imf13.hostedemail.com (Postfix) with ESMTP id 5CEA72000F for ; Thu, 1 Aug 2024 15:08:03 +0000 (UTC) Authentication-Results: imf13.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=dCdNIFYy; spf=pass (imf13.hostedemail.com: domain of aliceryhl@google.com designates 209.85.221.46 as permitted sender) smtp.mailfrom=aliceryhl@google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1722524807; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=vizYiMazlQtEmYAHeE5sxQujP9cdybZTZcyos4O6/34=; b=KQ6uhQzMYcs4oaECZ8phZ+MRw87u0JHJIN6stRkx3LcXzzBYvIoB/nshZY7Kqh6pn6Lm4i VpDyuU1RLEMSaislvDNoi4AiVIMXbUiEahPU0jXAJ8P1nbCB8zxsOiXHV/f06L6VBZujjO 3Wyb6+4DM11BwUrGibyYNstJrT/GVmI= ARC-Authentication-Results: i=1; imf13.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=dCdNIFYy; spf=pass (imf13.hostedemail.com: domain of aliceryhl@google.com designates 209.85.221.46 as permitted sender) smtp.mailfrom=aliceryhl@google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1722524807; a=rsa-sha256; cv=none; b=Ckp01cfqb8DYaEgSEWdlv/dfU56iA/uwenyKDVSTbxgB5wE3aIdHCZkXAtySdmgRTuaiPP jhQBiLZg2Yj4DPRiYreqhY2tFmsB/NLOWpxzCDLFUojXgJ13MCnif4nIIvMmiJYHzYuC7A OsSAxJ/vM5UORNlq70pIbGTdLmdGwl4= Received: by mail-wr1-f46.google.com with SMTP id ffacd0b85a97d-368440b073bso1494281f8f.0 for ; Thu, 01 Aug 2024 08:08:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1722524881; x=1723129681; darn=kvack.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=vizYiMazlQtEmYAHeE5sxQujP9cdybZTZcyos4O6/34=; b=dCdNIFYyEjNm38g8wZQLAONbIkS/dITgItkvHSP1jTVecPqhoDu6WCxULFD1PWasF3 5sgi2gL82NIs3/sOvcFsMNG2hBIeD9+qpWNE+1e162SfmJ4qaXj7SixhKKUB1Oq4v6U1 VzzHSkNqoX00Qmh0f31c8PONqdU00cagZVRgqWY0ZA3xSiQlnsF9P919JdDEGBlEe8q1 adLrY70adJ45ASzq6aAACOIMs1DzMRnvjhIoxwipGQ47DtURItfAe3k2qJNwXhqXGAj9 JOuFURap9mQmcHaHDLu35uorK7oNucWA697FnDSJX0H16z5LyQ3YWI1WWUPzC8g9i60O +DAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722524882; x=1723129682; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vizYiMazlQtEmYAHeE5sxQujP9cdybZTZcyos4O6/34=; b=fmMXJcIzANtXX31wwOCfjsWH/kn2gYsb+UYf9SRgEEkiDGZC9TUyTXDwX8kyl0C+Rh WqMF01B8eQDIm5SnKfIe0YTslpQaZhcSi7qG4tFKsVS8VPrQTuwJotX2i+rACA1urn0f /Z3rJ7OccI77A1weQBz60wd1LYHr95pYMV2ccWbgMudGCuHNZzJxm/8FXJPggHyiYnIH R8A/u4G0DtwdQq7XmPUtYXmj4me3hj2fjZmYdNB2fR/MittNuG5OIBSfL5oo7BHD1I4K L2GY0AQzXG6UZCq6RLtvZVNQoowdxnA3HXfTPrHbdZGB8ICf+zFXs899+167iytXE5Ac ml4g== X-Forwarded-Encrypted: i=1; AJvYcCWcrVHGwl4dNFkrJbCCD82QDbFcb5QZLN0yAzLVpkn8Eubv0P6LRFOOMtUXeQDlyegInXshx9y4IOjCC3v6whZczgI= X-Gm-Message-State: AOJu0YxoVrYefhgMUC8tcjA27ji5U/MPCo1LiltR4RYMq8oaomnqzRQa bgwzoRhUA9i8IQgdubMI71YsSG0sWwyXJ9OI9RWs3/3PL+bBxSw7uo6sGet4dsK2SMfJXehpQx6 0lmUYzgyFfs9ZoeNLIEDX/b8azuZk+qgBdq/o X-Google-Smtp-Source: AGHT+IHFQ6rW6WpmdZpV3rx5JcfrGd60MukV3jEmR+h3sIwd7AxVnACcQa0y7IQKDQ2ho1ntU6252CFAQl1Q56G+/Dg= X-Received: by 2002:a05:6000:156e:b0:360:8c88:ab82 with SMTP id ffacd0b85a97d-36bbbeefe27mr317933f8f.30.1722524881255; Thu, 01 Aug 2024 08:08:01 -0700 (PDT) MIME-Version: 1.0 References: <20240801000641.1882-1-dakr@kernel.org> <20240801000641.1882-17-dakr@kernel.org> In-Reply-To: <20240801000641.1882-17-dakr@kernel.org> From: Alice Ryhl Date: Thu, 1 Aug 2024 17:07:48 +0200 Message-ID: Subject: Re: [PATCH v3 16/25] rust: alloc: implement `IntoIterator` for `Vec` To: Danilo Krummrich Cc: ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, benno.lossin@proton.me, a.hindborg@samsung.com, akpm@linux-foundation.org, daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, acurrid@nvidia.com, cjia@nvidia.com, jhubbard@nvidia.com, airlied@redhat.com, ajanulgu@redhat.com, lyude@redhat.com, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-mm@kvack.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: 5CEA72000F X-Stat-Signature: ng7qyezj19qhso1ag13q4fh6uigg68yi X-Rspam-User: X-HE-Tag: 1722524883-805858 X-HE-Meta: U2FsdGVkX1+jf1GvREF4oFnj1QQ8s2mw9/CiOUVoAx7k9cYfEhNbYntLMxzq7hMuaRU3HrjZ2ViXSNAJL/ZDlQVsWSDG69YDfsvAVOmF2TxyMTIRmTyil9bRzztD9K31424yies9hunWxXqlCQmlGrtbFeuNOxtiT6CPA49BpGIEI8l34+GiX6dXmcNmpadCDZ+WF7QlRBokAvJ0MrBl0iPRad/dX9aW6Kg12MKHMRe1vbZlZbgpMWk5dCz9/8TKfcLUtZGIttlpEkAXaSJ3+7jXuv4J3dIvwMqKtej0NNrvE+szasscT5q9r+ZVEB/Jo9Dw/I7Te0Z1+MAeyP8clhOkHgRXm8FWQLcnnu0epO3w6xHMC6J15ROHSaX7b1jr+OUNnjt7S2y09ic2Wo2iCmtdyB+gmZTYRcT5jatnv55/dg3C509YhMHfhmo4UPcscIZ7Aphxl3FBgDJZfTTkqvoTuNpXk3DkfKntW/5C3lNH08bUxps0AB+cSPPUW3pfsWglOf+MLpjjWhFivBjyFAp01rdU8dhi8GwWEzm/wHjfKh/E6e8+rAKIEGOjSwhHgBlBDW68KnBK3KL/cRodKrV13bBlVtVHz8EvNnnOJflzdiskzW+xyYtFNtGvYS5nup3x9Z0kQBqCSjFvmDtd66aDIebnEXSCRfMaT8gWUYwtCtssramk8wB3PQE65hqmQloeNYSe9LnNHdNL4CJHt6hLpJ4FhrLZ7DasUSap9ayp2LApdtThJLT9UV3y2BJ62C7kMhTE+8SqDQnWLSI4Ddy/Yt0+NVwlcHZH9fl6iKbCELhB2d8ofjh25xR1ln03m0Pb3KlBtzdizD/5C18ucEkib2nM8CR+fqg7sctOgmk0K2Ra1Jj0e6jKe11CjeS1Ynb1fx0sfXneS4lZtuuJQLYN/qrs81T0/sEoFZSWN1+P0JeVl3JzPfno7iS57kQS+t0Vt551/A6ulcCj9Gi 7wItJz6l nNSeCLUWKU2AfT+G7U+r9EIEva3mazxdEjq7Uz6i2/PGImg/wyKadNuFVDWHuElKVFOhw0au4bek9UWiwm4ovTmjH1nweloeFCd3GK4cb1J0erw9ywakS9QWxGbuO6zgue7ePfMqyFN1LT43VWDahhBRZp1omYWamZBh4HW8TI9kGEJejJlopQlPb6GBzbmZ+JQ5DbRrrBxETvQbFUAKHhFqrJSr8jy006fhp0FRgP37kD0cu4u220aUyuNK2wfcAw+2Dy3SwDqpJpHxsYn4Xo57KnA1WjjJH9RwUtgCokQ3f8Ki1NOmOVq2Y6QrEvoDH/uzbZm7KDt0KWlyw/zTkz8wzjQ== X-Bogosity: Ham, tests=bogofilter, spamicity=0.074402, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: On Thu, Aug 1, 2024 at 2:08=E2=80=AFAM Danilo Krummrich w= rote: > > Implement `IntoIterator` for `Vec`, `Vec`'s `IntoIter` type, as well as > `Iterator` for `IntoIter`. > > `Vec::into_iter` disassembles the `Vec` into its raw parts; additionally, > `IntoIter` keeps track of a separate pointer, which is incremented > correspondingsly as the iterator advances, while the length, or the count > of elements, is decremented. > > This also means that `IntoIter` takes the ownership of the backing > buffer and is responsible to drop the remaining elements and free the > backing buffer, if it's dropped. > > Signed-off-by: Danilo Krummrich > --- > rust/kernel/alloc.rs | 1 + > rust/kernel/alloc/kvec.rs | 186 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 187 insertions(+) > > diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs > index bd93140f3094..f2998ad57456 100644 > --- a/rust/kernel/alloc.rs > +++ b/rust/kernel/alloc.rs > @@ -19,6 +19,7 @@ > pub use self::kbox::KVBox; > pub use self::kbox::VBox; > > +pub use self::kvec::IntoIter; > pub use self::kvec::KVVec; > pub use self::kvec::KVec; > pub use self::kvec::VVec; > diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs > index 04cc85f7d92c..50e7705e5686 100644 > --- a/rust/kernel/alloc/kvec.rs > +++ b/rust/kernel/alloc/kvec.rs > @@ -12,6 +12,8 @@ > ops::DerefMut, > ops::Index, > ops::IndexMut, > + ptr, > + ptr::NonNull, > slice, > slice::SliceIndex, > }; > @@ -581,3 +583,187 @@ fn eq(&self, other: &$rhs) -> bool { self[..] =3D= =3D other[..] } > __impl_slice_eq! { [A: Allocator] [T], Vec } > __impl_slice_eq! { [A: Allocator, const N: usize] Vec, [U; N] } > __impl_slice_eq! { [A: Allocator, const N: usize] Vec, &[U; N] } > + > +impl<'a, T, A> IntoIterator for &'a Vec > +where > + A: Allocator, > +{ > + type Item =3D &'a T; > + type IntoIter =3D slice::Iter<'a, T>; > + > + fn into_iter(self) -> Self::IntoIter { > + self.iter() > + } > +} > + > +impl<'a, T, A: Allocator> IntoIterator for &'a mut Vec > +where > + A: Allocator, > +{ > + type Item =3D &'a mut T; > + type IntoIter =3D slice::IterMut<'a, T>; > + > + fn into_iter(self) -> Self::IntoIter { > + self.iter_mut() > + } > +} > + > +/// An iterator that moves out of a vector. > +/// > +/// This `struct` is created by the `into_iter` method on [`Vec`] (provi= ded by the [`IntoIterator`] > +/// trait). > +/// > +/// # Examples > +/// > +/// ``` > +/// let v =3D kernel::kvec![0, 1, 2]?; > +/// let iter =3D v.into_iter(); > +/// > +/// # Ok::<(), Error>(()) > +/// ``` > +pub struct IntoIter { > + ptr: *mut T, > + buf: NonNull, > + len: usize, > + cap: usize, > + _p: PhantomData, > +} > + > +impl IntoIter > +where > + A: Allocator, > +{ > + fn as_raw_mut_slice(&mut self) -> *mut [T] { > + ptr::slice_from_raw_parts_mut(self.ptr, self.len) > + } > +} > + > +impl Iterator for IntoIter > +where > + A: Allocator, > +{ > + type Item =3D T; > + > + /// # Examples > + /// > + /// ``` > + /// let v =3D kernel::kvec![1, 2, 3]?; > + /// let mut it =3D v.into_iter(); > + /// > + /// assert_eq!(it.next(), Some(1)); > + /// assert_eq!(it.next(), Some(2)); > + /// assert_eq!(it.next(), Some(3)); > + /// assert_eq!(it.next(), None); > + /// > + /// # Ok::<(), Error>(()) > + /// ``` > + fn next(&mut self) -> Option { > + if self.len =3D=3D 0 { > + return None; > + } > + > + let ptr =3D self.ptr; > + if !Vec::::is_zst() { > + // SAFETY: We can't overflow; `end` is guaranteed to mark th= e end of the buffer. > + unsafe { self.ptr =3D self.ptr.add(1) }; > + } else { > + // For ZST `ptr` has to stay where it is to remain aligned, = so we just reduce `self.len` > + // by 1. > + } > + self.len -=3D 1; > + > + // SAFETY: `ptr` is guaranteed to point at a valid element withi= n the buffer. > + Some(unsafe { ptr.read() }) > + } > + > + /// # Examples > + /// > + /// ``` > + /// let v: KVec =3D kernel::kvec![1, 2, 3]?; > + /// let mut iter =3D v.into_iter(); > + /// let size =3D iter.size_hint().0; > + /// > + /// iter.next(); > + /// assert_eq!(iter.size_hint().0, size - 1); > + /// > + /// iter.next(); > + /// assert_eq!(iter.size_hint().0, size - 2); > + /// > + /// iter.next(); > + /// assert_eq!(iter.size_hint().0, size - 3); > + /// > + /// # Ok::<(), Error>(()) > + /// ``` > + fn size_hint(&self) -> (usize, Option) { > + (self.len, Some(self.len)) > + } > +} > + > +impl Drop for IntoIter > +where > + A: Allocator, > +{ > + fn drop(&mut self) { > + // SAFETY: Drop the remaining vector's elements in place, before= we free the backing > + // memory. > + unsafe { ptr::drop_in_place(self.as_raw_mut_slice()) }; > + > + // If `cap =3D=3D 0` we never allocated any memory in the first = place. > + if self.cap !=3D 0 { > + // SAFETY: `self.buf` was previously allocated with `A`. > + unsafe { A::free(self.buf.cast()) }; > + } Is this ok for ZST? > + } > +} > + > +impl IntoIterator for Vec > +where > + A: Allocator, > +{ > + type Item =3D T; > + type IntoIter =3D IntoIter; > + > + /// Creates a consuming iterator, that is, one that moves each value= out of > + /// the vector (from start to end). The vector cannot be used after = calling > + /// this. > + /// > + /// # Examples > + /// > + /// ``` > + /// let v =3D kernel::kvec![1, 2]?; > + /// let mut v_iter =3D v.into_iter(); > + /// > + /// let first_element: Option =3D v_iter.next(); > + /// > + /// assert_eq!(first_element, Some(1)); > + /// assert_eq!(v_iter.next(), Some(2)); > + /// assert_eq!(v_iter.next(), None); > + /// > + /// # Ok::<(), Error>(()) > + /// ``` > + /// > + /// ``` > + /// let v =3D kernel::kvec![]; > + /// let mut v_iter =3D v.into_iter(); > + /// > + /// let first_element: Option =3D v_iter.next(); > + /// > + /// assert_eq!(first_element, None); > + /// > + /// # Ok::<(), Error>(()) > + /// ``` > + #[inline] > + fn into_iter(self) -> Self::IntoIter { > + let (ptr, len, cap) =3D self.into_raw_parts(); > + > + IntoIter { > + ptr, > + // SAFETY: `ptr` is either a dangling pointer or a pointer t= o a valid memory > + // allocation, allocated with `A`. > + buf: unsafe { NonNull::new_unchecked(ptr) }, > + len, > + cap, > + _p: PhantomData::, > + } > + } > +} > -- > 2.45.2 >