aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-10-08 16:52:33 +0000
committerChristian Grothoff <christian@grothoff.org>2010-10-08 16:52:33 +0000
commit194224be3b68264c4147857604bed570bf3e8e36 (patch)
tree0f6ff9ff09015e56802c7fd5b3b0d40ff883eeb1 /src
parent29a092166fa5713d3aae69a0edd8373438423e22 (diff)
downloadgnunet-194224be3b68264c4147857604bed570bf3e8e36.tar.gz
gnunet-194224be3b68264c4147857604bed570bf3e8e36.zip
die cpu load code, die
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_os_lib.h21
-rw-r--r--src/util/Makefile.am7
-rw-r--r--src/util/os_load.c684
-rw-r--r--src/util/test_os_load.c184
4 files changed, 0 insertions, 896 deletions
diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h
index bea960346..701aae593 100644
--- a/src/include/gnunet_os_lib.h
+++ b/src/include/gnunet_os_lib.h
@@ -172,27 +172,6 @@ void GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor
172 172
173 173
174/** 174/**
175 * Get the current CPU load.
176 *
177 * @param cfg to determine acceptable load level (LOAD::MAXCPULOAD)
178 * @return -1 on error, otherwise load value (between 0 and 100,
179 * (100 is equivalent to full load for one CPU)
180 */
181int GNUNET_OS_load_cpu_get (const struct GNUNET_CONFIGURATION_Handle *cfg);
182
183
184/**
185 * Get the current IO load.
186 *
187 * @param cfg to determine acceptable load level (LOAD::MAXIOLOAD)
188 * @return -1 on error, otherwise load value (between 0 and 100,
189 * 100 means that we spend all of our cycles waiting for
190 * the disk)
191 */
192int GNUNET_OS_load_disk_get (const struct GNUNET_CONFIGURATION_Handle *cfg);
193
194
195/**
196 * Set process priority 175 * Set process priority
197 * 176 *
198 * @param proc id of the process 177 * @param proc id of the process
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 40e867631..c8fd7dfba 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -52,7 +52,6 @@ libgnunetutil_la_SOURCES = \
52 load.c \ 52 load.c \
53 network.c \ 53 network.c \
54 os_installation.c \ 54 os_installation.c \
55 os_load.c \
56 os_network.c \ 55 os_network.c \
57 os_priority.c \ 56 os_priority.c \
58 peer.c \ 57 peer.c \
@@ -128,7 +127,6 @@ check_PROGRAMS = \
128 test_connection_timeout \ 127 test_connection_timeout \
129 test_connection_timeout_no_connect \ 128 test_connection_timeout_no_connect \
130 test_connection_transmit_cancel \ 129 test_connection_transmit_cancel \
131 test_os_load \
132 test_os_network \ 130 test_os_network \
133 test_os_priority \ 131 test_os_priority \
134 test_peer \ 132 test_peer \
@@ -292,11 +290,6 @@ test_connection_transmit_cancel_SOURCES = \
292test_connection_transmit_cancel_LDADD = \ 290test_connection_transmit_cancel_LDADD = \
293 $(top_builddir)/src/util/libgnunetutil.la 291 $(top_builddir)/src/util/libgnunetutil.la
294 292
295test_os_load_SOURCES = \
296 test_os_load.c
297test_os_load_LDADD = \
298 $(top_builddir)/src/util/libgnunetutil.la
299
300test_os_network_SOURCES = \ 293test_os_network_SOURCES = \
301 test_os_network.c 294 test_os_network.c
302test_os_network_LDADD = \ 295test_os_network_LDADD = \
diff --git a/src/util/os_load.c b/src/util/os_load.c
deleted file mode 100644
index 53e9a84c3..000000000
--- a/src/util/os_load.c
+++ /dev/null
@@ -1,684 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2005, 2006 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 util/os_load.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 */
29
30#include "platform.h"
31#include "gnunet_common.h"
32#include "gnunet_os_lib.h"
33#include "gnunet_strings_lib.h"
34
35#if SOLARIS
36#if HAVE_KSTAT_H
37#include <kstat.h>
38#endif
39#if HAVE_SYS_SYSINFO_H
40#include <sys/sysinfo.h>
41#endif
42#if HAVE_KVM_H
43#include <kvm.h>
44#endif
45#endif
46#if SOMEBSD
47#if HAVE_KVM_H
48#include <kvm.h>
49#endif
50#endif
51
52#ifdef DARWIN
53#include <mach/mach.h>
54
55static processor_cpu_load_info_t prev_cpu_load;
56#endif
57
58#define DEBUG_STATUSCALLS GNUNET_NO
59
60#ifdef LINUX
61/**
62 * File descriptor for reading /proc/stat (or NULL)
63 */
64static FILE *proc_stat;
65
66/**
67 * Is this the first time we're trying to open /proc/stat? If
68 * not, we don't try again if we failed...
69 */
70static int first_time;
71#endif
72
73/**
74 * Current CPU load, as percentage of CPU cycles not idle or
75 * blocked on IO.
76 */
77static int currentCPULoad;
78
79static double agedCPULoad = -1;
80
81/**
82 * Current IO load, as percentage of CPU cycles blocked on IO.
83 */
84static int currentIOLoad;
85
86static double agedIOLoad = -1;
87
88#ifdef DARWIN
89static int
90initMachCpuStats ()
91{
92 unsigned int cpu_count;
93 processor_cpu_load_info_t cpu_load;
94 mach_msg_type_number_t cpu_msg_count;
95 kern_return_t kret;
96 int i, j;
97
98 kret = host_processor_info (mach_host_self (),
99 PROCESSOR_CPU_LOAD_INFO,
100 &cpu_count,
101 (processor_info_array_t *) & cpu_load,
102 &cpu_msg_count);
103 if (kret != KERN_SUCCESS)
104 {
105 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
106 "host_processor_info failed.");
107 return GNUNET_SYSERR;
108 }
109 prev_cpu_load = GNUNET_malloc (cpu_count * sizeof (*prev_cpu_load));
110 for (i = 0; i < cpu_count; i++)
111 {
112 for (j = 0; j < CPU_STATE_MAX; j++)
113 {
114 prev_cpu_load[i].cpu_ticks[j] = cpu_load[i].cpu_ticks[j];
115 }
116 }
117 vm_deallocate (mach_task_self (),
118 (vm_address_t) cpu_load,
119 (vm_size_t) (cpu_msg_count * sizeof (*cpu_load)));
120 return GNUNET_OK;
121}
122#endif
123
124
125/**
126 * Update the currentCPU and currentIO load values.
127 *
128 * Before its first invocation the method initStatusCalls() must be called.
129 * If there is an error the method returns -1.
130 */
131static int
132updateUsage ()
133{
134 currentIOLoad = -1;
135 currentCPULoad = -1;
136#ifdef LINUX
137 /* under linux, first try %idle/usage using /proc/stat;
138 if that does not work, disable /proc/stat for the future
139 by closing the file and use the next-best method. */
140 if (0 == first_time)
141 {
142 first_time = 1;
143 proc_stat = fopen ("/proc/stat", "r");
144 if (NULL == proc_stat)
145 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "fopen", "/proc/stat");
146 }
147 if (proc_stat != NULL)
148 {
149 static unsigned long long last_cpu_results[5] = { 0, 0, 0, 0, 0 };
150 static int have_last_cpu = GNUNET_NO;
151 int ret;
152 char line[256];
153 unsigned long long user_read, system_read, nice_read, idle_read,
154 iowait_read;
155 unsigned long long user, system, nice, idle, iowait;
156 unsigned long long usage_time = 0, total_time = 1;
157
158 /* Get the first line with the data */
159 memset (line, 0, sizeof (line));
160 rewind (proc_stat);
161 fflush (proc_stat);
162 if (NULL == fgets (line, sizeof (line), proc_stat))
163 {
164 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR |
165 GNUNET_ERROR_TYPE_BULK,
166 "fgets", "/proc/stat");
167 fclose (proc_stat);
168 proc_stat = NULL; /* don't try again */
169 }
170 else
171 {
172 iowait_read = 0;
173 ret = sscanf (line, "%*s %llu %llu %llu %llu %llu",
174 &user_read,
175 &system_read, &nice_read, &idle_read, &iowait_read);
176 if (ret < 4)
177 {
178 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR |
179 GNUNET_ERROR_TYPE_BULK,
180 "fgets-sscanf", "/proc/stat");
181 fclose (proc_stat);
182 proc_stat = NULL; /* don't try again */
183 have_last_cpu = GNUNET_NO;
184 }
185 else
186 {
187 /* Store the current usage */
188 user = user_read - last_cpu_results[0];
189 system = system_read - last_cpu_results[1];
190 nice = nice_read - last_cpu_results[2];
191 idle = idle_read - last_cpu_results[3];
192 iowait = iowait_read - last_cpu_results[4];
193 /* Calculate the % usage */
194 usage_time = user + system + nice;
195 total_time = usage_time + idle + iowait;
196 if ((total_time > 0) && (have_last_cpu == GNUNET_YES))
197 {
198 currentCPULoad = (int) (100L * usage_time / total_time);
199 if (ret > 4)
200 currentIOLoad = (int) (100L * iowait / total_time);
201 else
202 currentIOLoad = -1; /* 2.4 kernel */
203 }
204 /* Store the values for the next calculation */
205 last_cpu_results[0] = user_read;
206 last_cpu_results[1] = system_read;
207 last_cpu_results[2] = nice_read;
208 last_cpu_results[3] = idle_read;
209 last_cpu_results[4] = iowait_read;
210 have_last_cpu = GNUNET_YES;
211 return GNUNET_OK;
212 }
213 }
214 }
215#endif
216
217#ifdef DARWIN
218 {
219 unsigned int cpu_count;
220 processor_cpu_load_info_t cpu_load;
221 mach_msg_type_number_t cpu_msg_count;
222 unsigned long long t_sys, t_user, t_nice, t_idle, t_total;
223 unsigned long long t_idle_all, t_total_all;
224 kern_return_t kret;
225 int i, j;
226
227 t_idle_all = t_total_all = 0;
228 kret = host_processor_info (mach_host_self (), PROCESSOR_CPU_LOAD_INFO,
229 &cpu_count,
230 (processor_info_array_t *) & cpu_load,
231 &cpu_msg_count);
232 if (kret == KERN_SUCCESS)
233 {
234 for (i = 0; i < cpu_count; i++)
235 {
236 if (cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] >=
237 prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM])
238 {
239 t_sys = cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] -
240 prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM];
241 }
242 else
243 {
244 t_sys = cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] +
245 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] +
246 1);
247 }
248
249 if (cpu_load[i].cpu_ticks[CPU_STATE_USER] >=
250 prev_cpu_load[i].cpu_ticks[CPU_STATE_USER])
251 {
252 t_user = cpu_load[i].cpu_ticks[CPU_STATE_USER] -
253 prev_cpu_load[i].cpu_ticks[CPU_STATE_USER];
254 }
255 else
256 {
257 t_user = cpu_load[i].cpu_ticks[CPU_STATE_USER] +
258 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_USER] +
259 1);
260 }
261
262 if (cpu_load[i].cpu_ticks[CPU_STATE_NICE] >=
263 prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE])
264 {
265 t_nice = cpu_load[i].cpu_ticks[CPU_STATE_NICE] -
266 prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE];
267 }
268 else
269 {
270 t_nice = cpu_load[i].cpu_ticks[CPU_STATE_NICE] +
271 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE] +
272 1);
273 }
274
275 if (cpu_load[i].cpu_ticks[CPU_STATE_IDLE] >=
276 prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE])
277 {
278 t_idle = cpu_load[i].cpu_ticks[CPU_STATE_IDLE] -
279 prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE];
280 }
281 else
282 {
283 t_idle = cpu_load[i].cpu_ticks[CPU_STATE_IDLE] +
284 (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE] +
285 1);
286 }
287 t_total = t_sys + t_user + t_nice + t_idle;
288 t_idle_all += t_idle;
289 t_total_all += t_total;
290 }
291 for (i = 0; i < cpu_count; i++)
292 {
293 for (j = 0; j < CPU_STATE_MAX; j++)
294 {
295 prev_cpu_load[i].cpu_ticks[j] = cpu_load[i].cpu_ticks[j];
296 }
297 }
298 if (t_total_all > 0)
299 currentCPULoad = 100 - (100 * t_idle_all) / t_total_all;
300 else
301 currentCPULoad = -1;
302 vm_deallocate (mach_task_self (),
303 (vm_address_t) cpu_load,
304 (vm_size_t) (cpu_msg_count * sizeof (*cpu_load)));
305 currentIOLoad = -1; /* There's no IO load meter on darwin */
306 return GNUNET_OK;
307 }
308 else
309 {
310 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
311 "host_processor_info failed.");
312 return GNUNET_SYSERR;
313 }
314 }
315#endif
316 /* try kstat (Solaris only) */
317#if SOLARIS && HAVE_KSTAT_H && HAVE_SYS_SYSINFO_H
318 {
319 static long long last_idlecount;
320 static long long last_totalcount;
321 static int kstat_once; /* if open fails, don't keep
322 trying */
323 kstat_ctl_t *kc;
324 kstat_t *khelper;
325 long long idlecount;
326 long long totalcount;
327 long long deltaidle;
328 long long deltatotal;
329
330 if (kstat_once == 1)
331 goto ABORT_KSTAT;
332 kc = kstat_open ();
333 if (kc == NULL)
334 {
335 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
336 "kstat_open");
337 goto ABORT_KSTAT;
338 }
339
340 idlecount = 0;
341 totalcount = 0;
342 for (khelper = kc->kc_chain; khelper != NULL; khelper = khelper->ks_next)
343 {
344 cpu_stat_t stats;
345
346 if (0 != strncmp (khelper->ks_name, "cpu_stat", strlen ("cpu_stat")))
347 continue;
348 if (khelper->ks_data_size > sizeof (cpu_stat_t))
349 continue; /* better save then sorry! */
350 if (-1 != kstat_read (kc, khelper, &stats))
351 {
352 idlecount += stats.cpu_sysinfo.cpu[CPU_IDLE];
353 totalcount
354 += stats.cpu_sysinfo.cpu[CPU_IDLE] +
355 stats.cpu_sysinfo.cpu[CPU_USER] +
356 stats.cpu_sysinfo.cpu[CPU_KERNEL] +
357 stats.cpu_sysinfo.cpu[CPU_WAIT];
358 }
359 }
360 if (0 != kstat_close (kc))
361 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
362 "kstat_close");
363 if ((idlecount == 0) && (totalcount == 0))
364 goto ABORT_KSTAT; /* no stats found => abort */
365 deltaidle = idlecount - last_idlecount;
366 deltatotal = totalcount - last_totalcount;
367 if ((deltatotal > 0) && (last_totalcount > 0))
368 {
369 currentCPULoad = (unsigned int) (100.0 * deltaidle / deltatotal);
370 if (currentCPULoad > 100)
371 currentCPULoad = 100; /* odd */
372 if (currentCPULoad < 0)
373 currentCPULoad = 0; /* odd */
374 currentCPULoad = 100 - currentCPULoad; /* computed idle-load before! */
375 }
376 else
377 currentCPULoad = -1;
378 currentIOLoad = -1; /* FIXME-SOLARIS! */
379 last_idlecount = idlecount;
380 last_totalcount = totalcount;
381 return GNUNET_OK;
382 ABORT_KSTAT:
383 kstat_once = 1; /* failed, don't try again */
384 return GNUNET_SYSERR;
385 }
386#endif
387
388 /* insert methods better than getloadavg for
389 other platforms HERE! */
390
391 /* ok, maybe we have getloadavg on this platform */
392#if HAVE_GETLOADAVG
393 {
394 static int warnOnce = 0;
395 double loadavg;
396 if (1 != getloadavg (&loadavg, 1))
397 {
398 /* only warn once, if there is a problem with
399 getloadavg, we're going to hit it frequently... */
400 if (warnOnce == 0)
401 {
402 warnOnce = 1;
403 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "getloadavg");
404 }
405 return GNUNET_SYSERR;
406 }
407 else
408 {
409 /* success with getloadavg */
410 currentCPULoad = (int) (100 * loadavg);
411 currentIOLoad = -1; /* FIXME */
412 return GNUNET_OK;
413 }
414 }
415#endif
416
417#if MINGW
418 /* Win NT? */
419 if (GNNtQuerySystemInformation)
420 {
421 static double dLastKernel;
422 static double dLastIdle;
423 static double dLastUser;
424 double dKernel;
425 double dIdle;
426 double dUser;
427 double dDiffKernel;
428 double dDiffIdle;
429 double dDiffUser;
430 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION theInfo;
431
432 if (GNNtQuerySystemInformation (SystemProcessorPerformanceInformation,
433 &theInfo,
434 sizeof (theInfo), NULL) == NO_ERROR)
435 {
436 /* PORT-ME MINGW: Multi-processor? */
437 dKernel = Li2Double (theInfo.KernelTime);
438 dIdle = Li2Double (theInfo.IdleTime);
439 dUser = Li2Double (theInfo.UserTime);
440 dDiffKernel = dKernel - dLastKernel;
441 dDiffIdle = dIdle - dLastIdle;
442 dDiffUser = dUser - dLastUser;
443
444 if (((dDiffKernel + dDiffUser) > 0) &&
445 (dLastIdle + dLastKernel + dLastUser > 0))
446 currentCPULoad =
447 100.0 - (dDiffIdle / (dDiffKernel + dDiffUser)) * 100.0;
448 else
449 currentCPULoad = -1; /* don't know (yet) */
450
451 dLastKernel = dKernel;
452 dLastIdle = dIdle;
453 dLastUser = dUser;
454
455 currentIOLoad = -1; /* FIXME-MINGW */
456 return GNUNET_OK;
457 }
458 else
459 {
460 /* only warn once, if there is a problem with
461 NtQuery..., we're going to hit it frequently... */
462 static int once;
463 if (once == 0)
464 {
465 once = 1;
466 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
467 _("Cannot query the CPU usage (Windows NT).\n"));
468 }
469 return GNUNET_SYSERR;
470 }
471 }
472 else
473 { /* Win 9x */
474 HKEY hKey;
475 DWORD dwDataSize, dwType, dwDummy;
476
477 /* Start query */
478 if (RegOpenKeyEx (HKEY_DYN_DATA,
479 "PerfStats\\StartSrv",
480 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
481 {
482 /* only warn once */
483 static int once = 0;
484 if (once == 0)
485 {
486 once = 1;
487 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
488 _("Cannot query the CPU usage (Win 9x)\n"));
489 }
490 }
491
492 RegOpenKeyEx (HKEY_DYN_DATA,
493 "PerfStats\\StartStat", 0, KEY_ALL_ACCESS, &hKey);
494 dwDataSize = sizeof (dwDummy);
495 RegQueryValueEx (hKey,
496 "KERNEL\\CPUUsage",
497 NULL, &dwType, (LPBYTE) & dwDummy, &dwDataSize);
498 RegCloseKey (hKey);
499
500 /* Get CPU usage */
501 RegOpenKeyEx (HKEY_DYN_DATA,
502 "PerfStats\\StatData", 0, KEY_ALL_ACCESS, &hKey);
503 dwDataSize = sizeof (currentCPULoad);
504 RegQueryValueEx (hKey,
505 "KERNEL\\CPUUsage",
506 NULL, &dwType, (LPBYTE) & currentCPULoad, &dwDataSize);
507 RegCloseKey (hKey);
508 currentIOLoad = -1; /* FIXME-MINGW! */
509
510 /* Stop query */
511 RegOpenKeyEx (HKEY_DYN_DATA,
512 "PerfStats\\StopStat", 0, KEY_ALL_ACCESS, &hKey);
513 RegOpenKeyEx (HKEY_DYN_DATA,
514 "PerfStats\\StopSrv", 0, KEY_ALL_ACCESS, &hKey);
515 dwDataSize = sizeof (dwDummy);
516 RegQueryValueEx (hKey,
517 "KERNEL\\CPUUsage",
518 NULL, &dwType, (LPBYTE) & dwDummy, &dwDataSize);
519 RegCloseKey (hKey);
520
521 return GNUNET_OK;
522 }
523#endif
524
525 /* loadaverage not defined and no platform
526 specific alternative defined
527 => default: error
528 */
529 return GNUNET_SYSERR;
530}
531
532/**
533 * Update load values (if enough time has expired),
534 * including computation of averages. Code assumes
535 * that lock has already been obtained.
536 */
537static void
538updateAgedLoad (const struct GNUNET_CONFIGURATION_Handle *cfg)
539{
540 static struct GNUNET_TIME_Absolute lastCall;
541
542 if ((agedCPULoad == -1)
543 || (GNUNET_TIME_absolute_get_duration (lastCall).value > 500))
544 {
545 /* use smoothing, but do NOT update lastRet at frequencies higher
546 than 500ms; this makes the smoothing (mostly) independent from
547 the frequency at which getCPULoad is called (and we don't spend
548 more time measuring CPU than actually computing something). */
549 lastCall = GNUNET_TIME_absolute_get ();
550 updateUsage ();
551 if (currentCPULoad == -1)
552 {
553 agedCPULoad = -1;
554 }
555 else
556 {
557 if (agedCPULoad == -1)
558 {
559 agedCPULoad = currentCPULoad;
560 }
561 else
562 {
563 /* for CPU, we don't do the 'fast increase' since CPU is much
564 more jitterish to begin with */
565 agedCPULoad = (agedCPULoad * 31 + currentCPULoad) / 32;
566 }
567 }
568 if (currentIOLoad == -1)
569 {
570 agedIOLoad = -1;
571 }
572 else
573 {
574 if (agedIOLoad == -1)
575 {
576 agedIOLoad = currentIOLoad;
577 }
578 else
579 {
580 /* for IO, we don't do the 'fast increase' since IO is much
581 more jitterish to begin with */
582 agedIOLoad = (agedIOLoad * 31 + currentIOLoad) / 32;
583 }
584 }
585 }
586}
587
588/**
589 * Get the load of the CPU relative to what is allowed.
590 * @return the CPU load as a percentage of allowed
591 * (100 is equivalent to full load)
592 */
593int
594GNUNET_OS_load_cpu_get (const struct GNUNET_CONFIGURATION_Handle *cfg)
595{
596 unsigned long long maxCPULoad;
597 int ret;
598
599 updateAgedLoad (cfg);
600 ret = agedCPULoad;
601 if (ret == -1)
602 return -1;
603 if (GNUNET_OK !=
604 GNUNET_CONFIGURATION_get_value_number (cfg, "LOAD", "MAXCPULOAD",
605 &maxCPULoad))
606 return GNUNET_SYSERR;
607 if (maxCPULoad == 0)
608 return 100;
609 return (100 * ret) / maxCPULoad;
610}
611
612
613/**
614 * Get the load of the CPU relative to what is allowed.
615 * @return the CPU load as a percentage of allowed
616 * (100 is equivalent to full load)
617 */
618int
619GNUNET_OS_load_disk_get (const struct GNUNET_CONFIGURATION_Handle *cfg)
620{
621 unsigned long long maxIOLoad;
622 int ret;
623
624 updateAgedLoad (cfg);
625 ret = agedIOLoad;
626 if (ret == -1)
627 return -1;
628 if (-1 ==
629 GNUNET_CONFIGURATION_get_value_number (cfg, "LOAD", "MAXIOLOAD",
630 &maxIOLoad))
631 return GNUNET_SYSERR;
632 if (maxIOLoad == 0)
633 return 100;
634 return (100 * ret) / maxIOLoad;
635}
636
637/**
638 * The following method is called in order to initialize the status calls
639 * routines. After that it is safe to call each of the status calls separately
640 * @return GNUNET_OK on success and GNUNET_SYSERR on error (or calls errexit).
641 */
642void __attribute__ ((constructor)) GNUNET_cpustats_ltdl_init ()
643{
644#ifdef LINUX
645 updateUsage (); /* initialize */
646 /* Most GNUnet processes don't really need this, so close the FD, but allow
647 re-opening it (unless we failed) */
648 if (proc_stat != NULL)
649 {
650 GNUNET_break (0 == fclose (proc_stat));
651 proc_stat = NULL;
652 first_time = 0;
653 }
654#elif defined(DARWIN)
655 initMachCpuStats ();
656 updateUsage (); /* initialize */
657#elif MINGW
658 GNInitWinEnv (NULL);
659 updateUsage (); /* initialize */
660#else
661 updateUsage (); /* initialize */
662#endif
663}
664
665/**
666 * Shutdown the status calls module.
667 */
668void __attribute__ ((destructor)) GNUNET_cpustats_ltdl_fini ()
669{
670#ifdef LINUX
671 if (proc_stat != NULL)
672 {
673 fclose (proc_stat);
674 proc_stat = NULL;
675 }
676#elif defined(DARWIN)
677 GNUNET_free_non_null (prev_cpu_load);
678#elif MINGW
679 GNShutdownWinEnv ();
680#endif
681}
682
683
684/* end of os_load.c */
diff --git a/src/util/test_os_load.c b/src/util/test_os_load.c
deleted file mode 100644
index a5639b048..000000000
--- a/src/util/test_os_load.c
+++ /dev/null
@@ -1,184 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2003, 2004, 2005, 2006, 2009 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 3, 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 * @file util/test_os_load.c
22 * @brief testcase for util/os_load.c
23 */
24#include "platform.h"
25#include "gnunet_common.h"
26#include "gnunet_configuration_lib.h"
27#include "gnunet_crypto_lib.h"
28#include "gnunet_disk_lib.h"
29#include "gnunet_os_lib.h"
30#include "gnunet_time_lib.h"
31
32#define VERBOSE 0
33
34static int
35testcpu ()
36{
37 static long k;
38 int ret;
39 struct GNUNET_TIME_Absolute start;
40 struct GNUNET_CONFIGURATION_Handle *cfg;
41
42 fprintf (stderr, "CPU load test, this may take a while.");
43 cfg = GNUNET_CONFIGURATION_create ();
44 GNUNET_assert (cfg != NULL);
45 /* need to run each phase for more than 10s since
46 statuscalls only refreshes that often... */
47 GNUNET_CONFIGURATION_set_value_number (cfg, "LOAD", "MAXCPULOAD", 100);
48 GNUNET_OS_load_cpu_get (cfg);
49 start = GNUNET_TIME_absolute_get ();
50 while ((GNUNET_TIME_absolute_get_duration (start).value < 120 * 1000) &&
51 (0 != GNUNET_OS_load_cpu_get (cfg)))
52 sleep (1);
53 start = GNUNET_TIME_absolute_get ();
54 ret = GNUNET_OS_load_cpu_get (cfg);
55 if (ret > 10)
56 {
57 fprintf (stderr,
58 "\nWARNING: base load too high (%d) to run CPU load test.\n",
59 ret);
60 GNUNET_CONFIGURATION_destroy (cfg);
61 return 0;
62 }
63 if (ret == -1)
64 {
65 fprintf (stderr, "\nWARNING: CPU load determination not supported.\n");
66 GNUNET_CONFIGURATION_destroy (cfg);
67 return 0;
68 }
69 while (GNUNET_TIME_absolute_get_duration (start).value < 60 * 1000)
70 {
71 k++; /* do some processing to drive load up */
72 if (ret < GNUNET_OS_load_cpu_get (cfg))
73 break;
74 }
75 if (ret >= GNUNET_OS_load_cpu_get (cfg))
76 {
77 fprintf (stderr,
78 "\nbusy loop failed to increase CPU load: %d >= %d.",
79 ret, GNUNET_OS_load_cpu_get (cfg));
80 }
81 else
82 {
83#if VERBOSE
84 fprintf (stderr,
85 "\nbusy loop increased CPU load: %d < %d.",
86 ret, GNUNET_OS_load_cpu_get (cfg));
87#endif
88 }
89 fprintf (stderr, "\n");
90
91
92 GNUNET_CONFIGURATION_destroy (cfg);
93 return 0;
94}
95
96static int
97testdisk ()
98{
99 int ret;
100 struct GNUNET_DISK_FileHandle *fh;
101 char buf[65536];
102 struct GNUNET_TIME_Absolute start;
103 struct GNUNET_CONFIGURATION_Handle *cfg;
104
105 fprintf (stderr, "IO load test, this may take a while.");
106 cfg = GNUNET_CONFIGURATION_create ();
107 GNUNET_assert (cfg != NULL);
108 /* need to run each phase for more than 10s since
109 statuscalls only refreshes that often... */
110 GNUNET_CONFIGURATION_set_value_number (cfg, "LOAD", "MAXIOLOAD", 100);
111 GNUNET_OS_load_disk_get (cfg);
112 start = GNUNET_TIME_absolute_get ();
113 while ((GNUNET_TIME_absolute_get_duration (start).value < 12 * 1000) &&
114 (0 != GNUNET_OS_load_disk_get (cfg)))
115 sleep (1);
116 start = GNUNET_TIME_absolute_get ();
117 ret = GNUNET_OS_load_disk_get (cfg);
118 if (ret > 10)
119 {
120 fprintf (stderr,
121 "WARNING: base load too high (%d) to run IO load test.\n",
122 ret);
123 GNUNET_CONFIGURATION_destroy (cfg);
124 return 0;
125 }
126 if (ret == -1)
127 {
128 fprintf (stderr, "WARNING: IO load determination not supported.\n");
129 GNUNET_CONFIGURATION_destroy (cfg);
130 return 0;
131 }
132 memset (buf, 42, sizeof (buf));
133 fh = GNUNET_DISK_file_open (".loadfile", GNUNET_DISK_OPEN_WRITE
134 | GNUNET_DISK_OPEN_CREATE,
135 GNUNET_DISK_PERM_USER_READ |
136 GNUNET_DISK_PERM_USER_WRITE);
137 GNUNET_assert (GNUNET_NO == GNUNET_DISK_handle_invalid (fh));
138 while (GNUNET_TIME_absolute_get_duration (start).value < 60 * 1000)
139 {
140 GNUNET_DISK_file_seek (fh,
141 GNUNET_CRYPTO_random_u64
142 (GNUNET_CRYPTO_QUALITY_WEAK, 1024 * 1024 * 1024),
143 GNUNET_DISK_SEEK_SET);
144 GNUNET_assert (sizeof (buf) ==
145 GNUNET_DISK_file_write (fh, buf, sizeof (buf)));
146 GNUNET_DISK_file_sync (fh);
147 if (ret < GNUNET_OS_load_disk_get (cfg))
148 break;
149 }
150 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fh));
151 GNUNET_break (0 == UNLINK (".loadfile"));
152 if (ret >= GNUNET_OS_load_disk_get (cfg))
153 {
154 fprintf (stderr,
155 "\nbusy loop failed to increase IO load: %d >= %d.",
156 ret, GNUNET_OS_load_disk_get (cfg));
157 ret = 0;
158 }
159 else
160 {
161#if VERBOSE
162 fprintf (stderr,
163 "\nbusy loop increased disk load: %d < %d.",
164 ret, GNUNET_OS_load_disk_get (cfg));
165#endif
166 ret = 0;
167 }
168 fprintf (stderr, "\n");
169 GNUNET_CONFIGURATION_destroy (cfg);
170 return ret;
171}
172
173int
174main (int argc, char *argv[])
175{
176 int errCnt = 0;
177
178 GNUNET_log_setup ("test-os-load", "WARNING", NULL);
179 if (0 != testcpu ())
180 errCnt++;
181 if (0 != testdisk ())
182 errCnt++;
183 return errCnt;
184}