diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2013-05-17 15:50:00 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2013-05-17 15:50:00 +0000 |
commit | a3b91939536499844d78cc357332e144b831f39a (patch) | |
tree | d8a5292c50208169a5a5c08d10142ea67634840a /src | |
parent | a0f79a7add4699aee795549de95c1178efa2d360 (diff) | |
download | gnunet-a3b91939536499844d78cc357332e144b831f39a.tar.gz gnunet-a3b91939536499844d78cc357332e144b831f39a.zip |
- include logging of memory statistics on Linux
Diffstat (limited to 'src')
-rw-r--r-- | src/testbed/Makefile.am | 4 | ||||
-rw-r--r-- | src/testbed/gnunet-service-testbed_cpustatus.c | 24 | ||||
-rw-r--r-- | src/testbed/gnunet-service-testbed_meminfo.c | 263 | ||||
-rw-r--r-- | src/testbed/gnunet-service-testbed_meminfo.h | 55 |
4 files changed, 342 insertions, 4 deletions
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am index 3f3d6db55..902d8391b 100644 --- a/src/testbed/Makefile.am +++ b/src/testbed/Makefile.am | |||
@@ -37,7 +37,9 @@ gnunet_service_testbed_SOURCES = \ | |||
37 | gnunet-service-testbed_peers.c \ | 37 | gnunet-service-testbed_peers.c \ |
38 | gnunet-service-testbed_cache.c \ | 38 | gnunet-service-testbed_cache.c \ |
39 | gnunet-service-testbed_oc.c \ | 39 | gnunet-service-testbed_oc.c \ |
40 | gnunet-service-testbed_cpustatus.c | 40 | gnunet-service-testbed_cpustatus.c \ |
41 | gnunet-service-testbed_meminfo.c \ | ||
42 | gnunet-service-testbed_meminfo.h | ||
41 | gnunet_service_testbed_LDADD = $(XLIB) \ | 43 | gnunet_service_testbed_LDADD = $(XLIB) \ |
42 | $(top_builddir)/src/util/libgnunetutil.la \ | 44 | $(top_builddir)/src/util/libgnunetutil.la \ |
43 | $(top_builddir)/src/core/libgnunetcore.la \ | 45 | $(top_builddir)/src/core/libgnunetcore.la \ |
diff --git a/src/testbed/gnunet-service-testbed_cpustatus.c b/src/testbed/gnunet-service-testbed_cpustatus.c index cb23800f4..5ae912923 100644 --- a/src/testbed/gnunet-service-testbed_cpustatus.c +++ b/src/testbed/gnunet-service-testbed_cpustatus.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include "platform.h" | 31 | #include "platform.h" |
32 | #include "gnunet_util_lib.h" | 32 | #include "gnunet_util_lib.h" |
33 | #include "gnunet-service-testbed_meminfo.h" | ||
33 | 34 | ||
34 | #if SOLARIS | 35 | #if SOLARIS |
35 | #if HAVE_KSTAT_H | 36 | #if HAVE_KSTAT_H |
@@ -120,7 +121,7 @@ initMachCpuStats () | |||
120 | #endif | 121 | #endif |
121 | 122 | ||
122 | /** | 123 | /** |
123 | * Update the currentCPU and currentIO load values. | 124 | * Update the currentCPU and currentIO load (and on Linux, memory) values. |
124 | * | 125 | * |
125 | * Before its first invocation the method initStatusCalls() must be called. | 126 | * Before its first invocation the method initStatusCalls() must be called. |
126 | * If there is an error the method returns -1. | 127 | * If there is an error the method returns -1. |
@@ -596,6 +597,21 @@ disk_get_load () | |||
596 | return (int) agedIOLoad; | 597 | return (int) agedIOLoad; |
597 | } | 598 | } |
598 | 599 | ||
600 | /** | ||
601 | * Get the percentage of memory used | ||
602 | * | ||
603 | * @return the percentage of memory used | ||
604 | */ | ||
605 | static unsigned int | ||
606 | mem_get_usage () | ||
607 | { | ||
608 | unsigned long currentMemUsage; | ||
609 | |||
610 | meminfo (); | ||
611 | currentMemUsage = kb_main_total - kb_main_free; | ||
612 | return (unsigned int) ((currentMemUsage / kb_main_total) * 100); | ||
613 | } | ||
614 | |||
599 | 615 | ||
600 | static void | 616 | static void |
601 | sample_load_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 617 | sample_load_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
@@ -605,6 +621,7 @@ sample_load_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
605 | int nbs; | 621 | int nbs; |
606 | int ld_cpu; | 622 | int ld_cpu; |
607 | int ld_disk; | 623 | int ld_disk; |
624 | unsigned int mem_usage; | ||
608 | 625 | ||
609 | sample_load_task_id = GNUNET_SCHEDULER_NO_TASK; | 626 | sample_load_task_id = GNUNET_SCHEDULER_NO_TASK; |
610 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | 627 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) |
@@ -613,9 +630,10 @@ sample_load_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
613 | ld_disk = disk_get_load (); | 630 | ld_disk = disk_get_load (); |
614 | if ( (-1 == ld_cpu) || (-1 == ld_disk) ) | 631 | if ( (-1 == ld_cpu) || (-1 == ld_disk) ) |
615 | goto reschedule; | 632 | goto reschedule; |
633 | mem_usage = mem_get_usage (); | ||
616 | now = GNUNET_TIME_absolute_get (); | 634 | now = GNUNET_TIME_absolute_get (); |
617 | nbs = GNUNET_asprintf (&str, "%llu %d %d\n", now.abs_value / 1000, | 635 | nbs = GNUNET_asprintf (&str, "%llu %d %d %u\n", now.abs_value / 1000, |
618 | ld_cpu, ld_disk); | 636 | ld_cpu, ld_disk, mem_usage); |
619 | if (0 < nbs) | 637 | if (0 < nbs) |
620 | { | 638 | { |
621 | GNUNET_BIO_write (bw, str, nbs); | 639 | GNUNET_BIO_write (bw, str, nbs); |
diff --git a/src/testbed/gnunet-service-testbed_meminfo.c b/src/testbed/gnunet-service-testbed_meminfo.c new file mode 100644 index 000000000..57fd506b2 --- /dev/null +++ b/src/testbed/gnunet-service-testbed_meminfo.c | |||
@@ -0,0 +1,263 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2008--2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include "platform.h" | ||
22 | #include "gnunet_common.h" | ||
23 | |||
24 | /* | ||
25 | * File for parsing top-level /proc entities. | ||
26 | * Copyright (C) 1992-1998 by Michael K. Johnson, johnsonm@redhat.com | ||
27 | * Copyright 1998-2003 Albert Cahalan | ||
28 | * June 2003, Fabian Frederick, disk and slab info | ||
29 | * | ||
30 | * This library is free software; you can redistribute it and/or | ||
31 | * modify it under the terms of the GNU Lesser General Public | ||
32 | * License as published by the Free Software Foundation; either | ||
33 | * version 2.1 of the License, or (at your option) any later version. | ||
34 | * | ||
35 | * This library is distributed in the hope that it will be useful, | ||
36 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
37 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
38 | * Lesser General Public License for more details. | ||
39 | * | ||
40 | * You should have received a copy of the GNU Lesser General Public | ||
41 | * License along with this library; if not, write to the Free Software | ||
42 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
43 | */ | ||
44 | |||
45 | #define BAD_OPEN_MESSAGE \ | ||
46 | "Error: /proc must be mounted\n" \ | ||
47 | " To mount /proc at boot you need an /etc/fstab line like:\n" \ | ||
48 | " proc /proc proc defaults\n" \ | ||
49 | " In the meantime, run \"mount proc /proc -t proc\"\n" | ||
50 | |||
51 | #define STAT_FILE "/proc/stat" | ||
52 | //static int stat_fd = -1; | ||
53 | #define UPTIME_FILE "/proc/uptime" | ||
54 | //static int uptime_fd = -1; | ||
55 | #define LOADAVG_FILE "/proc/loadavg" | ||
56 | //static int loadavg_fd = -1; | ||
57 | #define MEMINFO_FILE "/proc/meminfo" | ||
58 | static int meminfo_fd = -1; | ||
59 | #define VMINFO_FILE "/proc/vmstat" | ||
60 | //static int vminfo_fd = -1; | ||
61 | |||
62 | // As of 2.6.24 /proc/meminfo seems to need 888 on 64-bit, | ||
63 | // and would need 1258 if the obsolete fields were there. | ||
64 | static char buf[2048]; | ||
65 | |||
66 | /* This macro opens filename only if necessary and seeks to 0 so | ||
67 | * that successive calls to the functions are more efficient. | ||
68 | * It also reads the current contents of the file into the global buf. | ||
69 | */ | ||
70 | #define FILE_TO_BUF(filename, fd) do{ \ | ||
71 | static int local_n; \ | ||
72 | if (fd == -1 && (fd = open(filename, O_RDONLY)) == -1) { \ | ||
73 | fputs(BAD_OPEN_MESSAGE, stderr); \ | ||
74 | fflush(NULL); \ | ||
75 | _exit(102); \ | ||
76 | } \ | ||
77 | lseek(fd, 0L, SEEK_SET); \ | ||
78 | if ((local_n = read(fd, buf, sizeof buf - 1)) < 0) { \ | ||
79 | perror(filename); \ | ||
80 | fflush(NULL); \ | ||
81 | _exit(103); \ | ||
82 | } \ | ||
83 | buf[local_n] = '\0'; \ | ||
84 | }while(0) | ||
85 | |||
86 | |||
87 | /***********************************************************************/ | ||
88 | /* | ||
89 | * Copyright 1999 by Albert Cahalan; all rights reserved. | ||
90 | * This file may be used subject to the terms and conditions of the | ||
91 | * GNU Library General Public License Version 2, or any later version | ||
92 | * at your option, as published by the Free Software Foundation. | ||
93 | * This program is distributed in the hope that it will be useful, | ||
94 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
95 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
96 | * GNU Library General Public License for more details. | ||
97 | */ | ||
98 | |||
99 | typedef struct mem_table_struct { | ||
100 | const char *name; /* memory type name */ | ||
101 | unsigned long *slot; /* slot in return struct */ | ||
102 | } mem_table_struct; | ||
103 | |||
104 | static int compare_mem_table_structs(const void *a, const void *b){ | ||
105 | return strcmp(((const mem_table_struct*)a)->name,((const mem_table_struct*)b)->name); | ||
106 | } | ||
107 | |||
108 | /* example data, following junk, with comments added: | ||
109 | * | ||
110 | * MemTotal: 61768 kB old | ||
111 | * MemFree: 1436 kB old | ||
112 | * MemShared: 0 kB old (now always zero; not calculated) | ||
113 | * Buffers: 1312 kB old | ||
114 | * Cached: 20932 kB old | ||
115 | * Active: 12464 kB new | ||
116 | * Inact_dirty: 7772 kB new | ||
117 | * Inact_clean: 2008 kB new | ||
118 | * Inact_target: 0 kB new | ||
119 | * Inact_laundry: 0 kB new, and might be missing too | ||
120 | * HighTotal: 0 kB | ||
121 | * HighFree: 0 kB | ||
122 | * LowTotal: 61768 kB | ||
123 | * LowFree: 1436 kB | ||
124 | * SwapTotal: 122580 kB old | ||
125 | * SwapFree: 60352 kB old | ||
126 | * Inactive: 20420 kB 2.5.41+ | ||
127 | * Dirty: 0 kB 2.5.41+ | ||
128 | * Writeback: 0 kB 2.5.41+ | ||
129 | * Mapped: 9792 kB 2.5.41+ | ||
130 | * Slab: 4564 kB 2.5.41+ | ||
131 | * Committed_AS: 8440 kB 2.5.41+ | ||
132 | * PageTables: 304 kB 2.5.41+ | ||
133 | * ReverseMaps: 5738 2.5.41+ | ||
134 | * SwapCached: 0 kB 2.5.??+ | ||
135 | * HugePages_Total: 220 2.5.??+ | ||
136 | * HugePages_Free: 138 2.5.??+ | ||
137 | * Hugepagesize: 4096 kB 2.5.??+ | ||
138 | */ | ||
139 | |||
140 | /* obsolete */ | ||
141 | unsigned long kb_main_shared; | ||
142 | /* old but still kicking -- the important stuff */ | ||
143 | unsigned long kb_main_buffers; | ||
144 | unsigned long kb_main_cached; | ||
145 | unsigned long kb_main_free; | ||
146 | unsigned long kb_main_total; | ||
147 | unsigned long kb_swap_free; | ||
148 | unsigned long kb_swap_total; | ||
149 | /* recently introduced */ | ||
150 | unsigned long kb_high_free; | ||
151 | unsigned long kb_high_total; | ||
152 | unsigned long kb_low_free; | ||
153 | unsigned long kb_low_total; | ||
154 | /* 2.4.xx era */ | ||
155 | unsigned long kb_active; | ||
156 | unsigned long kb_inact_laundry; | ||
157 | unsigned long kb_inact_dirty; | ||
158 | unsigned long kb_inact_clean; | ||
159 | unsigned long kb_inact_target; | ||
160 | unsigned long kb_swap_cached; /* late 2.4 and 2.6+ only */ | ||
161 | /* derived values */ | ||
162 | unsigned long kb_swap_used; | ||
163 | unsigned long kb_main_used; | ||
164 | /* 2.5.41+ */ | ||
165 | unsigned long kb_writeback; | ||
166 | unsigned long kb_slab; | ||
167 | unsigned long nr_reversemaps; | ||
168 | unsigned long kb_committed_as; | ||
169 | unsigned long kb_dirty; | ||
170 | unsigned long kb_inactive; | ||
171 | unsigned long kb_mapped; | ||
172 | unsigned long kb_pagetables; | ||
173 | // seen on a 2.6.x kernel: | ||
174 | static unsigned long kb_vmalloc_chunk; | ||
175 | static unsigned long kb_vmalloc_total; | ||
176 | static unsigned long kb_vmalloc_used; | ||
177 | // seen on 2.6.24-rc6-git12 | ||
178 | static unsigned long kb_anon_pages; | ||
179 | static unsigned long kb_bounce; | ||
180 | static unsigned long kb_commit_limit; | ||
181 | static unsigned long kb_nfs_unstable; | ||
182 | static unsigned long kb_swap_reclaimable; | ||
183 | static unsigned long kb_swap_unreclaimable; | ||
184 | |||
185 | void meminfo(void){ | ||
186 | char namebuf[16]; /* big enough to hold any row name */ | ||
187 | mem_table_struct findme = { namebuf, NULL}; | ||
188 | mem_table_struct *found; | ||
189 | char *head; | ||
190 | char *tail; | ||
191 | static const mem_table_struct mem_table[] = { | ||
192 | {"Active", &kb_active}, // important | ||
193 | {"AnonPages", &kb_anon_pages}, | ||
194 | {"Bounce", &kb_bounce}, | ||
195 | {"Buffers", &kb_main_buffers}, // important | ||
196 | {"Cached", &kb_main_cached}, // important | ||
197 | {"CommitLimit", &kb_commit_limit}, | ||
198 | {"Committed_AS", &kb_committed_as}, | ||
199 | {"Dirty", &kb_dirty}, // kB version of vmstat nr_dirty | ||
200 | {"HighFree", &kb_high_free}, | ||
201 | {"HighTotal", &kb_high_total}, | ||
202 | {"Inact_clean", &kb_inact_clean}, | ||
203 | {"Inact_dirty", &kb_inact_dirty}, | ||
204 | {"Inact_laundry",&kb_inact_laundry}, | ||
205 | {"Inact_target", &kb_inact_target}, | ||
206 | {"Inactive", &kb_inactive}, // important | ||
207 | {"LowFree", &kb_low_free}, | ||
208 | {"LowTotal", &kb_low_total}, | ||
209 | {"Mapped", &kb_mapped}, // kB version of vmstat nr_mapped | ||
210 | {"MemFree", &kb_main_free}, // important | ||
211 | {"MemShared", &kb_main_shared}, // important, but now gone! | ||
212 | {"MemTotal", &kb_main_total}, // important | ||
213 | {"NFS_Unstable", &kb_nfs_unstable}, | ||
214 | {"PageTables", &kb_pagetables}, // kB version of vmstat nr_page_table_pages | ||
215 | {"ReverseMaps", &nr_reversemaps}, // same as vmstat nr_page_table_pages | ||
216 | {"SReclaimable", &kb_swap_reclaimable}, // "swap reclaimable" (dentry and inode structures) | ||
217 | {"SUnreclaim", &kb_swap_unreclaimable}, | ||
218 | {"Slab", &kb_slab}, // kB version of vmstat nr_slab | ||
219 | {"SwapCached", &kb_swap_cached}, | ||
220 | {"SwapFree", &kb_swap_free}, // important | ||
221 | {"SwapTotal", &kb_swap_total}, // important | ||
222 | {"VmallocChunk", &kb_vmalloc_chunk}, | ||
223 | {"VmallocTotal", &kb_vmalloc_total}, | ||
224 | {"VmallocUsed", &kb_vmalloc_used}, | ||
225 | {"Writeback", &kb_writeback}, // kB version of vmstat nr_writeback | ||
226 | }; | ||
227 | const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct); | ||
228 | |||
229 | FILE_TO_BUF(MEMINFO_FILE,meminfo_fd); | ||
230 | |||
231 | kb_inactive = ~0UL; | ||
232 | |||
233 | head = buf; | ||
234 | for(;;){ | ||
235 | tail = strchr(head, ':'); | ||
236 | if(!tail) break; | ||
237 | *tail = '\0'; | ||
238 | if(strlen(head) >= sizeof(namebuf)){ | ||
239 | head = tail+1; | ||
240 | goto nextline; | ||
241 | } | ||
242 | strcpy(namebuf,head); | ||
243 | found = bsearch(&findme, mem_table, mem_table_count, | ||
244 | sizeof(mem_table_struct), compare_mem_table_structs | ||
245 | ); | ||
246 | head = tail+1; | ||
247 | if(!found) goto nextline; | ||
248 | *(found->slot) = (unsigned long)strtoull(head,&tail,10); | ||
249 | nextline: | ||
250 | tail = strchr(head, '\n'); | ||
251 | if(!tail) break; | ||
252 | head = tail+1; | ||
253 | } | ||
254 | if(!kb_low_total){ /* low==main except with large-memory support */ | ||
255 | kb_low_total = kb_main_total; | ||
256 | kb_low_free = kb_main_free; | ||
257 | } | ||
258 | if(kb_inactive==~0UL){ | ||
259 | kb_inactive = kb_inact_dirty + kb_inact_clean + kb_inact_laundry; | ||
260 | } | ||
261 | kb_swap_used = kb_swap_total - kb_swap_free; | ||
262 | kb_main_used = kb_main_total - kb_main_free; | ||
263 | } | ||
diff --git a/src/testbed/gnunet-service-testbed_meminfo.h b/src/testbed/gnunet-service-testbed_meminfo.h new file mode 100644 index 000000000..6ee52300c --- /dev/null +++ b/src/testbed/gnunet-service-testbed_meminfo.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2008--2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* obsolete */ | ||
22 | extern unsigned long kb_main_shared; | ||
23 | /* old but still kicking -- the important stuff */ | ||
24 | extern unsigned long kb_main_buffers; | ||
25 | extern unsigned long kb_main_cached; | ||
26 | extern unsigned long kb_main_free; | ||
27 | extern unsigned long kb_main_total; | ||
28 | extern unsigned long kb_swap_free; | ||
29 | extern unsigned long kb_swap_total; | ||
30 | /* recently introduced */ | ||
31 | extern unsigned long kb_high_free; | ||
32 | extern unsigned long kb_high_total; | ||
33 | extern unsigned long kb_low_free; | ||
34 | extern unsigned long kb_low_total; | ||
35 | /* 2.4.xx era */ | ||
36 | extern unsigned long kb_active; | ||
37 | extern unsigned long kb_inact_laundry; // grrr... | ||
38 | extern unsigned long kb_inact_dirty; | ||
39 | extern unsigned long kb_inact_clean; | ||
40 | extern unsigned long kb_inact_target; | ||
41 | extern unsigned long kb_swap_cached; /* late 2.4+ */ | ||
42 | /* derived values */ | ||
43 | extern unsigned long kb_swap_used; | ||
44 | extern unsigned long kb_main_used; | ||
45 | /* 2.5.41+ */ | ||
46 | extern unsigned long kb_writeback; | ||
47 | extern unsigned long kb_slab; | ||
48 | extern unsigned long nr_reversemaps; | ||
49 | extern unsigned long kb_committed_as; | ||
50 | extern unsigned long kb_dirty; | ||
51 | extern unsigned long kb_inactive; | ||
52 | extern unsigned long kb_mapped; | ||
53 | extern unsigned long kb_pagetables; | ||
54 | |||
55 | extern void meminfo(void); | ||