| 97 | |
| 98 | namespace NMemInfo { |
| 99 | TMemInfo GetMemInfo(pid_t pid) { |
| 100 | TMemInfo result; |
| 101 | |
| 102 | #if defined(_unix_) |
| 103 | |
| 104 | #if defined(_linux_) || defined(_freebsd_) || defined(_cygwin_) |
| 105 | const ui32 pagesize = NSystemInfo::GetPageSize(); |
| 106 | #endif |
| 107 | |
| 108 | #if defined(_linux_) || defined(_cygwin_) |
| 109 | TString path; |
| 110 | if (!pid) { |
| 111 | path = "/proc/self/statm"; |
| 112 | } else { |
| 113 | path = TStringBuilder() << TStringBuf("/proc/") << pid << TStringBuf("/statm"); |
| 114 | } |
| 115 | const TString stats = TUnbufferedFileInput(path).ReadAll(); |
| 116 | |
| 117 | TStringBuf statsiter(stats); |
| 118 | |
| 119 | result.VMS = FromString<ui64>(statsiter.NextTok(' ')) * pagesize; |
| 120 | result.RSS = FromString<ui64>(statsiter.NextTok(' ')) * pagesize; |
| 121 | |
| 122 | #if defined(_cygwin_) |
| 123 | // cygwin not very accurate |
| 124 | result.VMS = Max(result.VMS, result.RSS); |
| 125 | #endif |
| 126 | #elif defined(_freebsd_) |
| 127 | if (pid == 0) { |
| 128 | pid = GetPID(); |
| 129 | } |
| 130 | int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; |
| 131 | size_t size = sizeof(struct kinfo_proc); |
| 132 | |
| 133 | struct kinfo_proc proc; |
| 134 | Zero(proc); |
| 135 | |
| 136 | errno = 0; |
| 137 | if (sysctl((int*)mib, 4, &proc, &size, nullptr, 0) == -1) { |
| 138 | int err = errno; |
| 139 | TString errtxt = LastSystemErrorText(err); |
| 140 | ythrow yexception() << "sysctl({CTL_KERN,KERN_PROC,KERN_PROC_PID,pid},4,proc,&size,NULL,0) returned -1, errno: " << err << " (" << errtxt << ")" << Endl; |
| 141 | } |
| 142 | |
| 143 | result.VMS = proc.ki_size; |
| 144 | result.RSS = proc.ki_rssize * pagesize; |
| 145 | #elif defined(_darwin_) && !defined(_arm_) && !defined(__IOS__) |
| 146 | if (!pid) { |
| 147 | pid = getpid(); |
| 148 | } |
| 149 | struct proc_taskinfo taskInfo; |
| 150 | const int r = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &taskInfo, sizeof(taskInfo)); |
| 151 | |
| 152 | if (r != sizeof(taskInfo)) { |
| 153 | int err = errno; |
| 154 | TString errtxt = LastSystemErrorText(err); |
| 155 | ythrow yexception() << "proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &taskInfo, sizeof(taskInfo)) returned " << r << ", errno: " << err << " (" << errtxt << ")" << Endl; |
| 156 | } |