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