1*0d9b7d92SLoGin use num_traits::FromPrimitive; 2*0d9b7d92SLoGin 3be8cdf4bSLoGin use crate::{syscall::SystemError, time::TimeSpec}; 4be8cdf4bSLoGin 5be8cdf4bSLoGin use super::ProcessControlBlock; 6be8cdf4bSLoGin 7be8cdf4bSLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] 8be8cdf4bSLoGin #[repr(C)] 9be8cdf4bSLoGin pub struct RUsage { 10be8cdf4bSLoGin /// User time used 11be8cdf4bSLoGin pub ru_utime: TimeSpec, 12be8cdf4bSLoGin /// System time used 13be8cdf4bSLoGin pub ru_stime: TimeSpec, 14be8cdf4bSLoGin 15be8cdf4bSLoGin // 以下是linux的rusage结构体扩展 16be8cdf4bSLoGin /// Maximum resident set size 17be8cdf4bSLoGin pub ru_maxrss: usize, 18be8cdf4bSLoGin /// Integral shared memory size 19be8cdf4bSLoGin pub ru_ixrss: usize, 20be8cdf4bSLoGin /// Integral unshared data size 21be8cdf4bSLoGin pub ru_idrss: usize, 22be8cdf4bSLoGin /// Integral unshared stack size 23be8cdf4bSLoGin pub ru_isrss: usize, 24be8cdf4bSLoGin /// Page reclaims (soft page faults) 25be8cdf4bSLoGin pub ru_minflt: usize, 26be8cdf4bSLoGin /// Page faults (hard page faults) 27be8cdf4bSLoGin pub ru_majflt: usize, 28be8cdf4bSLoGin /// Swaps 29be8cdf4bSLoGin pub ru_nswap: usize, 30be8cdf4bSLoGin /// Block input operations 31be8cdf4bSLoGin pub ru_inblock: usize, 32be8cdf4bSLoGin /// Block output operations 33be8cdf4bSLoGin pub ru_oublock: usize, 34be8cdf4bSLoGin /// IPC messages sent 35be8cdf4bSLoGin pub ru_msgsnd: usize, 36be8cdf4bSLoGin /// IPC messages received 37be8cdf4bSLoGin pub ru_msgrcv: usize, 38be8cdf4bSLoGin /// Signals received 39be8cdf4bSLoGin pub ru_nsignals: usize, 40be8cdf4bSLoGin /// Voluntary context switches 41be8cdf4bSLoGin pub ru_nvcsw: usize, 42be8cdf4bSLoGin /// Involuntary context switches 43be8cdf4bSLoGin pub ru_nivcsw: usize, 44be8cdf4bSLoGin } 45be8cdf4bSLoGin 46be8cdf4bSLoGin /// 47be8cdf4bSLoGin /// Definition of struct rusage taken from BSD 4.3 Reno 48be8cdf4bSLoGin /// 49be8cdf4bSLoGin /// We don't support all of these yet, but we might as well have them.... 50be8cdf4bSLoGin /// Otherwise, each time we add new items, programs which depend on this 51be8cdf4bSLoGin /// structure will lose. This reduces the chances of that happening. 52be8cdf4bSLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq)] 53be8cdf4bSLoGin pub enum RUsageWho { 54be8cdf4bSLoGin RUsageSelf = 0, 55be8cdf4bSLoGin RUsageChildren = -1, 56be8cdf4bSLoGin /// sys_wait4() uses this 57be8cdf4bSLoGin RUsageBoth = -2, 58be8cdf4bSLoGin /// only the calling thread 59be8cdf4bSLoGin RusageThread = 1, 60be8cdf4bSLoGin } 61be8cdf4bSLoGin 62be8cdf4bSLoGin impl TryFrom<i32> for RUsageWho { 63be8cdf4bSLoGin type Error = SystemError; 64be8cdf4bSLoGin 65be8cdf4bSLoGin fn try_from(value: i32) -> Result<Self, Self::Error> { 66be8cdf4bSLoGin match value { 67be8cdf4bSLoGin 0 => Ok(RUsageWho::RUsageSelf), 68be8cdf4bSLoGin -1 => Ok(RUsageWho::RUsageChildren), 69be8cdf4bSLoGin -2 => Ok(RUsageWho::RUsageBoth), 70be8cdf4bSLoGin 1 => Ok(RUsageWho::RusageThread), 71be8cdf4bSLoGin _ => Err(SystemError::EINVAL), 72be8cdf4bSLoGin } 73be8cdf4bSLoGin } 74be8cdf4bSLoGin } 75be8cdf4bSLoGin 76*0d9b7d92SLoGin /// Resource limit 77*0d9b7d92SLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq)] 78*0d9b7d92SLoGin #[repr(C)] 79*0d9b7d92SLoGin pub struct RLimit64 { 80*0d9b7d92SLoGin /// The current (soft) limit 81*0d9b7d92SLoGin pub rlim_cur: u64, 82*0d9b7d92SLoGin /// The hard limit 83*0d9b7d92SLoGin pub rlim_max: u64, 84*0d9b7d92SLoGin } 85*0d9b7d92SLoGin 86*0d9b7d92SLoGin /// Resource limit IDs 87*0d9b7d92SLoGin /// 88*0d9b7d92SLoGin /// ## Note 89*0d9b7d92SLoGin /// 90*0d9b7d92SLoGin /// 有些架构中,这里[5,9]的值是不同的,我们将来需要在这里增加条件编译 91*0d9b7d92SLoGin #[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive)] 92*0d9b7d92SLoGin pub enum RLimitID { 93*0d9b7d92SLoGin /// CPU time in sec 94*0d9b7d92SLoGin Cpu = 0, 95*0d9b7d92SLoGin /// Maximum file size 96*0d9b7d92SLoGin Fsize = 1, 97*0d9b7d92SLoGin /// Max data size 98*0d9b7d92SLoGin Data = 2, 99*0d9b7d92SLoGin /// Max stack size 100*0d9b7d92SLoGin Stack = 3, 101*0d9b7d92SLoGin /// Max core file size 102*0d9b7d92SLoGin Core = 4, 103*0d9b7d92SLoGin /// Max resident set size 104*0d9b7d92SLoGin Rss = 5, 105*0d9b7d92SLoGin 106*0d9b7d92SLoGin /// Max number of processes 107*0d9b7d92SLoGin Nproc = 6, 108*0d9b7d92SLoGin /// Max number of open files 109*0d9b7d92SLoGin Nofile = 7, 110*0d9b7d92SLoGin /// Max locked-in-memory address space 111*0d9b7d92SLoGin Memlock = 8, 112*0d9b7d92SLoGin /// Address space limit 113*0d9b7d92SLoGin As = 9, 114*0d9b7d92SLoGin /// Max number of file locks held 115*0d9b7d92SLoGin Locks = 10, 116*0d9b7d92SLoGin 117*0d9b7d92SLoGin /// Max number of pending signals 118*0d9b7d92SLoGin Sigpending = 11, 119*0d9b7d92SLoGin /// Max bytes in POSIX mqueues 120*0d9b7d92SLoGin Msgqueue = 12, 121*0d9b7d92SLoGin /// Max nice prio allowed to raise to 122*0d9b7d92SLoGin /// 0-39 for nice level 19 .. -20 123*0d9b7d92SLoGin Nice = 13, 124*0d9b7d92SLoGin /// Max realtime priority 125*0d9b7d92SLoGin Rtprio = 14, 126*0d9b7d92SLoGin /// Timeout for RT tasks in us 127*0d9b7d92SLoGin Rttime = 15, 128*0d9b7d92SLoGin Nlimits = 16, 129*0d9b7d92SLoGin } 130*0d9b7d92SLoGin 131*0d9b7d92SLoGin impl TryFrom<usize> for RLimitID { 132*0d9b7d92SLoGin type Error = SystemError; 133*0d9b7d92SLoGin 134*0d9b7d92SLoGin fn try_from(value: usize) -> Result<Self, Self::Error> { 135*0d9b7d92SLoGin <Self as FromPrimitive>::from_usize(value).ok_or(SystemError::EINVAL) 136*0d9b7d92SLoGin } 137*0d9b7d92SLoGin } 138*0d9b7d92SLoGin 139be8cdf4bSLoGin impl ProcessControlBlock { 140be8cdf4bSLoGin /// 获取进程资源使用情况 141be8cdf4bSLoGin /// 142be8cdf4bSLoGin /// ## TODO 143be8cdf4bSLoGin /// 144be8cdf4bSLoGin /// 当前函数尚未实现,只是返回了一个默认的RUsage结构体 145be8cdf4bSLoGin pub fn get_rusage(&self, _who: RUsageWho) -> Option<RUsage> { 146be8cdf4bSLoGin let rusage = RUsage::default(); 147be8cdf4bSLoGin 148be8cdf4bSLoGin Some(rusage) 149be8cdf4bSLoGin } 150be8cdf4bSLoGin } 151