/** * XMPP - libpurple transport * * Copyright (C) 2009, Jan Kaluza * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "transport/memoryusage.h" #include #include #include #include #include #ifndef WIN32 #include #endif #ifdef BSD #include #include #include #include #include #endif namespace Transport { #ifndef WIN32 #ifdef BSD void process_mem_usage(double& vm_usage, double& resident_set) { int mib[4]; size_t size; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = getpid(); struct kinfo_proc proc; size = sizeof(struct kinfo_proc); if (sysctl((int*)mib, 4, &proc, &size, NULL, 0) == -1) { vm_usage = 0; resident_set = 0; return; } // sysctl stores 0 in the size if we can't find the process information. // Set errno to ESRCH which will be translated in NoSuchProcess later on. if (size == 0) { vm_usage = 0; resident_set = 0; return; } int pagesize,cnt; size = sizeof(pagesize); sysctlbyname("hw.pagesize", &pagesize, &size, NULL, 0); resident_set = (double) (proc.ki_rssize * pagesize / 1024); vm_usage = (double) proc.ki_size; } #else /* BSD */ void process_mem_usage(double& shared, double& resident_set) { using std::ios_base; using std::ifstream; using std::string; shared = 0.0; resident_set = 0.0; // 'file' stat seems to give the most reliable results // ifstream stat_stream("/proc/self/statm",ios_base::in); if (!stat_stream.is_open()) { shared = 0; resident_set = 0; return; } // dummy vars for leading entries in stat that we don't care about // string pid, comm, state, ppid, pgrp, session, tty_nr; string tpgid, flags, minflt, cminflt, majflt, cmajflt; string utime, stime, cutime, cstime, priority, nice; string O, itrealvalue, starttime; // the two fields we want // unsigned long shared_; long rss; stat_stream >> O >> rss >> shared_; // don't care about the rest long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages shared = shared_ * page_size_kb; resident_set = rss * page_size_kb; } #endif /* else BSD */ #endif /* WIN32 */ }