preempt_rt/
thread.rs

1use crate::sched::{IntoSchedParams, ParameterizedScheduler, Scheduler};
2use std::thread;
3
4#[must_use = "must eventually spawn the thread"]
5#[derive(Debug)]
6pub struct Builder {
7    name: Option<String>,
8    stack_size: Option<usize>,
9    parameterized_scheduler: ParameterizedScheduler,
10}
11
12impl Builder {
13    pub fn new(scheduler: Scheduler, params: impl IntoSchedParams) -> Builder {
14        Builder {
15            name: None,
16            stack_size: None,
17            parameterized_scheduler: scheduler.with_params(params.into_sched_params()),
18        }
19    }
20
21    pub fn name(mut self, name: &str) -> Builder {
22        self.name = Some(name.into());
23        self
24    }
25
26    pub fn stack_size(mut self, stack_size: usize) -> Builder {
27        self.stack_size = Some(stack_size);
28        self
29    }
30
31    pub fn try_spawn<F, T>(self, f: F) -> thread::JoinHandle<T>
32    where
33        F: FnOnce(crate::sched::RtResult<()>) -> T + Send + 'static,
34        T: Send + 'static,
35    {
36        let mut tb = thread::Builder::new();
37
38        if let Some(name) = self.name {
39            tb = tb.name(name.clone());
40        }
41
42        if let Some(stack_size) = self.stack_size {
43            tb = tb.stack_size(stack_size);
44        }
45
46        tb.spawn(|| {
47            let sched_result = self.parameterized_scheduler.set_current();
48            f(sched_result)
49        })
50        .expect("failed to spawn thread")
51    }
52}
53
54/// Spawn a thread with the provided scheduler and params.
55///
56/// Params can either be a SchedParams struct, or an i32 representing the desired priority.
57/// This function validates that the priority is between min and max for the scheduler before
58/// attempting to set it. It panics if the priority is outside the allowed range or setting the
59/// scheduler returns an error code.
60///
61/// This function will panic if the scheduler and priority are not correct or could not be set
62/// for any reason (process does not have the correct permissions, the scheduler is
63/// not supported on the target, or PREEMPT_RT is not enabled/not supported on this platform).
64pub fn spawn<F, T>(
65    scheduler: Scheduler,
66    params: impl IntoSchedParams,
67    f: F,
68) -> thread::JoinHandle<T>
69where
70    F: FnOnce() -> T,
71    F: Send + 'static,
72    T: Send + 'static,
73{
74    try_spawn(scheduler, params, move |set_result| {
75        set_result.expect("failed to set scheduler");
76        f()
77    })
78}
79
80/// Spawn a thread and attempt to set the schedule of the current thread. The result of setting
81/// the scheduler is provided to the thread closure as an argument.
82///
83/// Params can either be a SchedParams struct, or an i32 representing the desired priority.
84/// This function validates that the priority is between min and max for the scheduler before
85/// attempting to set it. Failures will continue execution and pass through the Result to the
86/// thread closure.
87///
88/// This function passes an RtResult to the provided closure which can be used to check if
89/// the chosen scheduler has been enabled.
90pub fn try_spawn<F, T>(
91    scheduler: Scheduler,
92    params: impl IntoSchedParams,
93    f: F,
94) -> thread::JoinHandle<T>
95where
96    F: FnOnce(crate::sched::RtResult<()>) -> T,
97    F: Send + 'static,
98    T: Send + 'static,
99{
100    Builder::new(scheduler, params).try_spawn(f)
101}