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
/// Gathered information about a thread, returned by [super::KernelPID::stack_stats()].
///
/// All accessors are unconditional, because the StackStats can't be obtained without develhelp in
/// the first place.
#[derive(Debug)]
#[non_exhaustive]
pub struct StackStats {
    pub(crate) start: *mut i8,
    pub(crate) size: usize,
    pub(crate) free: usize,
}

impl StackStats {
    pub fn start(&self) -> *mut i8 {
        self.start
    }

    pub fn size(&self) -> usize {
        self.size
    }

    pub fn end(&self) -> *mut i8 {
        // This is the last legal pointer to construct on this ... last-plus-one rule.
        unsafe { self.start.offset(self.size as isize) }
    }

    pub fn free(&self) -> usize {
        self.free
    }

    pub fn used(&self) -> usize {
        self.size - self.free
    }
}

#[non_exhaustive]
#[derive(Debug, Copy, Clone)]
pub enum StackStatsError {
    /// Requested PID does not correspond to a thread
    NoSuchThread,
    /// Details on the stack are unavailable because develhelp is disabled
    InformationUnavailable,
}

impl From<super::NoSuchThread> for StackStatsError {
    fn from(_: super::NoSuchThread) -> Self {
        StackStatsError::NoSuchThread
    }
}