Skip to content

Commit

Permalink
rust: workqueue: add examples
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Martin Rodriguez Reboredo <[email protected]>
Reviewed-by: Gary Guo <[email protected]>
Reviewed-by: "Andreas Hindborg (Samsung)" <[email protected]>
Reviewed-by: Benno Lossin <[email protected]>
Reviewed-by: Boqun Feng <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
  • Loading branch information
Darksonn authored and htejun committed Sep 25, 2023
1 parent 115c95e commit 15b286d
Showing 1 changed file with 106 additions and 0 deletions.
106 changes: 106 additions & 0 deletions rust/kernel/workqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down

0 comments on commit 15b286d

Please sign in to comment.