capsules_system/
process_policies.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2024.
4
5//! Process policy implementations for the Tock kernel.
6//!
7//! This file contains implementations of policies the Tock kernel can use when
8//! managing processes. For example, these policies control decisions such as
9//! whether a specific process should be restarted.
10
11use kernel::process;
12use kernel::process::Process;
13use kernel::process::ProcessFaultPolicy;
14
15/// Simply panic the entire board if a process faults.
16pub struct PanicFaultPolicy {}
17
18impl ProcessFaultPolicy for PanicFaultPolicy {
19    fn action(&self, _: &dyn Process) -> process::FaultAction {
20        process::FaultAction::Panic
21    }
22}
23
24/// Simply stop the process and no longer schedule it if a process faults.
25pub struct StopFaultPolicy {}
26
27impl ProcessFaultPolicy for StopFaultPolicy {
28    fn action(&self, _: &dyn Process) -> process::FaultAction {
29        process::FaultAction::Stop
30    }
31}
32
33/// Stop the process and no longer schedule it if a process faults, but also
34/// print a debug message notifying the user that the process faulted and
35/// stopped.
36pub struct StopWithDebugFaultPolicy {}
37
38impl ProcessFaultPolicy for StopWithDebugFaultPolicy {
39    fn action(&self, process: &dyn Process) -> process::FaultAction {
40        kernel::debug!(
41            "Process {} faulted and was stopped.",
42            process.get_process_name()
43        );
44        process::FaultAction::Stop
45    }
46}
47
48/// Always restart the process if it faults.
49pub struct RestartFaultPolicy {}
50
51impl ProcessFaultPolicy for RestartFaultPolicy {
52    fn action(&self, _: &dyn Process) -> process::FaultAction {
53        process::FaultAction::Restart
54    }
55}
56
57/// Always restart the process if it faults, but print a debug message:
58pub struct RestartWithDebugFaultPolicy {}
59
60impl ProcessFaultPolicy for RestartWithDebugFaultPolicy {
61    fn action(&self, process: &dyn Process) -> process::FaultAction {
62        kernel::debug!(
63            "Process {} faulted and will be restarted.",
64            process.get_process_name()
65        );
66        process::FaultAction::Restart
67    }
68}
69
70/// Implementation of `ProcessFaultPolicy` that uses a threshold to decide
71/// whether to restart a process when it faults.
72///
73/// If the process has been restarted more times than the threshold
74/// then the process will be stopped and no longer scheduled.
75pub struct ThresholdRestartFaultPolicy {
76    threshold: usize,
77}
78
79impl ThresholdRestartFaultPolicy {
80    pub const fn new(threshold: usize) -> ThresholdRestartFaultPolicy {
81        ThresholdRestartFaultPolicy { threshold }
82    }
83}
84
85impl ProcessFaultPolicy for ThresholdRestartFaultPolicy {
86    fn action(&self, process: &dyn Process) -> process::FaultAction {
87        if process.get_restart_count() <= self.threshold {
88            process::FaultAction::Restart
89        } else {
90            process::FaultAction::Stop
91        }
92    }
93}
94
95/// Implementation of `ProcessFaultPolicy` that uses a threshold to decide
96/// whether to restart a process when it faults.
97///
98/// If the process has been restarted more times than the threshold
99/// then the board will panic.
100pub struct ThresholdRestartThenPanicFaultPolicy {
101    threshold: usize,
102}
103
104impl ThresholdRestartThenPanicFaultPolicy {
105    pub const fn new(threshold: usize) -> ThresholdRestartThenPanicFaultPolicy {
106        ThresholdRestartThenPanicFaultPolicy { threshold }
107    }
108}
109
110impl ProcessFaultPolicy for ThresholdRestartThenPanicFaultPolicy {
111    fn action(&self, process: &dyn Process) -> process::FaultAction {
112        if process.get_restart_count() <= self.threshold {
113            process::FaultAction::Restart
114        } else {
115            process::FaultAction::Panic
116        }
117    }
118}