mirror of
https://github.com/torvalds/linux.git
synced 2024-11-01 04:53:36 +01:00
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>
This commit is contained in:
parent
115c95e9e1
commit
15b286d1fd
1 changed files with 106 additions and 0 deletions
|
@ -26,6 +26,112 @@
|
||||||
//! * The `WorkItemPointer` trait is implemented for the pointer type that points at a something
|
//! * The `WorkItemPointer` trait is implemented for the pointer type that points at a something
|
||||||
//! that implements `WorkItem`.
|
//! 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)
|
//! C header: [`include/linux/workqueue.h`](../../../../include/linux/workqueue.h)
|
||||||
|
|
||||||
use crate::{bindings, prelude::*, sync::Arc, sync::LockClassKey, types::Opaque};
|
use crate::{bindings, prelude::*, sync::Arc, sync::LockClassKey, types::Opaque};
|
||||||
|
|
Loading…
Reference in a new issue