preemptive_threads/
errors.rs

1//! Comprehensive error handling for the threading system.
2//!
3//! This module provides detailed error types for all threading operations,
4//! enabling proper error handling and debugging throughout the system.
5
6use core::fmt;
7extern crate alloc;
8use alloc::string::String;
9
10/// Result type for threading operations.
11pub type ThreadResult<T> = Result<T, ThreadError>;
12
13/// Comprehensive error type for all threading operations.
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum ThreadError {
16    /// Thread spawning errors
17    Spawn(SpawnError),
18    /// Thread joining errors  
19    Join(JoinError),
20    /// Scheduling errors
21    Schedule(ScheduleError),
22    /// Memory allocation errors
23    Memory(MemoryError),
24    /// Timer and timing errors
25    Timer(TimerError),
26    /// Architecture-specific errors
27    Arch(ArchError),
28    /// Thread-local storage errors
29    Tls(TlsError),
30    /// Permission and security errors
31    Permission(PermissionError),
32    /// Resource limit errors
33    Resource(ResourceError),
34    /// Invalid operation errors
35    InvalidOperation(InvalidOperationError),
36}
37
38/// Errors that can occur during thread spawning.
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub enum SpawnError {
41    /// System is not initialized
42    NotInitialized,
43    /// Out of memory for stack allocation
44    OutOfMemory,
45    /// Maximum number of threads reached
46    TooManyThreads,
47    /// Invalid stack size specified
48    InvalidStackSize(usize),
49    /// Invalid priority specified
50    InvalidPriority(u8),
51    /// Invalid CPU affinity specified
52    InvalidAffinity(u64),
53    /// Thread name is invalid or too long
54    InvalidName(String),
55    /// Architecture does not support requested feature
56    UnsupportedFeature(String),
57    /// Scheduler rejected the thread
58    SchedulerRejected,
59}
60
61/// Errors that can occur during thread joining.
62#[derive(Debug, Clone, PartialEq, Eq)]
63pub enum JoinError {
64    /// Thread has already been joined
65    AlreadyJoined,
66    /// Thread panicked during execution
67    ThreadPanicked,
68    /// Thread was terminated abnormally
69    Terminated,
70    /// Join operation timed out
71    Timeout,
72    /// Thread is still running (for try_join)
73    StillRunning,
74    /// Invalid thread handle
75    InvalidHandle,
76}
77
78/// Errors related to scheduling operations.
79#[derive(Debug, Clone, PartialEq, Eq)]
80pub enum ScheduleError {
81    /// No schedulable threads available
82    NoThreadsAvailable,
83    /// Scheduler is in an invalid state
84    InvalidState,
85    /// CPU does not exist or is offline
86    InvalidCpu(usize),
87    /// Priority change not allowed
88    PriorityChangeNotAllowed,
89    /// Scheduler queue is full
90    QueueFull,
91    /// Preemption is disabled
92    PreemptionDisabled,
93}
94
95/// Memory-related errors.
96#[derive(Debug, Clone, PartialEq, Eq)]
97pub enum MemoryError {
98    /// Out of memory
99    OutOfMemory,
100    /// Stack overflow detected
101    StackOverflow,
102    /// Stack underflow detected
103    StackUnderflow,
104    /// Invalid memory address
105    InvalidAddress(usize),
106    /// Memory alignment error
107    AlignmentError,
108    /// Memory pool exhausted
109    PoolExhausted,
110    /// Invalid memory layout
111    InvalidLayout,
112}
113
114/// Timer and timing related errors.
115#[derive(Debug, Clone, PartialEq, Eq)]
116pub enum TimerError {
117    /// Timer not initialized
118    NotInitialized,
119    /// Timer already running
120    AlreadyRunning,
121    /// Timer not running
122    NotRunning,
123    /// Invalid timer frequency
124    InvalidFrequency(u32),
125    /// Timer hardware not available
126    HardwareNotAvailable,
127    /// Invalid timer configuration
128    InvalidConfig,
129}
130
131/// Architecture-specific errors.
132#[derive(Debug, Clone, PartialEq, Eq)]
133pub enum ArchError {
134    /// Unsupported architecture
135    UnsupportedArchitecture,
136    /// Context switch failed
137    ContextSwitchFailed,
138    /// Invalid CPU state
139    InvalidCpuState,
140    /// Interrupt handling error
141    InterruptError,
142    /// FPU operation error
143    FpuError,
144    /// Invalid instruction
145    InvalidInstruction,
146}
147
148/// Thread-local storage errors.
149#[derive(Debug, Clone, PartialEq, Eq)]
150pub enum TlsError {
151    /// TLS key not found
152    KeyNotFound,
153    /// TLS storage exhausted
154    StorageExhausted,
155    /// Invalid TLS key
156    InvalidKey,
157    /// TLS data corrupted
158    DataCorrupted,
159    /// TLS not supported
160    NotSupported,
161}
162
163/// Permission and security errors.
164#[derive(Debug, Clone, PartialEq, Eq)]
165pub enum PermissionError {
166    /// Operation not permitted
167    NotPermitted,
168    /// Access denied
169    AccessDenied,
170    /// Insufficient privileges
171    InsufficientPrivileges,
172    /// Security policy violation
173    SecurityViolation,
174    /// Operation would compromise security
175    SecurityRisk,
176}
177
178/// Resource limit errors.
179#[derive(Debug, Clone, PartialEq, Eq)]
180pub enum ResourceError {
181    /// Maximum threads per process exceeded
182    MaxThreadsPerProcess,
183    /// Maximum threads per user exceeded
184    MaxThreadsPerUser,
185    /// Maximum memory usage exceeded
186    MaxMemoryUsage,
187    /// Maximum CPU time exceeded
188    MaxCpuTime,
189    /// Maximum file descriptors exceeded
190    MaxFileDescriptors,
191    /// Resource temporarily unavailable
192    ResourceUnavailable,
193}
194
195/// Invalid operation errors.
196#[derive(Debug, Clone, PartialEq, Eq)]
197pub enum InvalidOperationError {
198    /// Operation called on wrong thread
199    WrongThread,
200    /// Operation called in wrong state
201    WrongState,
202    /// Invalid parameter provided
203    InvalidParameter(String),
204    /// Operation not supported in current context
205    NotSupported,
206    /// Deadlock would occur
207    WouldDeadlock,
208    /// Operation already in progress
209    AlreadyInProgress,
210}
211
212// Display implementations for user-friendly error messages
213
214impl fmt::Display for ThreadError {
215    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216        match self {
217            ThreadError::Spawn(e) => write!(f, "Thread spawn error: {}", e),
218            ThreadError::Join(e) => write!(f, "Thread join error: {}", e),
219            ThreadError::Schedule(e) => write!(f, "Scheduling error: {}", e),
220            ThreadError::Memory(e) => write!(f, "Memory error: {}", e),
221            ThreadError::Timer(e) => write!(f, "Timer error: {}", e),
222            ThreadError::Arch(e) => write!(f, "Architecture error: {}", e),
223            ThreadError::Tls(e) => write!(f, "Thread-local storage error: {}", e),
224            ThreadError::Permission(e) => write!(f, "Permission error: {}", e),
225            ThreadError::Resource(e) => write!(f, "Resource error: {}", e),
226            ThreadError::InvalidOperation(e) => write!(f, "Invalid operation: {}", e),
227        }
228    }
229}
230
231impl fmt::Display for SpawnError {
232    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233        match self {
234            SpawnError::NotInitialized => write!(f, "Threading system not initialized"),
235            SpawnError::OutOfMemory => write!(f, "Out of memory for thread creation"),
236            SpawnError::TooManyThreads => write!(f, "Maximum number of threads reached"),
237            SpawnError::InvalidStackSize(size) => write!(f, "Invalid stack size: {}", size),
238            SpawnError::InvalidPriority(prio) => write!(f, "Invalid priority: {}", prio),
239            SpawnError::InvalidAffinity(affinity) => write!(f, "Invalid CPU affinity: {:#x}", affinity),
240            SpawnError::InvalidName(name) => write!(f, "Invalid thread name: {}", name),
241            SpawnError::UnsupportedFeature(feature) => write!(f, "Unsupported feature: {}", feature),
242            SpawnError::SchedulerRejected => write!(f, "Scheduler rejected thread creation"),
243        }
244    }
245}
246
247impl fmt::Display for JoinError {
248    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249        match self {
250            JoinError::AlreadyJoined => write!(f, "Thread has already been joined"),
251            JoinError::ThreadPanicked => write!(f, "Thread panicked during execution"),
252            JoinError::Terminated => write!(f, "Thread was terminated abnormally"),
253            JoinError::Timeout => write!(f, "Join operation timed out"),
254            JoinError::StillRunning => write!(f, "Thread is still running"),
255            JoinError::InvalidHandle => write!(f, "Invalid thread handle"),
256        }
257    }
258}
259
260impl fmt::Display for ScheduleError {
261    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
262        match self {
263            ScheduleError::NoThreadsAvailable => write!(f, "No schedulable threads available"),
264            ScheduleError::InvalidState => write!(f, "Scheduler is in an invalid state"),
265            ScheduleError::InvalidCpu(cpu) => write!(f, "Invalid CPU ID: {}", cpu),
266            ScheduleError::PriorityChangeNotAllowed => write!(f, "Priority change not allowed"),
267            ScheduleError::QueueFull => write!(f, "Scheduler queue is full"),
268            ScheduleError::PreemptionDisabled => write!(f, "Preemption is disabled"),
269        }
270    }
271}
272
273impl fmt::Display for MemoryError {
274    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
275        match self {
276            MemoryError::OutOfMemory => write!(f, "Out of memory"),
277            MemoryError::StackOverflow => write!(f, "Stack overflow detected"),
278            MemoryError::StackUnderflow => write!(f, "Stack underflow detected"),
279            MemoryError::InvalidAddress(addr) => write!(f, "Invalid memory address: {:#x}", addr),
280            MemoryError::AlignmentError => write!(f, "Memory alignment error"),
281            MemoryError::PoolExhausted => write!(f, "Memory pool exhausted"),
282            MemoryError::InvalidLayout => write!(f, "Invalid memory layout"),
283        }
284    }
285}
286
287impl fmt::Display for TimerError {
288    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
289        match self {
290            TimerError::NotInitialized => write!(f, "Timer not initialized"),
291            TimerError::AlreadyRunning => write!(f, "Timer already running"),
292            TimerError::NotRunning => write!(f, "Timer not running"),
293            TimerError::InvalidFrequency(freq) => write!(f, "Invalid timer frequency: {} Hz", freq),
294            TimerError::HardwareNotAvailable => write!(f, "Timer hardware not available"),
295            TimerError::InvalidConfig => write!(f, "Invalid timer configuration"),
296        }
297    }
298}
299
300impl fmt::Display for ArchError {
301    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
302        match self {
303            ArchError::UnsupportedArchitecture => write!(f, "Unsupported architecture"),
304            ArchError::ContextSwitchFailed => write!(f, "Context switch failed"),
305            ArchError::InvalidCpuState => write!(f, "Invalid CPU state"),
306            ArchError::InterruptError => write!(f, "Interrupt handling error"),
307            ArchError::FpuError => write!(f, "FPU operation error"),
308            ArchError::InvalidInstruction => write!(f, "Invalid instruction"),
309        }
310    }
311}
312
313impl fmt::Display for TlsError {
314    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
315        match self {
316            TlsError::KeyNotFound => write!(f, "TLS key not found"),
317            TlsError::StorageExhausted => write!(f, "TLS storage exhausted"),
318            TlsError::InvalidKey => write!(f, "Invalid TLS key"),
319            TlsError::DataCorrupted => write!(f, "TLS data corrupted"),
320            TlsError::NotSupported => write!(f, "TLS not supported"),
321        }
322    }
323}
324
325impl fmt::Display for PermissionError {
326    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
327        match self {
328            PermissionError::NotPermitted => write!(f, "Operation not permitted"),
329            PermissionError::AccessDenied => write!(f, "Access denied"),
330            PermissionError::InsufficientPrivileges => write!(f, "Insufficient privileges"),
331            PermissionError::SecurityViolation => write!(f, "Security policy violation"),
332            PermissionError::SecurityRisk => write!(f, "Operation would compromise security"),
333        }
334    }
335}
336
337impl fmt::Display for ResourceError {
338    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
339        match self {
340            ResourceError::MaxThreadsPerProcess => write!(f, "Maximum threads per process exceeded"),
341            ResourceError::MaxThreadsPerUser => write!(f, "Maximum threads per user exceeded"),
342            ResourceError::MaxMemoryUsage => write!(f, "Maximum memory usage exceeded"),
343            ResourceError::MaxCpuTime => write!(f, "Maximum CPU time exceeded"),
344            ResourceError::MaxFileDescriptors => write!(f, "Maximum file descriptors exceeded"),
345            ResourceError::ResourceUnavailable => write!(f, "Resource temporarily unavailable"),
346        }
347    }
348}
349
350impl fmt::Display for InvalidOperationError {
351    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352        match self {
353            InvalidOperationError::WrongThread => write!(f, "Operation called on wrong thread"),
354            InvalidOperationError::WrongState => write!(f, "Operation called in wrong state"),
355            InvalidOperationError::InvalidParameter(param) => write!(f, "Invalid parameter: {}", param),
356            InvalidOperationError::NotSupported => write!(f, "Operation not supported in current context"),
357            InvalidOperationError::WouldDeadlock => write!(f, "Operation would cause deadlock"),
358            InvalidOperationError::AlreadyInProgress => write!(f, "Operation already in progress"),
359        }
360    }
361}
362
363// Conversion implementations for ergonomic error handling
364
365impl From<SpawnError> for ThreadError {
366    fn from(error: SpawnError) -> Self {
367        ThreadError::Spawn(error)
368    }
369}
370
371impl From<JoinError> for ThreadError {
372    fn from(error: JoinError) -> Self {
373        ThreadError::Join(error)
374    }
375}
376
377impl From<ScheduleError> for ThreadError {
378    fn from(error: ScheduleError) -> Self {
379        ThreadError::Schedule(error)
380    }
381}
382
383impl From<MemoryError> for ThreadError {
384    fn from(error: MemoryError) -> Self {
385        ThreadError::Memory(error)
386    }
387}
388
389impl From<TimerError> for ThreadError {
390    fn from(error: TimerError) -> Self {
391        ThreadError::Timer(error)
392    }
393}
394
395impl From<ArchError> for ThreadError {
396    fn from(error: ArchError) -> Self {
397        ThreadError::Arch(error)
398    }
399}
400
401impl From<TlsError> for ThreadError {
402    fn from(error: TlsError) -> Self {
403        ThreadError::Tls(error)
404    }
405}
406
407impl From<PermissionError> for ThreadError {
408    fn from(error: PermissionError) -> Self {
409        ThreadError::Permission(error)
410    }
411}
412
413impl From<ResourceError> for ThreadError {
414    fn from(error: ResourceError) -> Self {
415        ThreadError::Resource(error)
416    }
417}
418
419impl From<InvalidOperationError> for ThreadError {
420    fn from(error: InvalidOperationError) -> Self {
421        ThreadError::InvalidOperation(error)
422    }
423}
424
425// Convert from old SpawnError to new system
426impl From<crate::kernel::SpawnError> for SpawnError {
427    fn from(error: crate::kernel::SpawnError) -> Self {
428        match error {
429            crate::kernel::SpawnError::NotInitialized => SpawnError::NotInitialized,
430            crate::kernel::SpawnError::OutOfMemory => SpawnError::OutOfMemory,
431            crate::kernel::SpawnError::TooManyThreads => SpawnError::TooManyThreads,
432            crate::kernel::SpawnError::InvalidStackSize => SpawnError::InvalidStackSize(0),
433        }
434    }
435}
436
437impl From<crate::time::TimerError> for TimerError {
438    fn from(error: crate::time::TimerError) -> Self {
439        match error {
440            crate::time::TimerError::NotInitialized => TimerError::NotInitialized,
441            crate::time::TimerError::AlreadyRunning => TimerError::AlreadyRunning,
442            crate::time::TimerError::NotRunning => TimerError::NotRunning,
443            crate::time::TimerError::UnsupportedFrequency => TimerError::InvalidFrequency(0),
444            crate::time::TimerError::InvalidConfig => TimerError::InvalidConfig,
445            crate::time::TimerError::NotAvailable => TimerError::HardwareNotAvailable,
446        }
447    }
448}
449
450// Convenience constructors for common error patterns
451impl ThreadError {
452    /// Create a memory error.
453    pub fn MemoryError() -> Self {
454        ThreadError::Memory(MemoryError::OutOfMemory)
455    }
456    
457    /// Create a resource exhaustion error.
458    pub fn ResourceExhaustion() -> Self {
459        ThreadError::Resource(ResourceError::ResourceUnavailable)
460    }
461    
462    /// Create an invalid state error.
463    pub fn InvalidState() -> Self {
464        ThreadError::Schedule(ScheduleError::InvalidState)
465    }
466    
467    /// Create a permission denied error.
468    pub fn PermissionDenied() -> Self {
469        ThreadError::Permission(PermissionError::AccessDenied)
470    }
471    
472    /// Create an unsupported operation error.
473    pub fn UnsupportedOperation(msg: String) -> Self {
474        ThreadError::InvalidOperation(InvalidOperationError::InvalidParameter(msg))
475    }
476    
477    /// Create a generic "Other" error with a message.  
478    pub fn Other(msg: String) -> Self {
479        ThreadError::InvalidOperation(InvalidOperationError::InvalidParameter(msg))
480    }
481}