| 213 | }; |
| 214 | |
| 215 | static bool read_proc_memory(ProcMemory &m) { |
| 216 | m = ProcMemory(); |
| 217 | errno = 0; |
| 218 | #if defined(OS_LINUX) |
| 219 | butil::ScopedFILE fp("/proc/self/statm", "r"); |
| 220 | if (NULL == fp) { |
| 221 | PLOG_ONCE(WARNING) << "Fail to open /proc/self/statm"; |
| 222 | return false; |
| 223 | } |
| 224 | if (fscanf(fp, "%ld %ld %ld %ld %ld %ld %ld", |
| 225 | &m.size, &m.resident, &m.share, |
| 226 | &m.trs, &m.lrs, &m.drs, &m.dt) != 7) { |
| 227 | PLOG(WARNING) << "Fail to fscanf /proc/self/statm"; |
| 228 | return false; |
| 229 | } |
| 230 | return true; |
| 231 | #elif defined(OS_MACOSX) |
| 232 | // TODO(zhujiashun): get remaining memory info in MacOS. |
| 233 | memset(&m, 0, sizeof(m)); |
| 234 | static pid_t pid = getpid(); |
| 235 | static int64_t pagesize = getpagesize(); |
| 236 | std::ostringstream oss; |
| 237 | char cmdbuf[128]; |
| 238 | snprintf(cmdbuf, sizeof(cmdbuf), "ps -p %ld -o rss=,vsz=", (long)pid); |
| 239 | if (butil::read_command_output(oss, cmdbuf) != 0) { |
| 240 | LOG(ERROR) << "Fail to read memory state"; |
| 241 | return false; |
| 242 | } |
| 243 | const std::string& result = oss.str(); |
| 244 | if (sscanf(result.c_str(), "%ld %ld", &m.resident, &m.size) != 2) { |
| 245 | PLOG(WARNING) << "Fail to sscanf"; |
| 246 | return false; |
| 247 | } |
| 248 | // resident and size in Kbytes |
| 249 | m.resident = m.resident * 1024 / pagesize; |
| 250 | m.size = m.size * 1024 / pagesize; |
| 251 | return true; |
| 252 | #else |
| 253 | return false; |
| 254 | #endif |
| 255 | } |
| 256 | |
| 257 | class ProcMemoryReader { |
| 258 | public: |
no test coverage detected