Re: [PATCH 7/9] rust: list: add cursor

From: Alice Ryhl
Date: Wed Apr 03 2024 - 08:49:34 EST


On Wed, Apr 3, 2024 at 2:19 PM Benno Lossin <benno.lossin@xxxxxxxxx> wrote:
>
> On 02.04.24 14:17, Alice Ryhl wrote:
> > diff --git a/rust/kernel/list.rs b/rust/kernel/list.rs
> > index 892705dd0571..47e52818c7bd 100644
> > --- a/rust/kernel/list.rs
> > +++ b/rust/kernel/list.rs
> > @@ -408,6 +408,20 @@ pub fn push_all_back(&mut self, other: &mut List<T, ID>) {
> > other.first = ptr::null_mut();
> > }
> >
> > + /// Returns a cursor to the first element of the list.
> > + ///
> > + /// If the list is empty, this returns `None`.
> > + pub fn cursor_front(&mut self) -> Option<Cursor<'_, T, ID>> {
> > + if self.first.is_null() {
> > + None
> > + } else {
> > + Some(Cursor {
>
> Missing INVARIANT comment.
>
> > + current: self.first,
> > + list: self,
> > + })
> > + }
> > + }
> > +
> > /// Creates an iterator over the list.
> > pub fn iter(&self) -> Iter<'_, T, ID> {
> > // INVARIANT: If the list is empty, both pointers are null. Otherwise, both pointers point
> > @@ -476,6 +490,69 @@ fn next(&mut self) -> Option<ArcBorrow<'a, T>> {
> > }
> > }
> >
> > +/// A cursor into a [`List`].
> > +///
> > +/// # Invariants
> > +///
> > +/// The `current` pointer points a value in `list`.
> > +pub struct Cursor<'a, T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
> > + current: *mut ListLinksFields,
> > + list: &'a mut List<T, ID>,
> > +}
> > +
> > +impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> Cursor<'a, T, ID> {
> > + /// Access the current element of this cursor.
> > + pub fn current(&self) -> ArcBorrow<'_, T> {
> > + // SAFETY: The `current` pointer points a value in the list.
> > + let me = unsafe { T::view_value(ListLinks::from_fields(self.current)) };
> > + // SAFETY:
> > + // * All values in a list are stored in an `Arc`.
> > + // * The value cannot be removed from the list for the duration of the lifetime annotated
> > + // on the returned `ArcBorrow`, because removing it from the list would require mutable
> > + // access to the cursor or the list. However, the `ArcBorrow` holds an immutable borrow
> > + // on the cursor, which in turn holds an immutable borrow on the list, so any such
>
> The cursor has a mutable borrow on the list.
>
>
> > + // mutable access requires first releasing the immutable borrow on the cursor.
> > + // * Values in a list never have a `UniqueArc` reference.
>
> Is there some type invariant guaranteeing this?

The List owns a ListArc reference to the value. It would be unsound
for there to also be a UniqueArc reference to it.

Alice