diff options
author | Alice Ryhl <aliceryhl@google.com> | 2023-08-28 10:48:07 +0000 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2023-09-25 09:46:42 -1000 |
commit | 15b286d1fd056b0366bc8d211ff2c4ce2449eacb (patch) | |
tree | 7fdf27b5adeffca0f1fd65d02dab33d72e762c4b /rust | |
parent | 115c95e9e14c482682080598907e6a18091fd0af (diff) | |
download | lwn-15b286d1fd056b0366bc8d211ff2c4ce2449eacb.tar.gz lwn-15b286d1fd056b0366bc8d211ff2c4ce2449eacb.zip |
rust: workqueue: add examples
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: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: "Andreas Hindborg (Samsung)" <nmi@metaspace.dk>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'rust')
-rw-r--r-- | rust/kernel/workqueue.rs | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs index 40ccc53f6e93..b67fb1ba168e 100644 --- a/rust/kernel/workqueue.rs +++ b/rust/kernel/workqueue.rs @@ -26,6 +26,112 @@ //! * 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}; +//! use kernel::{impl_has_work, new_work}; +//! +//! #[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 <- new_work!("MyStruct::work"), +//! })) +//! } +//! } +//! +//! 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}; +//! use kernel::{impl_has_work, new_work}; +//! +//! #[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 <- new_work!("MyStruct::work_1"), +//! work_2 <- new_work!("MyStruct::work_2"), +//! })) +//! } +//! } +//! +//! 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, sync::LockClassKey, types::Opaque}; |