Skip to main content

joule_profiler_source_rapl/
error.rs

1use crate::domain_type::RaplDomainType;
2use thiserror::Error;
3
4/// Errors that can occur when using the RAPL source.
5#[derive(Debug, Error)]
6pub enum RaplError {
7    /// Intel RAPL interface is not available on this system.
8    #[error("Intel RAPL not available: {0}")]
9    RaplNotAvailable(String),
10
11    /// No RAPL domains were discovered on this system.
12    #[error("No RAPL domains found")]
13    NoDomains,
14
15    /// Failed to read a value from a RAPL domain.
16    #[error("Failed to read RAPL domain: {0}")]
17    RaplReadError(String),
18
19    /// A RAPL sysfs path could not be parsed or resolved.
20    #[error("Invalid RAPL domain path: {0}")]
21    InvalidRaplPath(String),
22
23    /// The socket specification string is malformed.
24    #[error("Invalid socket specification: {0}")]
25    InvalidSocketSpec(String),
26
27    /// The requested socket index does not exist in the discovered RAPL domains.
28    #[error("Socket {0} not found in available RAPL domains")]
29    SocketNotFound(u32),
30
31    /// A required system command was not found.
32    #[error("Command not found: {0}")]
33    CommandNotFound(String),
34
35    /// RAPL is only supported on Linux.
36    #[error("Unsupported operating system: {0}. Only Linux is supported")]
37    UnsupportedOS(String),
38
39    /// The process lacks the required permissions to access RAPL counters.
40    #[error("Insufficient permissions to access RAPL counters. Try running with sudo")]
41    InsufficientPermissions,
42
43    /// A RAPL domain name could not be matched to a known type.
44    #[error("Unknown domain {0}")]
45    UnknownDomain(String),
46
47    /// No CPU in the socket was able to open the perf counter for this domain.
48    /// It can also appear if `perf_event_open` returns an error other than unsupported event for a specific CPU.
49    #[error("Failed to open domain counter, {0}")]
50    FailToOpenDomainCounter(String),
51
52    /// The event format string for this domain could not be parsed.
53    #[error("Invalid event format for domain {0}")]
54    InvalidEventFormat(String),
55
56    /// This RAPL domain is not supported by the hardware.
57    #[error("Domain {0} not supported")]
58    DomainNotSupported(RaplDomainType),
59
60    /// The `perf_event_paranoid` level is too restrictive.
61    #[error(transparent)]
62    PerfParanoid(#[from] PerfParanoidError),
63
64    /// The energy scale factor could not be retrieved from the perf event.
65    #[error("Cannot retrieve perf RAPL scale")]
66    RetrieveScaleError,
67
68    /// Generic I/O error not covered by other variants.
69    #[error(transparent)]
70    IoError(std::io::Error),
71
72    /// Failed to parse an energy value as an integer.
73    #[error("Failed to parse energy value")]
74    ParseEnergyError(
75        #[from]
76        #[source]
77        std::num::ParseIntError,
78    ),
79
80    /// Failed to parse a domain scale value as a float.
81    #[error("Failed to parse domain scale")]
82    ParseDomainScale(
83        #[from]
84        #[source]
85        std::num::ParseFloatError,
86    ),
87
88    /// Not enough snapshots have been taken to compute an energy delta.
89    #[error("Not enough measures to compute RAPL counters differences")]
90    NotEnoughSamples,
91
92    #[error("RAPL source mutex poisoned.")]
93    MutexPoisoned,
94}
95
96impl From<std::io::Error> for RaplError {
97    fn from(err: std::io::Error) -> Self {
98        match err.kind() {
99            std::io::ErrorKind::NotFound => RaplError::RaplNotAvailable(err.to_string()),
100            std::io::ErrorKind::PermissionDenied => RaplError::InsufficientPermissions,
101            _ => RaplError::IoError(err),
102        }
103    }
104}
105
106/// Errors related to `/proc/sys/kernel/perf_event_paranoid`.
107#[derive(Debug, Error)]
108pub enum PerfParanoidError {
109    /// The `perf_event_paranoid` file does not exist on this system.
110    #[error("perf_event_paranoid file not found")]
111    NotFound,
112
113    /// The `perf_event_paranoid` file could not be read due to a lack of permissions.
114    #[error("perf_event_paranoid not readable: {0}")]
115    PermissionDenied(String),
116
117    /// The paranoid level is too high to allow unprivileged perf access.
118    #[error(
119        "perf_event_paranoid level is {0}, try setting it to 0 or launch profiler with root rights"
120    )]
121    ParanoidLevelTooHigh(i8),
122
123    /// Generic I/O error while reading the paranoid file.
124    #[error(transparent)]
125    IoError(std::io::Error),
126
127    /// Failed to parse the paranoid level as an integer.
128    #[error("Failed to parse paranoid level")]
129    ParseParanoidLevelError(
130        #[from]
131        #[source]
132        std::num::ParseIntError,
133    ),
134}