Messages in this thread | | | From | "Andreas Hindborg (Samsung)" <> | Subject | Re: [PATCH v2 8/8] rust: workqueue: add examples | Date | Fri, 02 Jun 2023 16:48:14 +0200 |
| |
Alice Ryhl <aliceryhl@google.com> writes:
> This adds two examples of how to use the workqueue. The first example > shows how to use it when you only have one `work_struct` field, and the > second example shows how to use it when you have multiple `work_struct` > fields. > > Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg (Samsung) <nmi@metaspace.dk>
> --- > rust/kernel/workqueue.rs | 104 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 104 insertions(+) > > diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs > index c302e8b8624b..cefcf43ff40e 100644 > --- a/rust/kernel/workqueue.rs > +++ b/rust/kernel/workqueue.rs > @@ -26,6 +26,110 @@ > //! * The `WorkItemPointer` trait is implemented for the pointer type that points at a something > //! that implements `WorkItem`. > //! > +//! ## Example > +//! > +//! This example defines a struct that holds an integer and can be scheduled on the workqueue. When > +//! the struct is executed, it will print the integer. Since there is only one `work_struct` field, > +//! we do not need to specify ids for the fields. > +//! > +//! ``` > +//! use kernel::prelude::*; > +//! use kernel::sync::Arc; > +//! use kernel::workqueue::{self, Work, WorkItem}; > +//! > +//! #[pin_data] > +//! struct MyStruct { > +//! value: i32, > +//! #[pin] > +//! work: Work<MyStruct>, > +//! } > +//! > +//! impl_has_work! { > +//! impl HasWork<Self> for MyStruct { self.work } > +//! } > +//! > +//! impl MyStruct { > +//! fn new(value: i32) -> Result<Arc<Self>> { > +//! Arc::pin_init(pin_init!(MyStruct { > +//! value, > +//! work <- Work::new(), > +//! })) > +//! } > +//! } > +//! > +//! impl WorkItem for MyStruct { > +//! type Pointer = Arc<MyStruct>; > +//! > +//! fn run(this: Arc<MyStruct>) { > +//! pr_info!("The value is: {}", this.value); > +//! } > +//! } > +//! > +//! /// This method will enqueue the struct for execution on the system workqueue, where its value > +//! /// will be printed. > +//! fn print_later(val: Arc<MyStruct>) { > +//! let _ = workqueue::system().enqueue(val); > +//! } > +//! ``` > +//! > +//! The following example shows how multiple `work_struct` fields can be used: > +//! > +//! ``` > +//! use kernel::prelude::*; > +//! use kernel::sync::Arc; > +//! use kernel::workqueue::{self, Work, WorkItem}; > +//! > +//! #[pin_data] > +//! struct MyStruct { > +//! value_1: i32, > +//! value_2: i32, > +//! #[pin] > +//! work_1: Work<MyStruct, 1>, > +//! #[pin] > +//! work_2: Work<MyStruct, 2>, > +//! } > +//! > +//! impl_has_work! { > +//! impl HasWork<Self, 1> for MyStruct { self.work_1 } > +//! impl HasWork<Self, 2> for MyStruct { self.work_2 } > +//! } > +//! > +//! impl MyStruct { > +//! fn new(value_1: i32, value_2: i32) -> Result<Arc<Self>> { > +//! Arc::pin_init(pin_init!(MyStruct { > +//! value_1, > +//! value_2, > +//! work_1 <- Work::new(), > +//! work_2 <- Work::new(), > +//! })) > +//! } > +//! } > +//! > +//! impl WorkItem<1> for MyStruct { > +//! type Pointer = Arc<MyStruct>; > +//! > +//! fn run(this: Arc<MyStruct>) { > +//! pr_info!("The value is: {}", this.value_1); > +//! } > +//! } > +//! > +//! impl WorkItem<2> for MyStruct { > +//! type Pointer = Arc<MyStruct>; > +//! > +//! fn run(this: Arc<MyStruct>) { > +//! pr_info!("The second value is: {}", this.value_2); > +//! } > +//! } > +//! > +//! fn print_1_later(val: Arc<MyStruct>) { > +//! let _ = workqueue::system().enqueue::<Arc<MyStruct>, 1>(val); > +//! } > +//! > +//! fn print_2_later(val: Arc<MyStruct>) { > +//! let _ = workqueue::system().enqueue::<Arc<MyStruct>, 2>(val); > +//! } > +//! ``` > +//! > //! C header: [`include/linux/workqueue.h`](../../../../include/linux/workqueue.h) > > use crate::{bindings, prelude::*, sync::Arc, types::Opaque};
| |