* [RFC PATCH 0/2] rust: list: Add examples for linked list @ 2025-03-10 7:30 I Hsin Cheng 2025-03-10 7:30 ` [RFC PATCH 1/2] rust: list: Implement normal initializer for ListLinks I Hsin Cheng 2025-03-10 7:30 ` [RFC PATCH 2/2] rust: list: Add examples for linked list I Hsin Cheng 0 siblings, 2 replies; 6+ messages in thread From: I Hsin Cheng @ 2025-03-10 7:30 UTC (permalink / raw) To: ojeda Cc: alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin, a.hindborg, aliceryhl, tmgross, rust-for-linux, linux-kernel, skhan, linux-kernel-mentees, jserv, I Hsin Cheng This patch series introduce runnable examples for linked list. They also serve as the unit tests for the methods for "List". A new initialized method is also introduced for "ListLinks", in order to provide the ability to create a new "ListLinks" instance, and provide simplicity for the examples. If there exists a convenient and proper way to handle the return type of "ListLinks::new()", e.g. "ListLinks::try_pin_init()" , then the method won't be needed. I Hsin Cheng (2): rust: list: Implement normal initializer for ListLinks rust: list: Add examples for linked list rust/kernel/list.rs | 100 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) -- 2.43.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC PATCH 1/2] rust: list: Implement normal initializer for ListLinks 2025-03-10 7:30 [RFC PATCH 0/2] rust: list: Add examples for linked list I Hsin Cheng @ 2025-03-10 7:30 ` I Hsin Cheng 2025-03-10 9:44 ` Alice Ryhl 2025-03-10 7:30 ` [RFC PATCH 2/2] rust: list: Add examples for linked list I Hsin Cheng 1 sibling, 1 reply; 6+ messages in thread From: I Hsin Cheng @ 2025-03-10 7:30 UTC (permalink / raw) To: ojeda Cc: alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin, a.hindborg, aliceryhl, tmgross, rust-for-linux, linux-kernel, skhan, linux-kernel-mentees, jserv, I Hsin Cheng Currently ListLinks only supports to create an initializer through "new()", which will need further initialization because the return type of "new()" is "impl Pininit<Self>". Not even "ListLinksSlefPtr" use the method to create a new instance of "ListLinks". Implement a normal method to create a new instance of type "ListLinks". This may be redundant as long as there exist a convenient and proper way to deal with "ListLinks::new()". For now it's introduce for the simplicity of examples in the following patches. Signed-off-by: I Hsin Cheng <richard120310@gmail.com> --- rust/kernel/list.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rust/kernel/list.rs b/rust/kernel/list.rs index fb93330f4af4..57d75ca16434 100644 --- a/rust/kernel/list.rs +++ b/rust/kernel/list.rs @@ -158,6 +158,16 @@ unsafe impl<const ID: u64> Send for ListLinks<ID> {} unsafe impl<const ID: u64> Sync for ListLinks<ID> {} impl<const ID: u64> ListLinks<ID> { + /// Create a new instance of this type. + pub fn new_link() -> Self { + ListLinks { + inner: Opaque::new(ListLinksFields { + prev: ptr::null_mut(), + next: ptr::null_mut(), + }), + } + } + /// Creates a new initializer for this type. pub fn new() -> impl PinInit<Self> { // INVARIANT: Pin-init initializers can't be used on an existing `Arc`, so this value will -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC PATCH 1/2] rust: list: Implement normal initializer for ListLinks 2025-03-10 7:30 ` [RFC PATCH 1/2] rust: list: Implement normal initializer for ListLinks I Hsin Cheng @ 2025-03-10 9:44 ` Alice Ryhl 2025-03-10 11:14 ` I Hsin Cheng 0 siblings, 1 reply; 6+ messages in thread From: Alice Ryhl @ 2025-03-10 9:44 UTC (permalink / raw) To: I Hsin Cheng Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin, a.hindborg, tmgross, rust-for-linux, linux-kernel, skhan, linux-kernel-mentees, jserv On Mon, Mar 10, 2025 at 03:30:39PM +0800, I Hsin Cheng wrote: > Currently ListLinks only supports to create an initializer through > "new()", which will need further initialization because the return type > of "new()" is "impl Pininit<Self>". Not even "ListLinksSlefPtr" use the > method to create a new instance of "ListLinks". > > Implement a normal method to create a new instance of type "ListLinks". > This may be redundant as long as there exist a convenient and proper way > to deal with "ListLinks::new()". > > For now it's introduce for the simplicity of examples in the following > patches. > > Signed-off-by: I Hsin Cheng <richard120310@gmail.com> This change is not good. The ListLinks type has an invariant about when the pointers are null. The existing constructor argues that the invariant is satisfied because pin-init initializers can't be used in an existing Arc. Why is that satisfied here? Alice ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH 1/2] rust: list: Implement normal initializer for ListLinks 2025-03-10 9:44 ` Alice Ryhl @ 2025-03-10 11:14 ` I Hsin Cheng 2025-03-10 11:44 ` Alice Ryhl 0 siblings, 1 reply; 6+ messages in thread From: I Hsin Cheng @ 2025-03-10 11:14 UTC (permalink / raw) To: Alice Ryhl Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin, a.hindborg, tmgross, rust-for-linux, linux-kernel, skhan, linux-kernel-mentees, jserv On Mon, Mar 10, 2025 at 09:44:41AM +0000, Alice Ryhl wrote: > On Mon, Mar 10, 2025 at 03:30:39PM +0800, I Hsin Cheng wrote: > > Currently ListLinks only supports to create an initializer through > > "new()", which will need further initialization because the return type > > of "new()" is "impl Pininit<Self>". Not even "ListLinksSlefPtr" use the > > method to create a new instance of "ListLinks". > > > > Implement a normal method to create a new instance of type "ListLinks". > > This may be redundant as long as there exist a convenient and proper way > > to deal with "ListLinks::new()". > > > > For now it's introduce for the simplicity of examples in the following > > patches. > > > > Signed-off-by: I Hsin Cheng <richard120310@gmail.com> > > This change is not good. The ListLinks type has an invariant about when > the pointers are null. The existing constructor argues that the > invariant is satisfied because pin-init initializers can't be used in an > existing Arc. Why is that satisfied here? > > Alice Hi Alice, Thanks for your kindly review. Indeed , I was trying to find a way to cope with "ListLinks::new()", wondering if there's any macros like "ListLinks::try_pin_init!()" to help us deal with "impl PinInit", so I try to send a RFC patch for it. Sorry I overlooked "commit 52ae96f"[1], it demonstrate a good way to handle the basic structure for "List", I'll fix the patch and send a v2 as soon as possible. Still I would love to ask why don't we provide "ListLinks::pin_init" or "ListLinks::try_pin_init" to support for the pin-init initializer returned by "ListLink::new()" ? Maybe there're special reasons behind the pin-init initializer here ? I would love to learn if that's possible. I tried "Kbox::pint_init" but it wouldn't give variable of type "ListLinks". Best regards, I Hsin Cheng ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH 1/2] rust: list: Implement normal initializer for ListLinks 2025-03-10 11:14 ` I Hsin Cheng @ 2025-03-10 11:44 ` Alice Ryhl 0 siblings, 0 replies; 6+ messages in thread From: Alice Ryhl @ 2025-03-10 11:44 UTC (permalink / raw) To: I Hsin Cheng Cc: ojeda, alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin, a.hindborg, tmgross, rust-for-linux, linux-kernel, skhan, linux-kernel-mentees, jserv On Mon, Mar 10, 2025 at 12:14 PM I Hsin Cheng <richard120310@gmail.com> wrote: > > On Mon, Mar 10, 2025 at 09:44:41AM +0000, Alice Ryhl wrote: > > On Mon, Mar 10, 2025 at 03:30:39PM +0800, I Hsin Cheng wrote: > > > Currently ListLinks only supports to create an initializer through > > > "new()", which will need further initialization because the return type > > > of "new()" is "impl Pininit<Self>". Not even "ListLinksSlefPtr" use the > > > method to create a new instance of "ListLinks". > > > > > > Implement a normal method to create a new instance of type "ListLinks". > > > This may be redundant as long as there exist a convenient and proper way > > > to deal with "ListLinks::new()". > > > > > > For now it's introduce for the simplicity of examples in the following > > > patches. > > > > > > Signed-off-by: I Hsin Cheng <richard120310@gmail.com> > > > > This change is not good. The ListLinks type has an invariant about when > > the pointers are null. The existing constructor argues that the > > invariant is satisfied because pin-init initializers can't be used in an > > existing Arc. Why is that satisfied here? > > > > Alice > > Hi Alice, > > Thanks for your kindly review. Indeed , I was trying to find a way to > cope with "ListLinks::new()", wondering if there's any macros like > "ListLinks::try_pin_init!()" to help us deal with "impl PinInit", so I > try to send a RFC patch for it. > > Sorry I overlooked "commit 52ae96f"[1], it demonstrate a good way to > handle the basic structure for "List", I'll fix the patch and send a v2 > as soon as possible. > > Still I would love to ask why don't we provide "ListLinks::pin_init" or > "ListLinks::try_pin_init" to support for the pin-init initializer > returned by "ListLink::new()" ? Maybe there're special reasons behind > the pin-init initializer here ? I would love to learn if that's > possible. > > I tried "Kbox::pint_init" but it > wouldn't give variable of type "ListLinks". Please see the examples from: https://lore.kernel.org/rust-for-linux/20250210-cursor-between-v7-2-36f0215181ed@google.com/ Alice ^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC PATCH 2/2] rust: list: Add examples for linked list 2025-03-10 7:30 [RFC PATCH 0/2] rust: list: Add examples for linked list I Hsin Cheng 2025-03-10 7:30 ` [RFC PATCH 1/2] rust: list: Implement normal initializer for ListLinks I Hsin Cheng @ 2025-03-10 7:30 ` I Hsin Cheng 1 sibling, 0 replies; 6+ messages in thread From: I Hsin Cheng @ 2025-03-10 7:30 UTC (permalink / raw) To: ojeda Cc: alex.gaynor, boqun.feng, gary, bjorn3_gh, benno.lossin, a.hindborg, aliceryhl, tmgross, rust-for-linux, linux-kernel, skhan, linux-kernel-mentees, jserv, I Hsin Cheng Add basic examples for the structure "List". They also serve as the unit tests for basic list methods. A simple "struct MyData" is used here to serve as the data to form the list, the members are trivial and naive for the simplicity of examples. The trait "ListArcSafe<ID>" isn't tracked here, dicussions are needed to see whether a tracker is necessary. Link: https://github.com/Rust-for-Linux/linux/issues/1121 Signed-off-by: I Hsin Cheng <richard120310@gmail.com> --- rust/kernel/list.rs | 90 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/rust/kernel/list.rs b/rust/kernel/list.rs index 57d75ca16434..d1954c403f67 100644 --- a/rust/kernel/list.rs +++ b/rust/kernel/list.rs @@ -35,6 +35,96 @@ /// * All prev/next pointers in `ListLinks` fields of items in the list are valid and form a cycle. /// * For every item in the list, the list owns the associated [`ListArc`] reference and has /// exclusive access to the `ListLinks` field. +/// +/// # Examples +/// +/// ``` +/// use kernel::list::*; +/// +/// struct MyData { value: i32, link: ListLinks<0> }; +/// +/// impl_list_arc_safe! { +/// impl ListArcSafe<0> for MyData { untracked; } +/// } +/// impl_has_list_links! { +/// impl HasListLinks<0> for MyData { self.link } +/// } +/// impl_list_item! { +/// impl ListItem<0> for MyData { using ListLinks; } +/// } +/// +/// let mut my_list = List::<MyData, 0>::new(); +/// +/// // The list should be empty at the moment. +/// assert!(my_list.is_empty()); +/// +/// let item_1 = ListArc::<MyData, 0>::new( +/// MyData { +/// value: 10, +/// link: ListLinks::<0>::new_link(), +/// }, GFP_KERNEL +/// ).unwrap(); +/// +/// let item_2 = ListArc::<MyData, 0>::new( +/// MyData { +/// value: 20, +/// link: ListLinks::<0>::new_link(), +/// }, GFP_KERNEL +/// ).unwrap(); +/// +/// let item_3 = ListArc::<MyData, 0>::new( +/// MyData { +/// value: 30, +/// link: ListLinks::<0>::new_link(), +/// }, GFP_KERNEL +/// ).unwrap(); +/// +/// // Append the nodes using push_back() +/// my_list.push_back(item_1); +/// my_list.push_back(item_2); +/// my_list.push_back(item_3); +/// +/// // Verify the length of the list. +/// assert_eq!(my_list.iter().count(), 3); +/// +/// // Iterater over the list and verify +/// // the nodes were inserted correctly. +/// let mut counter = 10; +/// for item in my_list.iter() { +/// assert_eq!(item.value, counter); +/// counter += 10; +/// } +/// +/// // Pop the items out from the list and +/// // verify their content. +/// let item_3 = my_list.pop_back().unwrap(); +/// let item_1 = my_list.pop_front().unwrap(); +/// let item_2 = my_list.pop_front().unwrap(); +/// assert_eq!(item_1.value, 10); +/// assert_eq!(item_2.value, 20); +/// assert_eq!(item_3.value, 30); +/// assert!(my_list.is_empty()); +/// +/// // Append the nodes using push_front() +/// my_list.push_front(item_1); +/// my_list.push_front(item_2); +/// my_list.push_front(item_3); +/// assert_eq!(my_list.iter().count(), 3); +/// +/// // Use Cursor to verify the nodes were +/// // inserted correctly. +/// +/// let mut cursor = my_list.cursor_front().unwrap(); +/// assert_eq!(cursor.current().value, 30); +/// cursor = cursor.next().unwrap(); +/// assert_eq!(cursor.current().value, 20); +/// cursor = cursor.next().unwrap(); +/// assert_eq!(cursor.current().value, 10); +/// assert!(cursor.next().is_none()); +/// +/// # Ok::<(), Error>(()) +/// ``` +/// pub struct List<T: ?Sized + ListItem<ID>, const ID: u64 = 0> { first: *mut ListLinksFields, _ty: PhantomData<ListArc<T, ID>>, -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-03-10 11:44 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-03-10 7:30 [RFC PATCH 0/2] rust: list: Add examples for linked list I Hsin Cheng 2025-03-10 7:30 ` [RFC PATCH 1/2] rust: list: Implement normal initializer for ListLinks I Hsin Cheng 2025-03-10 9:44 ` Alice Ryhl 2025-03-10 11:14 ` I Hsin Cheng 2025-03-10 11:44 ` Alice Ryhl 2025-03-10 7:30 ` [RFC PATCH 2/2] rust: list: Add examples for linked list I Hsin Cheng
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).