-/*
+/*
* app_mem_usage.c
*
- * $Id: get_app_mem_usage.c 50885 2013-07-25 04:40:37Z etxrab $
- *
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* code copied from ekg2, GPL-2 */
-#include "config.h"
+#if defined(__linux__)
+ #define _XOPEN_SOURCE 500
+#endif
-#include <glib.h>
+#include "config.h"
#include <stdio.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
-#endif
+#include <glib.h>
#ifdef _WIN32
#include <windows.h>
#include <psapi.h>
#endif /* _WIN32 */
+#if defined(__linux__)
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <unistd.h>
+# include <fcntl.h>
+#endif
+
#include "app_mem_usage.h"
-gsize
-get_total_mem_used_by_app(void)
-{
-#if defined(_WIN32)
- HANDLE pHandle;
- PROCESS_MEMORY_COUNTERS pmc;
- SIZE_T workingSize = 0;
+#define MAX_COMPONENTS 16
- pHandle = GetCurrentProcess();
+#if defined(_WIN32)
+static gsize
+win32_get_total_mem_used_by_app(void)
+{
+ HANDLE pHandle;
+ PROCESS_MEMORY_COUNTERS pmc;
+ SIZE_T workingSize = 0;
- if (GetProcessMemoryInfo(pHandle, &pmc, sizeof(pmc))){
- workingSize = pmc.WorkingSetSize;
+ pHandle = GetCurrentProcess();
- workingSize = workingSize / 1024;
- }
+ if (GetProcessMemoryInfo(pHandle, &pmc, sizeof(pmc))){
+ workingSize = pmc.WorkingSetSize;
+ }
- CloseHandle(pHandle);
+ CloseHandle(pHandle);
if(workingSize == 0){
return -1;
}else{
return (int)workingSize;
}
-#else
- char *temp, *p = NULL;
- FILE *file = NULL;
- size_t rd = 0;
- int rozmiar = 0, unmres;
- struct utsname sys;
-
- unmres = uname(&sys);
-
- temp = g_strdup_printf("/proc/%d/status", getpid());
-
- if ( (unmres != -1 && !strcmp(sys.sysname, "FreeBSD")) || (file = fopen(temp,"rb")) ) {
- g_free(temp);
- {
-#ifdef __linux__
- char buf[1024];
-
- rd = fread(buf, 1, 1024, file);
- fclose(file);
- if (rd == 0)
- {
- return -1;
- }
- p = strstr(buf, "VmSize");
- if (p) {
- sscanf(p, "VmSize: %d kB", &rozmiar);
- } else {
- return -1;
- }
-#elif __sun
- pstatus_t proc_stat;
- rd = fread(&proc_stat, sizeof(proc_stat), 1, file);
- fclose(file);
- if (rd == 0)
- {
- return -1;
- }
- rozmiar = proc_stat.pr_brksize + proc_stat.pr_stksize;
-#elif __FreeBSD__ /* link with -lkvm */
- char errbuf[_POSIX2_LINE_MAX];
- int nentries = -1;
- struct kinfo_proc *kp;
- static kvm_t *kd;
-
- if (!(kd = kvm_openfiles(NULL /* "/dev/null" */, "/dev/null", NULL, /* O_RDONLY */0, errbuf))) {
- return -1;
- }
- kp = kvm_getprocs(kd, KERN_PROC_PID, getpid(), &nentries);
- if (!kp || nentries != 1) {
- return -1;
- }
-#ifdef HAVE_STRUCT_KINFO_PROC_KI_SIZE
- rozmiar = (u_long) kp->ki_size/1024; /* freebsd5 */
-#else
- rozmiar = kp->kp_eproc.e_vm.vm_map.size/1024; /* freebsd4 */
-#endif /* HAVE_STRUCT_KINFO_PROC_KI_SIZE */
-#else
- /* no /proc mounted */
- return -1;
+}
+
+#define get_total_mem_used_by_app win32_get_total_mem_used_by_app
+
+#endif /* (_WIN32) */
+
+#if defined(__linux__)
+
+static gboolean
+linux_get_memory(gsize *ptotal, gsize *prss)
+{
+ static int fd = -1;
+ static intptr_t pagesize = 0;
+
+ char buf[128];
+ unsigned long total, rss;
+ ssize_t ret;
+
+ if (!pagesize)
+ pagesize = sysconf(_SC_PAGESIZE);
+
+ if (pagesize == -1)
+ return FALSE;
+
+ if (fd < 0) {
+ char path[64];
+
+ g_snprintf(path, sizeof(path), "/proc/%d/statm", getpid());
+
+ fd = open(path, O_RDONLY);
+
+ /* XXX, fallback to some other /proc file ? */
+ }
+
+ if (fd < 0)
+ return FALSE;
+
+ ret = pread(fd, buf, sizeof(buf)-1, 0);
+ if (ret <= 0)
+ return FALSE;
+
+ buf[ret] = '\0';
+
+ if (sscanf(buf, "%lu %lu", &total, &rss) != 2)
+ return FALSE;
+
+ if (ptotal)
+ *ptotal = pagesize * (gsize) total;
+ if (prss)
+ *prss = pagesize * (gsize) rss;
+
+ return TRUE;
+}
+
+static gsize
+linux_get_total_mem_used_by_app(void)
+{
+ gsize total;
+
+ if (!linux_get_memory(&total, NULL))
+ total = 0;
+
+ return total;
+}
+
+static gsize
+linux_get_rss_mem_used_by_app(void)
+{
+ gsize rss;
+
+ if (!linux_get_memory(NULL, &rss))
+ rss = 0;
+
+ return rss;
+}
+
+#define get_total_mem_used_by_app linux_get_total_mem_used_by_app
+
+#define get_rss_mem_used_by_app linux_get_rss_mem_used_by_app
+
#endif
- }
- } else {
- return -1;
+
+/* XXX, BSD 4.3: getrusage() -> ru_ixrss ? */
+
+#ifdef get_total_mem_used_by_app
+static const ws_mem_usage_t total_usage = { "Total", get_total_mem_used_by_app, NULL };
+#endif
+
+#ifdef get_rss_mem_used_by_app
+static const ws_mem_usage_t rss_usage = { "RSS", get_rss_mem_used_by_app, NULL };
+#endif
+
+static const ws_mem_usage_t *memory_components[MAX_COMPONENTS] = {
+#ifdef get_total_mem_used_by_app
+ &total_usage,
+#endif
+#ifdef get_rss_mem_used_by_app
+ &rss_usage,
+#endif
+};
+
+static guint memory_register_num = 0
+#ifdef get_total_mem_used_by_app
+ + 1
+#endif
+#ifdef get_rss_mem_used_by_app
+ + 1
+#endif
+ ;
+
+/* public API */
+
+void
+memory_usage_component_register(const ws_mem_usage_t *component)
+{
+ if (memory_register_num >= MAX_COMPONENTS)
+ return;
+
+ memory_components[memory_register_num++] = component;
+}
+
+const char *
+memory_usage_get(guint index, gsize *value)
+{
+ if (index >= memory_register_num)
+ return NULL;
+
+ if (value)
+ *value = memory_components[index]->fetch();
+
+ return memory_components[index]->name;
+}
+
+void
+memory_usage_gc(void)
+{
+ guint i;
+
+ for (i = 0; i < memory_register_num; i++) {
+ if (memory_components[i]->gc)
+ memory_components[i]->gc();
}
- return rozmiar;
-#endif /* (_WIN32) */
}
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */