Fixed FieldInfo documentation.
[metze/wireshark/wip.git] / epan / app_mem_usage.c
1 /* 
2  * app_mem_usage.c
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #if defined(__linux__)
26  #define _XOPEN_SOURCE 500
27 #endif
28
29 #include "config.h"
30
31 #include <stdio.h>
32
33 #include <glib.h>
34
35 #ifdef _WIN32
36 #include <windows.h>
37 #include <psapi.h>
38 #endif /*  _WIN32 */
39
40 #if defined(__linux__)
41 # include <sys/types.h>
42 # include <sys/stat.h>
43 # include <unistd.h>
44 # include <fcntl.h>
45 #endif
46
47 #include "app_mem_usage.h"
48
49 #define MAX_COMPONENTS 16
50
51 #if defined(_WIN32)
52 static gsize
53 win32_get_total_mem_used_by_app(void)
54 {
55    HANDLE pHandle;
56    PROCESS_MEMORY_COUNTERS pmc;
57    SIZE_T workingSize = 0;
58
59    pHandle = GetCurrentProcess();
60
61    if (GetProcessMemoryInfo(pHandle, &pmc, sizeof(pmc))){
62       workingSize = pmc.WorkingSetSize;
63     }
64
65     CloseHandle(pHandle);
66
67         if(workingSize == 0){
68                 return -1;
69         }else{
70                 return (int)workingSize;
71         }
72 }
73
74 #define get_total_mem_used_by_app win32_get_total_mem_used_by_app
75
76 #endif /* (_WIN32) */
77
78 #if defined(__linux__)
79
80 static gboolean
81 linux_get_memory(gsize *ptotal, gsize *prss)
82 {
83         static int fd = -1;
84         static intptr_t pagesize = 0;
85
86         char buf[128];
87         unsigned long total, rss;
88         ssize_t ret;
89
90         if (!pagesize)
91                 pagesize = sysconf(_SC_PAGESIZE);
92
93         if (pagesize == -1)
94                 return FALSE;
95
96         if (fd < 0) {
97                 char path[64];
98
99                 g_snprintf(path, sizeof(path), "/proc/%d/statm", getpid());
100
101                 fd = open(path, O_RDONLY);
102
103                 /* XXX, fallback to some other /proc file ? */
104         }
105
106         if (fd < 0)
107                 return FALSE;
108
109         ret = pread(fd, buf, sizeof(buf)-1, 0);
110         if (ret <= 0)
111                 return FALSE;
112
113         buf[ret] = '\0';
114
115         if (sscanf(buf, "%lu %lu", &total, &rss) != 2)
116                 return FALSE;
117
118         if (ptotal)
119                 *ptotal = pagesize * (gsize) total;
120         if (prss)
121                 *prss = pagesize * (gsize) rss;
122
123         return TRUE;
124 }
125
126 static gsize
127 linux_get_total_mem_used_by_app(void)
128 {
129         gsize total;
130
131         if (!linux_get_memory(&total, NULL))
132                 total = 0;
133
134         return total;
135 }
136
137 static gsize
138 linux_get_rss_mem_used_by_app(void)
139 {
140         gsize rss;
141
142         if (!linux_get_memory(NULL, &rss))
143                 rss = 0;
144
145         return rss;
146 }
147
148 #define get_total_mem_used_by_app linux_get_total_mem_used_by_app
149
150 #define get_rss_mem_used_by_app linux_get_rss_mem_used_by_app
151
152 #endif
153
154 /* XXX, BSD 4.3: getrusage() -> ru_ixrss ? */
155
156 #ifdef get_total_mem_used_by_app
157 static const ws_mem_usage_t total_usage = { "Total", get_total_mem_used_by_app, NULL };
158 #endif
159
160 #ifdef get_rss_mem_used_by_app
161 static const ws_mem_usage_t rss_usage = { "RSS", get_rss_mem_used_by_app, NULL };
162 #endif
163
164 static const ws_mem_usage_t *memory_components[MAX_COMPONENTS] = { 
165 #ifdef get_total_mem_used_by_app
166         &total_usage,
167 #endif
168 #ifdef get_rss_mem_used_by_app
169         &rss_usage,
170 #endif
171 };
172
173 static guint memory_register_num = 0
174 #ifdef get_total_mem_used_by_app
175         + 1
176 #endif
177 #ifdef get_rss_mem_used_by_app
178         + 1
179 #endif
180         ;
181
182 /* public API */
183
184 void
185 memory_usage_component_register(const ws_mem_usage_t *component)
186 {
187         if (memory_register_num >= MAX_COMPONENTS)
188                 return;
189
190         memory_components[memory_register_num++] = component;
191 }
192
193 const char *
194 memory_usage_get(guint index, gsize *value)
195 {
196         if (index >= memory_register_num)
197                 return NULL;
198
199         if (value)
200                 *value = memory_components[index]->fetch();
201
202         return memory_components[index]->name;
203 }
204
205 void
206 memory_usage_gc(void)
207 {
208         guint i;
209
210         for (i = 0; i < memory_register_num; i++) {
211                 if (memory_components[i]->gc)
212                         memory_components[i]->gc();
213         }
214 }
215