Skip to content

Commit 3851011

Browse files
committed
rust: thread: Add Thread wrapper
Signed-off-by: Boqun Feng <[email protected]>
1 parent 51a196e commit 3851011

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

drivers/char/rust_example.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use kernel::{
1414
file_operations::FileOperations,
1515
miscdev, mutex_init, spinlock_init,
1616
sync::{Mutex, SpinLock},
17+
thread::Thread,
1718
};
1819

1920
module! {
@@ -97,6 +98,22 @@ impl KernelModule for RustExample {
9798
println!("Value: {}", *data.lock());
9899
}
99100

101+
// Test threads.
102+
{
103+
let mut a = 1;
104+
105+
let t1 = Thread::new(
106+
move || {
107+
for _ in 0..20 {
108+
a = a + 1;
109+
println!("Hello Rust Thread {}", a);
110+
}
111+
},
112+
"Rust thread",
113+
);
114+
t1.wake_up();
115+
}
116+
100117
// Including this large variable on the stack will trigger
101118
// stack probing on the supported archs.
102119
// This will verify that stack probing does not lead to

rust/kernel/bindings_helper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <linux/uaccess.h>
1010
#include <linux/version.h>
1111
#include <linux/miscdevice.h>
12+
#include <linux/kthread.h>
13+
#include <linux/err.h>
1214

1315
// `bindgen` gets confused at certain things
1416
const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;

rust/kernel/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub mod printk;
4242
pub mod random;
4343
mod static_assert;
4444
pub mod sync;
45+
pub mod thread;
4546

4647
#[cfg(CONFIG_SYSCTL)]
4748
pub mod sysctl;

rust/kernel/thread.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
use crate::bindings;
4+
use crate::c_types;
5+
6+
use alloc::boxed::Box;
7+
use core::ops::FnOnce;
8+
9+
#[no_mangle]
10+
unsafe extern "C" fn rust_thread_func(data: *mut c_types::c_void) -> c_types::c_int {
11+
Box::from_raw(data as *mut Box<dyn FnOnce()>)();
12+
0
13+
}
14+
15+
pub struct Thread {
16+
task: *mut bindings::task_struct,
17+
}
18+
19+
impl Thread {
20+
pub fn new<F>(f: F, name: &str) -> Self
21+
where
22+
F: FnOnce(),
23+
F: Send + 'static,
24+
{
25+
let bf: Box<dyn FnOnce() + 'static> = Box::new(f);
26+
27+
unsafe {
28+
let task = bindings::kthread_create_on_node(
29+
Some(rust_thread_func),
30+
Box::into_raw(Box::new(bf)) as *mut _,
31+
bindings::NUMA_NO_NODE,
32+
"%s".as_ptr() as *const c_types::c_char,
33+
name.as_ptr(),
34+
);
35+
Thread { task: task }
36+
}
37+
}
38+
39+
pub fn wake_up(&self) {
40+
unsafe {
41+
bindings::wake_up_process(self.task);
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)