aboutsummaryrefslogtreecommitdiff
path: root/src/testbed
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-04-04 10:49:12 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-04-04 10:49:12 +0000
commit155e24361788c1dfe6fae4c0f42fb836ca62e775 (patch)
tree76766f24c0adae1ee9670cb6a825198c8f8fea15 /src/testbed
parentc303b97bd731aef372ec24ebe8b47ee014ada23b (diff)
downloadgnunet-155e24361788c1dfe6fae4c0f42fb836ca62e775.tar.gz
gnunet-155e24361788c1dfe6fae4c0f42fb836ca62e775.zip
- load monitoring in testbed
Diffstat (limited to 'src/testbed')
-rw-r--r--src/testbed/Makefile.am3
-rw-r--r--src/testbed/gnunet-service-testbed.c5
-rw-r--r--src/testbed/gnunet-service-testbed.h5
-rw-r--r--src/testbed/gnunet-service-testbed_cpustatus.c648
4 files changed, 659 insertions, 2 deletions
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am
index af61135f6..d980e8b6e 100644
--- a/src/testbed/Makefile.am
+++ b/src/testbed/Makefile.am
@@ -33,7 +33,8 @@ gnunet_service_testbed_SOURCES = \
33 gnunet-service-testbed.c \ 33 gnunet-service-testbed.c \
34 gnunet-service-testbed.h \ 34 gnunet-service-testbed.h \
35 gnunet-service-testbed_cache.c \ 35 gnunet-service-testbed_cache.c \
36 gnunet-service-testbed_oc.c 36 gnunet-service-testbed_oc.c \
37 gnunet-service-testbed_cpustatus.c
37gnunet_service_testbed_LDADD = $(XLIB) \ 38gnunet_service_testbed_LDADD = $(XLIB) \
38 $(top_builddir)/src/util/libgnunetutil.la \ 39 $(top_builddir)/src/util/libgnunetutil.la \
39 $(top_builddir)/src/core/libgnunetcore.la \ 40 $(top_builddir)/src/core/libgnunetcore.la \
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c
index 4aaf42620..4195ee366 100644
--- a/src/testbed/gnunet-service-testbed.c
+++ b/src/testbed/gnunet-service-testbed.c
@@ -2748,7 +2748,10 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
2748 &GST_timeout)); 2748 &GST_timeout));
2749 GNUNET_assert (GNUNET_OK == 2749 GNUNET_assert (GNUNET_OK ==
2750 GNUNET_CONFIGURATION_get_value_string (cfg, "testbed", 2750 GNUNET_CONFIGURATION_get_value_string (cfg, "testbed",
2751 "HOSTNAME", &hostname)); 2751 "HOSTNAME", &hostname));
2752 if (GNUNET_OK ==
2753 GNUNET_CONFIGURATION_get_value_string (cfg, "testbed",
2754 "STATS_DIR", &GST_stats_dir));
2752 our_config = GNUNET_CONFIGURATION_dup (cfg); 2755 our_config = GNUNET_CONFIGURATION_dup (cfg);
2753 GNUNET_SERVER_add_handlers (server, message_handlers); 2756 GNUNET_SERVER_add_handlers (server, message_handlers);
2754 GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL); 2757 GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL);
diff --git a/src/testbed/gnunet-service-testbed.h b/src/testbed/gnunet-service-testbed.h
index 8b3650e28..da63475d6 100644
--- a/src/testbed/gnunet-service-testbed.h
+++ b/src/testbed/gnunet-service-testbed.h
@@ -659,6 +659,11 @@ extern unsigned int GST_host_list_size;
659 */ 659 */
660extern unsigned int GST_slave_list_size; 660extern unsigned int GST_slave_list_size;
661 661
662/**
663 * The directory where to store load statistics data
664 */
665extern char *GST_stats_dir;
666
662 667
663/** 668/**
664 * Queues a message in send queue for sending to the service 669 * Queues a message in send queue for sending to the service
diff --git a/src/testbed/gnunet-service-testbed_cpustatus.c b/src/testbed/gnunet-service-testbed_cpustatus.c
new file mode 100644
index 000000000..55b9cafbc
--- /dev/null
+++ b/src/testbed/gnunet-service-testbed_cpustatus.c
@@ -0,0 +1,648 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2005, 2006, 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/**
22 * @file testbed/gnunet-service-testbed_cpustatus.c
23 * @brief calls to determine current CPU load
24 * @author Tzvetan Horozov
25 * @author Christian Grothoff
26 * @author Igor Wronsky
27 * @author Alex Harper (OS X portion)
28 * @author Sree Harsha Totakura
29 */
30
31#include "platform.h"
32#include "gnunet_util_lib.h"
33
34#if SOLARIS
35#if HAVE_KSTAT_H
36#include <kstat.h>
37#endif
38#if HAVE_SYS_SYSINFO_H
39#include <sys/sysinfo.h>
40#endif
41#if HAVE_KVM_H
42#include <kvm.h>
43#endif
44#endif
45#if SOMEBSD
46#if HAVE_KVM_H
47#include <kvm.h>
48#endif
49#endif
50
51#ifdef OSX
52#include <mach/mach.h>
53
54static processor_cpu_load_info_t prev_cpu_load;
55#endif
56
57#define DEBUG_STATUSCALLS GNUNET_NO
58
59#ifdef LINUX
60static FILE *proc_stat;
61#endif
62
63/**
64 * Current CPU load, as percentage of CPU cycles not idle or
65 * blocked on IO.
66 */
67static int currentCPULoad;
68
69static double agedCPULoad = -1;
70
71/**
72 * Current IO load, as percentage of CPU cycles blocked on IO.
73 */
74static int currentIOLoad;
75
76static double agedIOLoad = -1;
77
78#ifdef OSX
79static int
80initMachCpuStats ()
81{
82 unsigned int cpu_count;
83 processor_cpu_load_info_t cpu_load;
84 mach_msg_type_number_t cpu_msg_count;
85 kern_return_t kret;
86 int i, j;
87
88 kret = host_processor_info (mach_host_self (),
89 PROCESSOR_CPU_LOAD_INFO,
90 &cpu_count,
91 (processor_info_array_t *) & cpu_load,
92 &cpu_msg_count);
93 if (kret != KERN_SUCCESS)
94 {
95 GNUNET_GE_LOG (NULL,
96 GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_ADMIN |
97 GNUNET_GE_BULK, "host_processor_info failed.");
98 return GNUNET_SYSERR;
99 }
100 prev_cpu_load = GNUNET_malloc (cpu_count * sizeof (*prev_cpu_load));
101 for (i = 0; i < cpu_count; i++)
102 {
103 for (j = 0; j < CPU_STATE_MAX; j++)
104 {
105 prev_cpu_load[i].cpu_ticks[j] = cpu_load[i].cpu_ticks[j];
106 }
107 }
108 vm_deallocate (mach_task_self (),
109 (vm_address_t) cpu_load,
110 (vm_size_t) (cpu_msg_count * sizeof (*cpu_load)));
111 return GNUNET_OK;
112}
113#endif
114
115/**
116 * Update the currentCPU and currentIO load values.
117 *
118 * Before its first invocation the method initStatusCalls() must be called.
119 * If there is an error the method returns -1.
120 */
121static int
122updateUsage ()
123{
124 currentIOLoad = -1;
125 currentCPULoad = -1;
126#ifdef LINUX
127 /* under linux, first try %idle/usage using /proc/stat;
128 if that does not work, disable /proc/stat for the future
129 by closing the file and use the next-best method. */
130 if (proc_stat != NULL)
131 {
132 static unsigned long long last_cpu_results[5] = { 0, 0, 0, 0, 0 };
133 static int have_last_cpu = GNUNET_NO;
134 int ret;
135 char line[256];
136 unsigned long long user_read, system_read, nice_read, idle_read,
137 iowait_read;
138 unsigned long long user, system, nice, idle, iowait;
139 unsigned long long usage_time = 0, total_time = 1;
140
141 /* Get the first line with the data */
142 rewind (proc_stat);
143 fflush (proc_stat);
144 if (NULL == fgets (line, 256, proc_stat))
145 {
146 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
147 "fgets", "/proc/stat");
148 proc_stat = NULL; /* don't try again */
149 }
150 else
151 {
152 iowait_read = 0;
153 ret = sscanf (line, "%*s %llu %llu %llu %llu %llu",
154 &user_read,
155 &system_read, &nice_read, &idle_read, &iowait_read);
156 if (ret < 4)
157 {
158 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
159 "fgets-sscanf", "/proc/stat");
160 fclose (proc_stat);
161 proc_stat = NULL; /* don't try again */
162 have_last_cpu = GNUNET_NO;
163 }
164 else
165 {
166 /* Store the current usage */
167 user = user_read - last_cpu_results[0];
168 system = system_read - last_cpu_results[1];
169 nice = nice_read - last_cpu_results[2];
170 idle = idle_read - last_cpu_results[3];
171 iowait = iowait_read - last_cpu_results[4];
172 /* Calculate the % usage */
173 usage_time = user + system + nice;
174 total_time = usage_time + idle + iowait;
175 if ((total_time > 0) && (have_last_cpu == GNUNET_YES))
176 {
177 currentCPULoad = (int) (100L * usage_time / total_time);
178 if (ret > 4)
179 currentIOLoad = (int) (100L * iowait / total_time);
180 else
181 currentIOLoad = -1; /* 2.4 kernel */
182 }
183 /* Store the values for the next calculation */
184 last_cpu_results[0] = user_read;
185 last_cpu_results[1] = system_read;
186 last_cpu_results[2] = nice_read;
187 last_cpu_results[3] = idle_read;
188 last_cpu_results[4] = iowait_read;
189 have_last_cpu = GNUNET_YES;
190 return GNUNET_OK;
191 }
192 }
193 }
194#endif
195
196#ifdef OSX
197 {
198 unsigned int cpu_count;
199 processor_cpu_load_info_t cpu_load;
200 mach_msg_type_number_t cpu_msg_count;
201 unsigned long long t_sys, t_user, t_nice, t_idle, t_total;
202 unsigned long long t_idle_all, t_total_all;
203 kern_return_t kret;
204 int i, j;
205
206 t_idle_all = t_total_all = 0;
207 kret = host_processor_info (mach_host_self (), PROCESSOR_CPU_LOAD_INFO,
208 &cpu_count,
209 (processor_info_array_t *) & cpu_load,
210 &cpu_msg_count);
211 if (kret == KERN_SUCCESS)
212 {
213 for (i = 0; i < cpu_count; i++)
214 {
215 if (cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] >=
216 prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM])
217 {
218 t_sys = cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] -
219 prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM];
220 }
221 else
222 {
223 t_sys = cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] +
224 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] +
225 1);
226 }
227
228 if (cpu_load[i].cpu_ticks[CPU_STATE_USER] >=
229 prev_cpu_load[i].cpu_ticks[CPU_STATE_USER])
230 {
231 t_user = cpu_load[i].cpu_ticks[CPU_STATE_USER] -
232 prev_cpu_load[i].cpu_ticks[CPU_STATE_USER];
233 }
234 else
235 {
236 t_user = cpu_load[i].cpu_ticks[CPU_STATE_USER] +
237 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_USER] +
238 1);
239 }
240
241 if (cpu_load[i].cpu_ticks[CPU_STATE_NICE] >=
242 prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE])
243 {
244 t_nice = cpu_load[i].cpu_ticks[CPU_STATE_NICE] -
245 prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE];
246 }
247 else
248 {
249 t_nice = cpu_load[i].cpu_ticks[CPU_STATE_NICE] +
250 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE] +
251 1);
252 }
253
254 if (cpu_load[i].cpu_ticks[CPU_STATE_IDLE] >=
255 prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE])
256 {
257 t_idle = cpu_load[i].cpu_ticks[CPU_STATE_IDLE] -
258 prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE];
259 }
260 else
261 {
262 t_idle = cpu_load[i].cpu_ticks[CPU_STATE_IDLE] +
263 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE] +
264 1);
265 }
266 t_total = t_sys + t_user + t_nice + t_idle;
267 t_idle_all += t_idle;
268 t_total_all += t_total;
269 }
270 for (i = 0; i < cpu_count; i++)
271 {
272 for (j = 0; j < CPU_STATE_MAX; j++)
273 {
274 prev_cpu_load[i].cpu_ticks[j] = cpu_load[i].cpu_ticks[j];
275 }
276 }
277 if (t_total_all > 0)
278 currentCPULoad = 100 - (100 * t_idle_all) / t_total_all;
279 else
280 currentCPULoad = -1;
281 vm_deallocate (mach_task_self (),
282 (vm_address_t) cpu_load,
283 (vm_size_t) (cpu_msg_count * sizeof (*cpu_load)));
284 currentIOLoad = -1; /* FIXME-OSX! */
285 return GNUNET_OK;
286 }
287 else
288 {
289 GNUNET_GE_LOG (NULL,
290 GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_ADMIN |
291 GNUNET_GE_BULK, "host_processor_info failed.");
292 return GNUNET_SYSERR;
293 }
294 }
295#endif
296 /* try kstat (Solaris only) */
297#if SOLARIS && HAVE_KSTAT_H && HAVE_SYS_SYSINFO_H
298 {
299 static long long last_idlecount;
300 static long long last_totalcount;
301 static int kstat_once; /* if open fails, don't keep
302 trying */
303 kstat_ctl_t *kc;
304 kstat_t *khelper;
305 long long idlecount;
306 long long totalcount;
307 long long deltaidle;
308 long long deltatotal;
309
310 if (kstat_once == 1)
311 goto ABORT_KSTAT;
312 kc = kstat_open ();
313 if (kc == NULL)
314 {
315 GNUNET_GE_LOG_STRERROR (NULL,
316 GNUNET_GE_ERROR | GNUNET_GE_USER |
317 GNUNET_GE_ADMIN | GNUNET_GE_BULK,
318 "kstat_open");
319 goto ABORT_KSTAT;
320 }
321
322 idlecount = 0;
323 totalcount = 0;
324 for (khelper = kc->kc_chain; khelper != NULL; khelper = khelper->ks_next)
325 {
326 cpu_stat_t stats;
327
328 if (0 != strncmp (khelper->ks_name, "cpu_stat", strlen ("cpu_stat")))
329 continue;
330 if (khelper->ks_data_size > sizeof (cpu_stat_t))
331 continue; /* better save then sorry! */
332 if (-1 != kstat_read (kc, khelper, &stats))
333 {
334 idlecount += stats.cpu_sysinfo.cpu[CPU_IDLE];
335 totalcount
336 += stats.cpu_sysinfo.cpu[CPU_IDLE] +
337 stats.cpu_sysinfo.cpu[CPU_USER] +
338 stats.cpu_sysinfo.cpu[CPU_KERNEL] +
339 stats.cpu_sysinfo.cpu[CPU_WAIT];
340 }
341 }
342 if (0 != kstat_close (kc))
343 GNUNET_GE_LOG_STRERROR (NULL,
344 GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
345 GNUNET_GE_USER | GNUNET_GE_BULK, "kstat_close");
346 if ((idlecount == 0) && (totalcount == 0))
347 goto ABORT_KSTAT; /* no stats found => abort */
348 deltaidle = idlecount - last_idlecount;
349 deltatotal = totalcount - last_totalcount;
350 if ((deltatotal > 0) && (last_totalcount > 0))
351 {
352 currentCPULoad = (unsigned int) (100.0 * deltaidle / deltatotal);
353 if (currentCPULoad > 100)
354 currentCPULoad = 100; /* odd */
355 if (currentCPULoad < 0)
356 currentCPULoad = 0; /* odd */
357 currentCPULoad = 100 - currentCPULoad; /* computed idle-load before! */
358 }
359 else
360 currentCPULoad = -1;
361 currentIOLoad = -1; /* FIXME-SOLARIS! */
362 last_idlecount = idlecount;
363 last_totalcount = totalcount;
364 return GNUNET_OK;
365 ABORT_KSTAT:
366 kstat_once = 1; /* failed, don't try again */
367 return GNUNET_SYSERR;
368 }
369#endif
370
371 /* insert methods better than getloadavg for
372 other platforms HERE! */
373
374 /* ok, maybe we have getloadavg on this platform */
375#if HAVE_GETLOADAVG
376 {
377 static int warnOnce = 0;
378 double loadavg;
379 if (1 != getloadavg (&loadavg, 1))
380 {
381 /* only warn once, if there is a problem with
382 getloadavg, we're going to hit it frequently... */
383 if (warnOnce == 0)
384 {
385 warnOnce = 1;
386 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "getloadavg");
387 }
388 return GNUNET_SYSERR;
389 }
390 else
391 {
392 /* success with getloadavg */
393 currentCPULoad = (int) (100 * loadavg);
394 currentIOLoad = -1; /* FIXME */
395 return GNUNET_OK;
396 }
397 }
398#endif
399
400#if MINGW
401 /* Win NT? */
402 if (GNNtQuerySystemInformation)
403 {
404 static double dLastKernel;
405 static double dLastIdle;
406 static double dLastUser;
407 double dKernel;
408 double dIdle;
409 double dUser;
410 double dDiffKernel;
411 double dDiffIdle;
412 double dDiffUser;
413 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION theInfo;
414
415 if (GNNtQuerySystemInformation (SystemProcessorPerformanceInformation,
416 &theInfo,
417 sizeof (theInfo), NULL) == NO_ERROR)
418 {
419 /* PORT-ME MINGW: Multi-processor? */
420 dKernel = Li2Double (theInfo.KernelTime);
421 dIdle = Li2Double (theInfo.IdleTime);
422 dUser = Li2Double (theInfo.UserTime);
423 dDiffKernel = dKernel - dLastKernel;
424 dDiffIdle = dIdle - dLastIdle;
425 dDiffUser = dUser - dLastUser;
426
427 if (((dDiffKernel + dDiffUser) > 0) &&
428 (dLastIdle + dLastKernel + dLastUser > 0))
429 currentCPULoad =
430 100.0 - (dDiffIdle / (dDiffKernel + dDiffUser)) * 100.0;
431 else
432 currentCPULoad = -1; /* don't know (yet) */
433
434 dLastKernel = dKernel;
435 dLastIdle = dIdle;
436 dLastUser = dUser;
437
438 currentIOLoad = -1; /* FIXME-MINGW */
439 return GNUNET_OK;
440 }
441 else
442 {
443 /* only warn once, if there is a problem with
444 NtQuery..., we're going to hit it frequently... */
445 static int once;
446 if (once == 0)
447 {
448 once = 1;
449 GNUNET_GE_LOG (NULL,
450 GNUNET_GE_ERROR | GNUNET_GE_USER |
451 GNUNET_GE_ADMIN | GNUNET_GE_BULK,
452 _("Cannot query the CPU usage (Windows NT).\n"));
453 }
454 return GNUNET_SYSERR;
455 }
456 }
457 else
458 { /* Win 9x */
459 HKEY hKey;
460 DWORD dwDataSize, dwType, dwDummy;
461
462 /* Start query */
463 if (RegOpenKeyEx (HKEY_DYN_DATA,
464 "PerfStats\\StartSrv",
465 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
466 {
467 /* only warn once */
468 static int once = 0;
469 if (once == 0)
470 {
471 once = 1;
472 GNUNET_GE_LOG (NULL,
473 GNUNET_GE_USER | GNUNET_GE_ADMIN |
474 GNUNET_GE_ERROR | GNUNET_GE_BULK,
475 _("Cannot query the CPU usage (Win 9x)\n"));
476 }
477 }
478
479 RegOpenKeyEx (HKEY_DYN_DATA,
480 "PerfStats\\StartStat", 0, KEY_ALL_ACCESS, &hKey);
481 dwDataSize = sizeof (dwDummy);
482 RegQueryValueEx (hKey,
483 "KERNEL\\CPUUsage",
484 NULL, &dwType, (LPBYTE) & dwDummy, &dwDataSize);
485 RegCloseKey (hKey);
486
487 /* Get CPU usage */
488 RegOpenKeyEx (HKEY_DYN_DATA,
489 "PerfStats\\StatData", 0, KEY_ALL_ACCESS, &hKey);
490 dwDataSize = sizeof (currentCPULoad);
491 RegQueryValueEx (hKey,
492 "KERNEL\\CPUUsage",
493 NULL, &dwType, (LPBYTE) & currentCPULoad, &dwDataSize);
494 RegCloseKey (hKey);
495 currentIOLoad = -1; /* FIXME-MINGW! */
496
497 /* Stop query */
498 RegOpenKeyEx (HKEY_DYN_DATA,
499 "PerfStats\\StopStat", 0, KEY_ALL_ACCESS, &hKey);
500 RegOpenKeyEx (HKEY_DYN_DATA,
501 "PerfStats\\StopSrv", 0, KEY_ALL_ACCESS, &hKey);
502 dwDataSize = sizeof (dwDummy);
503 RegQueryValueEx (hKey,
504 "KERNEL\\CPUUsage",
505 NULL, &dwType, (LPBYTE) & dwDummy, &dwDataSize);
506 RegCloseKey (hKey);
507
508 return GNUNET_OK;
509 }
510#endif
511
512 /* loadaverage not defined and no platform
513 specific alternative defined
514 => default: error
515 */
516 return GNUNET_SYSERR;
517}
518
519struct GNUNET_GE_Context;
520struct GNUNET_GC_Configuration;
521
522/**
523 * Update load values (if enough time has expired),
524 * including computation of averages. Code assumes
525 * that lock has already been obtained.
526 */
527static void
528updateAgedLoad (struct GNUNET_GE_Context *ectx,
529 struct GNUNET_GC_Configuration *cfg)
530{
531 static struct GNUNET_TIME_Absolute lastCall;
532 struct GNUNET_TIME_Relative age;
533
534 age = GNUNET_TIME_absolute_get_duration (lastCall);
535 if ( (agedCPULoad == -1)
536 || (age.rel_value > 500) )
537 {
538 /* use smoothing, but do NOT update lastRet at frequencies higher
539 than 500ms; this makes the smoothing (mostly) independent from
540 the frequency at which getCPULoad is called (and we don't spend
541 more time measuring CPU than actually computing something). */
542 lastCall = GNUNET_TIME_absolute_get ();
543 updateUsage ();
544 if (currentCPULoad == -1)
545 {
546 agedCPULoad = -1;
547 }
548 else
549 {
550 if (agedCPULoad == -1)
551 {
552 agedCPULoad = currentCPULoad;
553 }
554 else
555 {
556 /* for CPU, we don't do the 'fast increase' since CPU is much
557 more jitterish to begin with */
558 agedCPULoad = (agedCPULoad * 31 + currentCPULoad) / 32;
559 }
560 }
561 if (currentIOLoad == -1)
562 {
563 agedIOLoad = -1;
564 }
565 else
566 {
567 if (agedIOLoad == -1)
568 {
569 agedIOLoad = currentIOLoad;
570 }
571 else
572 {
573 /* for IO, we don't do the 'fast increase' since IO is much
574 more jitterish to begin with */
575 agedIOLoad = (agedIOLoad * 31 + currentIOLoad) / 32;
576 }
577 }
578 }
579}
580
581/**
582 * Get the load of the CPU relative to what is allowed.
583 * @return the CPU load as a percentage of allowed
584 * (100 is equivalent to full load)
585 */
586int
587GNUNET_cpu_get_load (struct GNUNET_GE_Context *ectx,
588 struct GNUNET_GC_Configuration *cfg)
589{
590 updateAgedLoad (ectx, cfg);
591 return (int) agedCPULoad;
592}
593
594
595/**
596 * Get the load of the CPU relative to what is allowed.
597 * @return the CPU load as a percentage of allowed
598 * (100 is equivalent to full load)
599 */
600int
601GNUNET_disk_get_load (struct GNUNET_GE_Context *ectx,
602 struct GNUNET_GC_Configuration *cfg)
603{
604 updateAgedLoad (ectx, cfg);
605 return (int) agedIOLoad;
606}
607
608/**
609 * The following method is called in order to initialize the status calls
610 * routines. After that it is safe to call each of the status calls separately
611 * @return GNUNET_OK on success and GNUNET_SYSERR on error (or calls errexit).
612 */
613void __attribute__ ((constructor)) GNUNET_cpustats_ltdl_init ()
614{
615#ifdef LINUX
616 proc_stat = fopen ("/proc/stat", "r");
617 if (NULL == proc_stat)
618 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
619 "fopen", "/proc/stat");
620#elif OSX
621 initMachCpuStats ();
622#elif MINGW
623 InitWinEnv (NULL);
624#endif
625 updateUsage (); /* initialize */
626}
627
628/**
629 * Shutdown the status calls module.
630 */
631void __attribute__ ((destructor)) GNUNET_cpustats_ltdl_fini ()
632{
633#ifdef LINUX
634 if (proc_stat != NULL)
635 {
636 fclose (proc_stat);
637 proc_stat = NULL;
638 }
639#elif OSX
640 GNUNET_free_non_null (prev_cpu_load);
641#elif MINGW
642 ShutdownWinEnv ();
643#endif
644}
645
646char *GST_stats_dir;
647
648/* end of cpustatus.c */