1 #include "config.h"
2 #undef NDEBUG
3 #include <assert.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <memory.h>
7 #include <strings.h>
8 #include <string.h>
9 #include <ctype.h>
10 #include <time.h>
11 #include <sys/time.h>
12 #include <sys/stat.h>
13 #ifdef HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16
17 #ifdef HAVE_SYSINFO
18 #include <sys/sysinfo.h>
19 #endif
20
21 #ifdef HAVE_MAC_SYSCTL
22 #include <sys/types.h>
23 #include <sys/sysctl.h>
24 #include <sys/socketvar.h>
25 #include <netinet/ip.h>
26 #include <netinet/ip_var.h>
27 #include <netinet/tcp.h>
28 #include <netinet/tcp_var.h>
29 #include <net/if.h>
30 #endif
31
32 #ifdef HAVE_UNAME
33 #include <sys/utsname.h>
34 #endif
35
36 #include "evpath.h"
37 #include "cm_internal.h"
38 #include "cod.h"
39 #include <fcntl.h>
40
41 /*#define CPU_FREQ_SCALING_MAX_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"*/
42 /*#define CPU_FREQ_SCALING_MIN_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq"*/
43 /*#define CPU_FREQ_SCALING_CUR_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"*/
44 /*#define CPU_FREQ_SCALING_AVAILABLE_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies"*/
45
46 /*#define CPU_FREQ_SCALING_GOVERNOR "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"*/
47 /*#define CPU_FREQ_SCALING_AVAILABLE_GOVERNORS "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors"*/
48
49 /*#define CPU_FREQ_AFFECTED_CPU "/sys/devices/system/cpu/cpu0/cpufreq/affected_cpus"*/
50
51 /*#define CPU_FREQ_ONDEMAND_SAMPLING_RATE_MIN "/sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate_min"*/
52 /*#define CPU_FREQ_ONDEMAND_SAMPLING_RATE_MAX "/sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate_max"*/
53 /*#define CPU_FREQ_ONDEMAND_SAMPLING_RATE "/sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate"*/
54 /*#define CPU_FREQ_ONDEMAND_UP_THRESHOLD "/sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold"*/
55 /*#define CPU_FREQ_ONDEMAND_IGNORE_NICE_LOAD "/sys/devices/system/cpu/cpu0/cpufreq/ondemand/ignore_nice_load"*/
56 /*#define CPU_FREQ_ONDEMAND_POWERSAVE_BIAD "/sys/devices/system/cpu/cpu0/cpufreq/ondemand/powersave_bias"*/
57
58 typedef struct sensor_slurp {
59 const char *name;
60 char buffer[8192];
61 } sensor_slurp, *sensor_slurp_ptr;
62
63 /*sensor_slurp proc_stat = { "/proc/stat" };*/
64 /*sensor_slurp proc_loadavg = { "/proc/loadavg" };*/
65 /*sensor_slurp proc_meminfo = { "/proc/meminfo" };*/
66 /*sensor_slurp proc_net_dev = { "/proc/net/dev" };*/
67
skip_whitespace(const char * p)68 char * skip_whitespace (const char *p)
69 {
70 while (isspace((unsigned char)*p)) p++;
71 return (char *)p;
72 }
73
skip_token(const char * p)74 char * skip_token (const char *p)
75 {
76 while (isspace((unsigned char)*p)) p++;
77 while (*p && !isspace((unsigned char)*p)) p++;
78 return (char *)p;
79 }
80
slurpfile(const char * filename,char * buffer,int buflen)81 int slurpfile(const char *filename, char *buffer, int buflen)
82 {
83 int fd, read_len;
84
85 fd = open(filename, O_RDONLY);
86 if(fd < 0) {
87 printf("open() error on file %s \n", filename);
88 exit(0);
89 }
90 read_len = read(fd, buffer, buflen);
91 if(read_len <= 0) {
92 printf("read() error on file %s \n", filename);
93 exit(0);
94 }
95 if (read_len == buflen) {
96 --read_len;
97 printf("slurpfile() read() buffer overflow on file %s", filename);
98 }
99 buffer[read_len] = '\0';
100 close(fd);
101 return read_len;
102 }
103
update_file(struct sensor_slurp * sf)104 char *update_file(struct sensor_slurp *sf) {
105 (void) slurpfile(sf->name, &sf->buffer[0], 8192);
106 return sf->buffer;
107 }
108
num_cpustates_func(void)109 unsigned int num_cpustates_func ( void ) {
110 char *p;
111 unsigned int i=0;
112
113 sensor_slurp proc_stat = { "/proc/stat" };
114 p = update_file(&proc_stat);
115
116 /**
117 ** Skip initial "cpu" token
118 **/
119 p = skip_token(p);
120 p = skip_whitespace(p);
121 /*
122 ** Loop over file until next "cpu" token is found.
123 ** i=4 : Linux 2.4.x
124 ** i=7 : Linux 2.6.x
125 */
126 while (strncmp(p,"cpu",3)) {
127 p = skip_token(p);
128 p = skip_whitespace(p);
129 i++;
130 }
131
132 return i;
133 }
134
total_jiffies_func(void)135 unsigned long total_jiffies_func ( void ) {
136
137 char *p;
138 unsigned long user_jiffies, nice_jiffies, system_jiffies, idle_jiffies,
139 wio_jiffies, irq_jiffies, sirq_jiffies;
140
141 sensor_slurp proc_stat = { "/proc/stat" };
142 p = update_file(&proc_stat);
143 p = skip_token(p);
144 p = skip_whitespace(p);
145 user_jiffies = (unsigned int)strtod( p, &p );
146 p = skip_whitespace(p);
147 nice_jiffies = (unsigned int)strtod( p, &p );
148 p = skip_whitespace(p);
149 system_jiffies = (unsigned int)strtod( p , &p );
150 p = skip_whitespace(p);
151 idle_jiffies = (unsigned int)strtod( p , &p );
152
153 int num_cpustates = num_cpustates_func();
154 if(num_cpustates == 4) /*NUM_CPUSTATES_24X*/
155 return user_jiffies + nice_jiffies + system_jiffies + idle_jiffies;
156
157 p = skip_whitespace(p);
158 wio_jiffies = (unsigned int)strtod( p , &p );
159 p = skip_whitespace(p);
160 irq_jiffies = (unsigned int)strtod( p , &p );
161 p = skip_whitespace(p);
162 sirq_jiffies = (unsigned int)strtod( p , &p );
163
164 return user_jiffies + nice_jiffies + system_jiffies + idle_jiffies +
165 wio_jiffies + irq_jiffies + sirq_jiffies;
166 }
167
cpu_and_core_usage_func(double usage[])168 void cpu_and_core_usage_func (double usage[])
169 {
170 char *p;
171 int n, numcores, i;
172 numcores = num_cpustates_func();
173 n = numcores + 1;
174 unsigned long user_jiffies[n], last_user_jiffies[n], nice_jiffies[n], last_nice_jiffies[n], system_jiffies[n], last_system_jiffies[n], idle_jiffies[n], last_idle_jiffies[n], wio_jiffies[n], last_wio_jiffies[n], irq_jiffies[n], last_irq_jiffies[n], sirq_jiffies[n], last_sirq_jiffies[n], delta_busy[n], delta_total[n];
175 sensor_slurp proc_stat = { "/proc/stat" };
176 p = update_file(&proc_stat);
177 p = skip_token(p);
178 p = skip_whitespace(p);
179 for(i=0;i<n;++i)
180 {
181 user_jiffies[i] = (unsigned int)strtod( p, &p );
182 p = skip_whitespace(p);
183 nice_jiffies[i] = (unsigned int)strtod( p, &p );
184 p = skip_whitespace(p);
185 system_jiffies[i] = (unsigned int)strtod( p , &p );
186 p = skip_whitespace(p);
187 idle_jiffies[i] = (unsigned int)strtod( p , &p );
188 p = skip_whitespace(p);
189 wio_jiffies[i] = (unsigned int)strtod( p , &p );
190 p = skip_whitespace(p);
191 irq_jiffies[i] = (unsigned int)strtod( p , &p );
192 p = skip_whitespace(p);
193 sirq_jiffies[i] = (unsigned int)strtod( p , &p );
194 p = skip_whitespace(p);
195 delta_busy[i] = (user_jiffies[i] - last_user_jiffies[i]) + (nice_jiffies[i] - last_nice_jiffies[i]) + (system_jiffies[i] - last_system_jiffies[i]);
196 delta_total[i] = delta_busy[i] + (idle_jiffies[i] - last_idle_jiffies[i]) + (wio_jiffies[i] - last_wio_jiffies[i]) + (irq_jiffies[i] - last_irq_jiffies[i]) + (sirq_jiffies[i] - last_sirq_jiffies[i]);
197 usage[i] = (double) delta_busy[i] / (double) delta_total[i] ;
198 last_user_jiffies[i] = user_jiffies[i];
199 last_nice_jiffies[i] = nice_jiffies[i];
200 last_system_jiffies[i] = system_jiffies[i];
201 last_idle_jiffies[i] = idle_jiffies[i];
202 last_wio_jiffies[i] = wio_jiffies[i];
203 last_irq_jiffies[i] = irq_jiffies[i];
204 last_sirq_jiffies[i] = sirq_jiffies[i];
205 while (strncmp(p,"cpu",3)) {
206 p = skip_token(p);
207 p = skip_whitespace(p);
208 }
209 p = skip_token(p);
210 p = skip_whitespace(p);
211
212 }
213
214 }
215
cpu_user_func(void)216 double cpu_user_func ( void )
217 {
218 char *p;
219 double val;
220 static double last_user_jiffies, last_total_jiffies;
221 double user_jiffies, total_jiffies, diff;
222
223 sensor_slurp proc_stat = { "/proc/stat" };
224 p = update_file(&proc_stat);
225
226 p = skip_token(p);
227 user_jiffies = strtod( p , (char **)NULL );
228 total_jiffies = (double) total_jiffies_func();
229
230 diff = user_jiffies - last_user_jiffies;
231
232 if ( diff )
233 val = (diff/(total_jiffies - last_total_jiffies))*100;
234 else
235 val = 0.0;
236
237 last_user_jiffies = user_jiffies;
238 last_total_jiffies = total_jiffies;
239
240 return val;
241 }
242
cpu_nice_func(void)243 double cpu_nice_func ( void )
244 {
245 char *p;
246 double val;
247 static double last_nice_jiffies, last_total_jiffies;
248 double nice_jiffies, total_jiffies, diff;
249
250 sensor_slurp proc_stat = { "/proc/stat" };
251 p = update_file(&proc_stat);
252
253 p = skip_token(p);
254 p = skip_token(p);
255 nice_jiffies = strtod( p , (char **)NULL );
256 total_jiffies = (double) total_jiffies_func();
257
258 diff = (nice_jiffies - last_nice_jiffies);
259
260 if ( diff )
261 val = (diff/(total_jiffies - last_total_jiffies))*100;
262 else
263 val = 0.0;
264
265 last_nice_jiffies = nice_jiffies;
266 last_total_jiffies = total_jiffies;
267
268 return val;
269 }
270
cpu_system_func(void)271 double cpu_system_func ( void )
272 {
273 char *p;
274 static double val;
275 static double last_system_jiffies, system_jiffies,
276 last_total_jiffies, total_jiffies, diff;
277
278 sensor_slurp proc_stat = { "/proc/stat" };
279 p = update_file(&proc_stat);
280 p = skip_token(p);
281 p = skip_token(p);
282 p = skip_token(p);
283 system_jiffies = strtod( p , (char **)NULL );
284 int num_cpustates = num_cpustates_func();
285 if (num_cpustates > 4 ) /*NUM_CPUSTATES_24X)*/ {
286 p = skip_token(p);
287 p = skip_token(p);
288 p = skip_token(p);
289 system_jiffies += strtod( p , (char **)NULL ); /* "intr" counted in system */
290 p = skip_token(p);
291 system_jiffies += strtod( p , (char **)NULL ); /* "sintr" counted in system */
292 }
293 total_jiffies = (double) total_jiffies_func();
294
295 diff = system_jiffies - last_system_jiffies;
296
297 if ( diff )
298 val = (diff/(total_jiffies - last_total_jiffies))*100;
299 else
300 val = 0.0;
301
302 last_system_jiffies = system_jiffies;
303 last_total_jiffies = total_jiffies;
304
305 return val;
306 }
307
cpu_idle_func(void)308 double cpu_idle_func ( void )
309 {
310 char *p;
311 static double val;
312 static double last_idle_jiffies, idle_jiffies,
313 last_total_jiffies, total_jiffies, diff;
314
315 sensor_slurp proc_stat = { "/proc/stat" };
316 p = update_file(&proc_stat);
317
318 p = skip_token(p);
319 p = skip_token(p);
320 p = skip_token(p);
321 p = skip_token(p);
322 idle_jiffies = strtod( p , (char **)NULL );
323 total_jiffies = (double) total_jiffies_func();
324
325 diff = idle_jiffies - last_idle_jiffies;
326
327 if ( diff )
328 val = (diff/(total_jiffies - last_total_jiffies))*100;
329 else
330 val = 0.0;
331 last_idle_jiffies = idle_jiffies;
332 last_total_jiffies = total_jiffies;
333 return val;
334 }
335
336 /**************NET FUNCTIONS*****************/
received_bytes(char * interface)337 long received_bytes(char *interface)
338 {
339 static long r_bytes=0;
340 #ifdef HAVE_MAC_SYSCTL
341 char *buf = NULL, *lim, *next;
342 static int mib[6];
343 size_t mlen,vlen;
344 struct if_msghdr *ifm;
345 unsigned int ifindex;
346 mib[0] = CTL_NET;
347 mib[1] = PF_ROUTE;
348 mib[2] = 0;
349 mib[3] = 0;
350 mib[4] = NET_RT_IFLIST;
351 mib[5] = 0;
352
353 mlen = 6;
354 ifindex = if_nametoindex(interface);
355 sysctl(mib,mlen,NULL,&vlen,NULL,0);
356 buf = malloc(vlen);
357 sysctl(mib,mlen,buf,&vlen,NULL,0);
358 lim = buf+vlen;
359 for(next = buf; next < lim; )
360 {
361 ifm = (struct if_msghdr *)next;
362 next += ifm->ifm_msglen;
363 // printf("Index %d, ifm index %d\n",ifindex,ifm->ifm_index);
364 // printf("ibytes %ld\n",ifm->ifm_data.ifi_ibytes);
365 if(ifindex == ifm->ifm_index)
366 {
367 //printf("Correct interface\n");
368 r_bytes = (long) ifm->ifm_data.ifi_ibytes;
369 break;
370 }
371 }
372 //printf("Received bytes %ld\n",r_bytes);
373 free(buf);
374
375 #else
376 char *temp_if;
377 char *p;
378 if(interface == NULL)
379 temp_if = strdup("eth0");
380 else
381 temp_if = strdup((const char *)interface);
382 sensor_slurp proc_net = { "/proc/net/dev" };
383 p = update_file(&proc_net);
384 while (p && strncmp(p,temp_if,strlen(temp_if)))
385 {
386 p = skip_token(p);
387 p = skip_whitespace(p);
388 }
389
390 p = skip_token(p);
391 p = skip_whitespace(p);
392 r_bytes = strtol( p ,NULL,10);
393 free(temp_if);
394 #endif // end HAVE_MAC_SYSCTL
395 return r_bytes;
396 }
397
sent_bytes(char * interface)398 long sent_bytes(char *interface)
399 {
400 long s_bytes;
401 #ifdef HAVE_MAC_SYSCTL
402
403 char *buf = NULL, *lim, *next;
404 static int mib[6];
405 size_t mlen,vlen;
406 struct if_msghdr *ifm;
407 unsigned int ifindex;
408 mib[0] = CTL_NET;
409 mib[1] = PF_ROUTE;
410 mib[2] = 0;
411 mib[3] = 0;
412 mib[4] = NET_RT_IFLIST;
413 mib[5] = 0;
414
415 mlen = 6;
416 ifindex = if_nametoindex(interface);
417 sysctl(mib,mlen,NULL,&vlen,NULL,0);
418 buf = malloc(vlen);
419 sysctl(mib,mlen,buf,&vlen,NULL,0);
420 lim = buf+vlen;
421 for(next = buf; next < lim; )
422 {
423 ifm = (struct if_msghdr *)next;
424 next += ifm->ifm_msglen;
425 if(ifindex == ifm->ifm_index)
426 {
427 // printf("Correct interface\n");
428 s_bytes = (long) ifm->ifm_data.ifi_obytes;
429 break;
430 }
431 }
432 // printf("Sent bytes %ld\n",s_bytes);
433 free(buf);
434 #else
435
436 char *temp_if;
437 char *p;
438 int i=0;
439 if(interface == NULL)
440 temp_if = strdup("eth0");
441 else
442 temp_if = strdup((const char *)interface);
443 sensor_slurp proc_net = { "/proc/net/dev" };
444 p = update_file(&proc_net);
445 while (p && strncmp(p,temp_if,strlen(temp_if)))
446 {
447 p = skip_token(p);
448 p = skip_whitespace(p);
449 }
450 while(i <= 8) {
451 p = skip_token(p);
452 p = skip_whitespace(p);
453 ++i;
454 }
455 s_bytes = strtol (p, NULL,10);
456 free(temp_if);
457 #endif // end HAVE_MAC_SYSCTL
458 return s_bytes;
459
460
461 }
462 /*
463 * This function returns the bandwidth of the network(in bits per second) as sampled over a certain window of time.
464 * stage can be "start" where the network sampling begins, and at stage end the monitored network
465 * bandwidth is returned. On OS X the two calls have to be atleast 425 microseconds apart.
466 * */
467
net_bw(char * interface,char * stage)468 double net_bw(char *interface, char *stage)
469 {
470 static long old_s_bytes, new_s_bytes, old_r_bytes, new_r_bytes, start_time, end_time;
471 long s_bytes, r_bytes;
472 struct timeval t;
473 double net_bw;
474 #ifdef HAVE_MAC_SYSCTL
475 char *buf = NULL, *lim, *next;
476 static int mib[6];
477 size_t mlen,vlen;
478 struct if_msghdr *ifm;
479 unsigned int ifindex;
480 mib[0] = CTL_NET;
481 mib[1] = PF_ROUTE;
482 mib[2] = 0;
483 mib[3] = 0;
484 mib[4] = NET_RT_IFLIST;
485 mib[5] = 0;
486
487 mlen = 6;
488 ifindex = if_nametoindex(interface);
489 sysctl(mib,mlen,NULL,&vlen,NULL,0);
490 buf = malloc(vlen);
491 sysctl(mib,mlen,buf,&vlen,NULL,0);
492 lim = buf+vlen;
493 for(next = buf; next < lim; )
494 {
495 ifm = (struct if_msghdr *)next;
496 next += ifm->ifm_msglen;
497 // printf("Index %d, ifm index %d\n",ifindex,ifm->ifm_index);
498 // printf("ibytes %ld\n",ifm->ifm_data.ifi_ibytes);
499 if(ifindex == ifm->ifm_index)
500 {
501 // printf("Correct interface\n");
502 r_bytes = (long) ifm->ifm_data.ifi_ibytes;
503 s_bytes = (long) ifm->ifm_data.ifi_obytes;
504 break;
505 }
506 }
507 // printf("Received bytes %ld Sent bytes %ld\n",r_bytes,s_bytes);
508 free(buf);
509
510 #else
511
512 int i=0;
513 char *temp_if;
514 char *p;
515
516 if(interface == NULL)
517 temp_if = strdup("eth0");
518 else
519 temp_if = strdup((const char*)interface);
520 sensor_slurp proc_net = { "/proc/net/dev" };
521 p = update_file(&proc_net);
522 gettimeofday(&t,NULL);
523
524 while (p && strncmp(p,temp_if,strlen(temp_if)))
525 {
526 p = skip_token(p);
527 p = skip_whitespace(p);
528 }
529
530 p = skip_token(p);
531 p = skip_whitespace(p);
532 r_bytes = strtol( p ,NULL,10);
533 while(i <= 7) {
534 p = skip_token(p);
535 p = skip_whitespace(p);
536 ++i;
537 }
538 s_bytes = strtol (p, NULL,10);
539 free(temp_if);
540 #endif // end HAVE_MAC_SYSCTL
541 if(strncmp(stage,"start",3)==0)
542 {
543 printf("Start %ld %ld \n",s_bytes,r_bytes);
544
545 old_s_bytes = s_bytes;
546 old_r_bytes = r_bytes;
547 start_time = t.tv_sec * 1000000 + t.tv_usec;
548
549 return 0.0;
550 }
551 printf("End %ld %ld \n",s_bytes,r_bytes);
552 new_s_bytes = s_bytes;
553 new_r_bytes = r_bytes;
554 end_time = t.tv_sec * 1000000 + t.tv_usec;
555 net_bw = (double) (((new_s_bytes - old_s_bytes) + (new_r_bytes - old_r_bytes)) / (double)(end_time - start_time))*1000000*8;
556 printf("Bandwidth = %f\n",net_bw);
557 return net_bw;
558
559 }
560
561 /**************TIMING FUNCTIONS**************/
562
dgettimeofday(void)563 double dgettimeofday( void )
564 {
565 #ifdef HAVE_GETTIMEOFDAY
566 double timestamp;
567 struct timeval now;
568 gettimeofday(&now, NULL);
569 timestamp = now.tv_sec + now.tv_usec* 1.0e-6 ;
570 return timestamp;
571 #else
572 return -1;
573 #endif
574 }
575
576 /**************OS FUNCTIONS**************/
os_type()577 char* os_type() {
578 static struct utsname output;
579 static int first = 1;
580 if (first) {
581 uname(&output);
582 first = 0;
583 }
584 return strdup(output.sysname);
585 }
586
os_release()587 char* os_release() {
588 static struct utsname output;
589 static int first = 1;
590 if (first) {
591 uname(&output);
592 first = 0;
593 }
594 return strdup(output.release);
595 }
596
597 /* Should probably test if gethostname & uname exist on box before using them.... */
hostname()598 char* hostname() {
599 static char val[256];
600 static int first = 1;
601 if (first) {
602 gethostname(&val[0],256);
603 first = 0;
604 }
605 return strdup(&val[0]);
606 }
607
608
609 /**************Stat FUNCTIONS**************/
stat_uptime()610 double stat_uptime() {
611 double val=0;
612 #ifdef HAVE_SYSINFO
613 struct sysinfo info;
614 sysinfo(&info);
615 val = (double) info.uptime;
616 #else
617 #ifdef HAVE_MAC_SYSCTL
618 static int mib[4];
619 struct timeval boottime;
620 size_t mlen,vlen;
621 mlen = 2;
622 mib[0] = CTL_KERN;
623 mib[1] = KERN_BOOTTIME;
624 vlen = sizeof(struct timeval);
625 sysctl(mib,mlen,&boottime,&vlen,NULL,0);
626 val = dgettimeofday() - (double) boottime.tv_sec - boottime.tv_usec* 1.0e-6;
627
628 #endif // end HAVE_MAC_SYSCTL
629 #endif // end HAVE_SYSINFO
630
631 return val;
632
633 }
634
635 /* double stat_cpu_user() { */
636 /* } */
637
638 /* double stat_cpu_system() { */
639 /* } */
640
stat_loadavg_one(void)641 double stat_loadavg_one ( void )
642 {
643 double val;
644 #ifdef HAVE_GETLOADAVG
645 double loadavg[3];
646 getloadavg(loadavg,3);
647 val = loadavg[0];
648
649 #else
650 sensor_slurp proc_loadavg = { "/proc/loadavg" };
651 val = strtod( update_file(&proc_loadavg), (char **)NULL);
652 #endif //end HAVE_GETLOADAVG
653 return val;
654 }
655
stat_loadavg_five(void)656 double stat_loadavg_five ( void )
657 {
658 double val;
659 #ifdef HAVE_GETLOADAVG
660 double loadavg[3];
661 getloadavg(loadavg,3);
662 val = loadavg[1];
663
664 #else
665 char *p;
666
667 sensor_slurp proc_loadavg = { "/proc/loadavg" };
668 p = update_file(&proc_loadavg);
669 p = skip_token(p);
670 val = strtod( p, (char **)NULL);
671 #endif //end HAVE_GETLOADAVG
672 return val;
673 }
674
stat_loadavg_fifteen(void)675 double stat_loadavg_fifteen ( void )
676 {
677 double val;
678 #ifdef HAVE_GETLOADAVG
679 double loadavg[3];
680 getloadavg(loadavg,3);
681 val = loadavg[2];
682
683 #else
684 char *p;
685 sensor_slurp proc_loadavg = { "/proc/loadavg" };
686 p = update_file(&proc_loadavg);
687
688 p = skip_token(p);
689 p = skip_token(p);
690 val = strtod( p, (char **)NULL);
691 #endif //end HAVE_GETLOADAVG
692 return val;
693 }
694
695 /**************MEMORY FUNCTIONS**************/
696
vm_mem_total()697 unsigned long vm_mem_total() {
698 unsigned long val = 0;
699 #ifdef HAVE_MAC_SYSCTL
700 /* static int flag=0; */
701 static int mib[4];
702 size_t mlen,vlen;
703 mib[0] = CTL_HW;
704 mib[1] = HW_MEMSIZE;
705 mlen = 2;
706 /* if (flag == 0) { */
707 /* sysctlnametomib("hw.memsize",mib,&mlen); */
708 /* flag=1; */
709 /* } */
710 vlen = sizeof(unsigned long);
711 sysctl(mib,mlen,&val,&vlen,NULL,0);
712
713 #else
714 char *p;
715
716 sensor_slurp proc_meminfo = { "/proc/meminfo" };
717 p = strstr( update_file(&proc_meminfo), "MemTotal:" );
718 if(p) {
719 p = skip_token(p);
720 val = strtoul( p, NULL, 10 );
721 } else {
722 val = 0;
723 }
724 #endif //end of HAVE_MAC_SYSCTL
725 return val;
726 }
727
728
vm_mem_free()729 unsigned long vm_mem_free() {
730 unsigned long val = 0;
731 #ifdef HAVE_MAC_SYSCTL
732 /* static int flag=0; */
733 static int mib[2] = {CTL_VM, VM_SWAPUSAGE};
734 struct xsw_usage swapval;
735 size_t vlen;
736 /* mlen = 4; */
737 /* if (flag == 0) { */
738 /* sysctlnametomib("vm.swapusage",mib,&mlen); */
739 /* flag=1; */
740 /* } */
741 vlen = sizeof(struct xsw_usage);
742 sysctl(mib,2,&swapval,&vlen,NULL,0);
743 val = (unsigned long) swapval.xsu_avail;
744
745 #else
746 char *p;
747
748 sensor_slurp proc_meminfo = { "/proc/meminfo" };
749 p = strstr( update_file(&proc_meminfo), "MemFree:" );
750 if(p) {
751 p = skip_token(p);
752 val = strtoul( p, NULL, 10 );
753 } else {
754 val = 0;
755 }
756 #endif //end of HAVE_MAC_SYSCTL
757
758 return val;
759 }
760
761
vm_swap_total(void)762 unsigned long vm_swap_total ( void )
763 {
764 unsigned long val = 0;
765 #ifdef HAVE_MAC_SYSCTL
766 static int mib[2] = {CTL_VM, VM_SWAPUSAGE};
767 struct xsw_usage swapval;
768 size_t vlen;
769 vlen = sizeof(struct xsw_usage);
770 sysctl(mib,2,&swapval,&vlen,NULL,0);
771 val = (unsigned long) swapval.xsu_total;
772
773 #else
774 char *p;
775
776 sensor_slurp proc_meminfo = { "/proc/meminfo" };
777 p = strstr( update_file(&proc_meminfo), "SwapFree:" );
778 if(p) {
779 p = skip_token(p);
780 val = strtoul( p, NULL, 10 );
781 } else {
782 val = 0;
783 }
784 #endif //end HAVE_MAC_SYSCTL
785 return val;
786 }
787
vm_swap_free(void)788 unsigned long vm_swap_free ( void )
789 {
790 unsigned long val = 0;
791 #ifdef HAVE_MAC_SYSCTL
792 static int mib[2] = {CTL_VM, VM_SWAPUSAGE};
793 struct xsw_usage swapval;
794 size_t vlen;
795 vlen = sizeof(struct xsw_usage);
796 sysctl(mib,2,&swapval,&vlen,NULL,0);
797 val = (unsigned long) swapval.xsu_avail;
798
799 #else
800 char *p;
801
802 sensor_slurp proc_meminfo = { "/proc/meminfo" };
803 p = strstr( update_file(&proc_meminfo), "SwapFree:" );
804 if(p) {
805 p = skip_token(p);
806 val = strtoul( p, NULL, 10 );
807 } else {
808 val = 0;
809 }
810 #endif //end HAVE_MAC_SYSCTL
811 return val;
812 }
813
814 /**************HARDWARE FUNCTIONS**************/
hw_cpus()815 int hw_cpus () {
816 long val = -1;
817 #ifdef HAVE_MAC_SYSCTL
818 static int mib[2] = {CTL_HW, HW_NCPU};
819 size_t vlen;
820 vlen = sizeof(long);
821 sysctl(mib,2,&val,&vlen,NULL,0);
822 #else
823 #if defined(HAVE_SYSCONF)
824 val = (long) sysconf(_SC_NPROCESSORS_ONLN);
825 #else
826 val = 1; // if we don't know any better...
827 #endif // end HAVE_SYSCONFIG
828 #endif //end of HAVE_MAC_SYSCTL
829 return (int) val;
830
831 }
832
833
hw_cpu_max_freq(void)834 long hw_cpu_max_freq( void )
835 {
836 long val = 0;
837 #ifdef HAVE_MAC_SYSCTL
838 size_t vlen;
839 vlen = sizeof(long);
840 sysctlbyname("hw.cpufrequency_max",&val,&vlen,NULL,0);
841 val = val/1e6;
842 #else
843 char *p;
844
845 struct stat struct_stat;
846 char sys_devices_system_cpu[32];
847 const char *CPU_FREQ_SCALING_MAX_FREQ = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq";
848 if ( stat(CPU_FREQ_SCALING_MAX_FREQ, &struct_stat) == 0 ) {
849 if(slurpfile(CPU_FREQ_SCALING_MAX_FREQ, sys_devices_system_cpu, 32)) {
850 p = sys_devices_system_cpu;
851 val = (strtol( p, (char **)NULL , 10 ) / 1000 );
852 }
853 }
854 #endif // end HAVE_MAC_SYSCTL
855 return val;
856 }
857
hw_cpu_min_freq(void)858 long hw_cpu_min_freq( void )
859 {
860 long val = -1;
861 #ifdef HAVE_MAC_SYSCTL
862 size_t vlen;
863 vlen = sizeof(long);
864 sysctlbyname("hw.cpufrequency_min",&val,&vlen,NULL,0);
865 val = val/1e6;
866
867 #else
868 char *p;
869
870 struct stat struct_stat;
871 char sys_devices_system_cpu[32];
872 const char *CPU_FREQ_SCALING_MIN_FREQ = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq";
873 if ( stat(CPU_FREQ_SCALING_MIN_FREQ, &struct_stat) == 0 ) {
874 if(slurpfile(CPU_FREQ_SCALING_MIN_FREQ, sys_devices_system_cpu, 32)) {
875 p = sys_devices_system_cpu;
876 val = (strtol( p, (char **)NULL , 10 ) / 1000 );
877 }
878 }
879 #endif //end HAVE_MAC_SYSCTL
880 return val;
881 }
882
hw_cpu_curr_freq(void)883 long hw_cpu_curr_freq( void )
884 {
885 long val = 0;
886 #ifdef HAVE_MAC_SYSCTL
887 /* static int flag=0; */
888 static int mib[2] = {CTL_HW, HW_CPU_FREQ};
889 size_t vlen;
890 /* if (flag == 0) { */
891 /* sysctlnametomib("hw.cpufrequency",mib,&mlen); */
892 /* printf("\nmib = { %i, %i, %i, %i};\n",mib[0],mib[1],mib[2],mib[3]); */
893 /* flag=1; */
894 /* } */
895 vlen = sizeof(long);
896 sysctl(mib,2,&val,&vlen,NULL,0);
897 val = val/1e6;
898
899 #else
900 char *p;
901
902 struct stat struct_stat;
903 char sys_devices_system_cpu[32];
904 const char *CPU_FREQ_SCALING_CUR_FREQ = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq";
905 if ( stat(CPU_FREQ_SCALING_CUR_FREQ, &struct_stat) == 0 ) {
906 if(slurpfile(CPU_FREQ_SCALING_CUR_FREQ, sys_devices_system_cpu, 32)) {
907 p = sys_devices_system_cpu;
908 val = (unsigned int) (strtoul( p, (char **)NULL , 10 ) / 1000 );
909 }
910 }
911 #endif //end HAVE_MAC_SYSCTL
912 return val;
913 }
914
915
916 void
add_metrics_routines(stone_type stone,cod_parse_context context)917 add_metrics_routines(stone_type stone, cod_parse_context context)
918 {
919 static char extern_string[] = "\
920 double dgettimeofday(); \n \
921 /* number of cpus */ \n \
922 int hw_cpus(); \n \
923 /* minimum allowed frequency in MHz */ \n \
924 long hw_cpu_min_freq(); \n \
925 /* maximum allowed frequency in MHz */ \n \
926 long hw_cpu_max_freq(); \n \
927 /* current frequency in Mhz */ \n \
928 long hw_cpu_curr_freq(); \n \
929 /* a string to identify the local OS type -- ie Linux */ \n \
930 char* os_type(); \n \
931 /* a string to identify the current release -- ie FC14 */ \n \
932 char* os_release(); \n\
933 /* a string to identify the hostname -- ie maquis1 */ \n \
934 char* hostname(); \n\
935 /* time in seconds that the computer has been up */ \n \
936 double stat_uptime(); \n\
937 /* load average over the last one minute */ \n \
938 double stat_loadavg_one(); \n \
939 /* load average over the last five minutes */ \n \
940 double stat_loadavg_five(); \n \
941 /* load average over the last fifteen minute */ \n \
942 double stat_loadavg_fifteen(); \n \
943 /* total physical memory */ \n \
944 unsigned long vm_mem_total(); \n \
945 /* free physical memory */ \n \
946 unsigned long vm_mem_free(); \n \
947 /* total swap available */ \n \
948 unsigned long vm_swap_total(); \n \
949 /* free swap */ \n \
950 unsigned long vm_swap_free(); \n";
951
952 static cod_extern_entry externs[] = {
953 {"dgettimeofday", (void *) 0}, // 0
954 {"hw_cpus", (void *) 0}, // 1
955 {"hw_cpu_min_freq", (void *) 0}, // 2
956 {"hw_cpu_max_freq", (void *) 0}, // 3
957 {"hw_cpu_curr_freq", (void *) 0}, // 4
958 {"os_type", (void *) 0}, // 5
959 {"os_release", (void *) 0}, // 6
960 {"hostname", (void *) 0}, // 7
961 {"stat_uptime", (void *) 0}, // 8
962 {"stat_loadavg_one", (void *) 0}, // 9
963 {"stat_loadavg_five", (void *) 0}, // 10
964 {"stat_loadavg_fifteen", (void *) 0}, // 11
965 {"vm_mem_total", (void *) 0}, // 12
966 {"vm_mem_free", (void *) 0}, // 13
967 {"vm_swap_total", (void *) 0}, // 14
968 {"vm_swap_free", (void*) 0}, // 15
969 {(void *) 0, (void *) 0}
970 };
971
972 (void) stone;
973 /*
974 * some compilers think it isn't a static initialization to put this
975 * in the structure above, so do it explicitly.
976 */
977 externs[0].extern_value = (void *) (long) dgettimeofday;
978 externs[1].extern_value = (void *) (long) hw_cpus;
979 externs[2].extern_value = (void *) (long) hw_cpu_min_freq;
980 externs[3].extern_value = (void *) (long) hw_cpu_max_freq;
981 externs[4].extern_value = (void *) (long) hw_cpu_curr_freq;
982 externs[5].extern_value = (void *) (long) os_type;
983 externs[6].extern_value = (void *) (long) os_release;
984 externs[7].extern_value = (void *) (long) hostname;
985 externs[8].extern_value = (void *) (long) stat_uptime;
986 externs[9].extern_value = (void *) (long) stat_loadavg_one;
987 externs[10].extern_value = (void *) (long) stat_loadavg_five;
988 externs[11].extern_value = (void *) (long) stat_loadavg_fifteen;
989 externs[12].extern_value = (void *) (long) vm_mem_total;
990 externs[13].extern_value = (void *) (long) vm_mem_free;
991 externs[14].extern_value = (void *) (long) vm_swap_total;
992 externs[15].extern_value = (void *) (long) vm_swap_free;
993
994 cod_assoc_externs(context, externs);
995 cod_parse_for_context(extern_string, context);
996 }
997
998
999 /*int main(int argc, char **argv) {
1000 //num_cpustates_func();
1001 printf (" CPU USER % : %lf \n", cpu_user_func());
1002 printf (" CPU NICE % : %lf \n", cpu_nice_func());
1003 printf (" CPU SYSTEM % : %lf \n", cpu_system_func());
1004 printf (" CPU IDLE % : %lf \n", cpu_idle_func());
1005
1006 printf (" LOAD 1 % : %lf \n", load_one_func());
1007 printf (" LOAD 5 % : %lf \n", load_five_func());
1008 printf (" LOAD 15 % : %lf \n", load_fifteen_func());
1009
1010 printf (" MEM FREE % : %lf \n", mem_free_func());
1011 printf (" MEM BUFF % : %lf \n", mem_buffers_func());
1012 printf (" MEM CACHE % : %lf \n", mem_cached_func());
1013
1014 printf (" SWAP FREE % : %lf \n", swap_free_func());
1015 printf (" GET TIMESTAMP % : %lf \n", gettimeofday_func());
1016
1017 printf (" CPU_MAX_FREQ % : %d \n", cpu_max_freq_func());
1018 printf (" CPU_MIN_FREQ % : %d \n", cpu_min_freq_func());
1019 printf (" CPU_CUR_FREQ % : %d \n", cpu_cur_freq_func());
1020 int *val;
1021 val = cpu_available_freq_func();
1022 printf (" CPU_AVAILABLE_FREQ % : %d , %d , %d \n", val[0], val[1], val[2]);
1023
1024 printf (" CPU_FREQ_GOVERNOR % : %s \n", cpu_scaling_governor_func());
1025 char **avail;
1026 avail = cpu_scaling_available_governors_func();
1027 printf (" CPU_FREQ_AVAILABLE_GOVERNORS % : %s , %s , %s \n", avail[0], avail[1], avail[2]);
1028 }*/
1029
1030 /* Dead functions.
1031
1032 char *cpu_scaling_governor_func( void )
1033 {
1034 char *p = NULL;
1035 struct stat struct_stat;
1036 char sys_devices_system_cpu[32];
1037 const char *CPU_FREQ_SCALING_GOVERNOR = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor";
1038 if ( stat(CPU_FREQ_SCALING_GOVERNOR, &struct_stat) == 0 ) {
1039 if(slurpfile(CPU_FREQ_SCALING_GOVERNOR, sys_devices_system_cpu, 32)) {
1040 p = strdup(sys_devices_system_cpu);
1041 }
1042 }
1043 return p;
1044 }
1045
1046 char **cpu_scaling_available_governors_func( void )
1047 {
1048 static char *val[3];
1049 char *p;
1050
1051 struct stat struct_stat;
1052 char sys_devices_system_cpu_available[128];
1053 const char *CPU_FREQ_SCALING_AVAILABLE_GOVERNORS = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors";
1054 if ( stat(CPU_FREQ_SCALING_AVAILABLE_GOVERNORS, &struct_stat) == 0 ) {
1055 if(slurpfile(CPU_FREQ_SCALING_AVAILABLE_GOVERNORS, sys_devices_system_cpu_available, 128)) {
1056 p = strdup(sys_devices_system_cpu_available);
1057 val[0] = strtok(p, " ");
1058 val[1] = strtok(NULL, " ");
1059 val[2] = strtok(NULL, " ");
1060 }
1061 }
1062 return val;
1063 }
1064
1065 int *cpu_available_freq_func( void )
1066 {
1067 char *p;
1068 static int val[3];
1069
1070 struct stat struct_stat;
1071 char sys_devices_system_cpu_available[128];
1072 const char *CPU_FREQ_SCALING_AVAILABLE_FREQ = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies";
1073 if ( stat(CPU_FREQ_SCALING_AVAILABLE_FREQ, &struct_stat) == 0 ) {
1074 if(slurpfile(CPU_FREQ_SCALING_AVAILABLE_FREQ, sys_devices_system_cpu_available, 128)) {
1075 p = sys_devices_system_cpu_available;
1076 val[0] = (strtol( p, (char **)NULL , 10 ) / 1000 );
1077 p = skip_token(p);
1078 val[1] = (strtol( p, (char **)NULL , 10 ) / 1000 );
1079 p = skip_token(p);
1080 val[2] = (strtol( p, (char **)NULL , 10 ) / 1000 );
1081 }
1082 }
1083 return val;
1084 }
1085
1086 double mem_cached_func ( void )
1087 {
1088 char *p;
1089 double val;
1090
1091 sensor_slurp proc_meminfo = { "/proc/meminfo" };
1092 p = strstr( update_file(&proc_meminfo), "Cached:");
1093 if(p) {
1094 p = skip_token(p);
1095 val = atof( p );
1096 } else {
1097 val = 0;
1098 }
1099 return val;
1100 }
1101
1102 double mem_buffers_func ( void )
1103 {
1104 char *p;
1105 double val;
1106
1107 sensor_slurp proc_meminfo = { "/proc/meminfo" };
1108 p = strstr( update_file(&proc_meminfo), "Buffers:" );
1109 if(p) {
1110 p = skip_token(p);
1111 val = atof( p );
1112 } else {
1113 val = 0;
1114 }
1115
1116 return val;
1117 }
1118
1119 */
1120
1121 #ifdef NVML_FOUND
1122 #include "nvml.h"
1123
gpu_mon_init_func()1124 void gpu_mon_init_func()
1125 {
1126 nvmlInit();
1127 }
1128
gpu_mon_cleanup_func()1129 void gpu_mon_cleanup_func()
1130 {
1131 nvmlShutdown();
1132 }
1133
num_gpus_func()1134 unsigned int num_gpus_func()
1135 {
1136 unsigned int ret;
1137 nvmlDeviceGetCount(&ret);
1138 return ret;
1139 }
1140
gpu_utilization_func(unsigned int * gpu_util_rates)1141 void gpu_utilization_func(unsigned int *gpu_util_rates)
1142 {
1143 unsigned int num_dev, i;
1144 unsigned int *util;
1145 nvmlUtilization_t nvmlUtil;
1146 nvmlDevice_t dev;
1147 num_dev = num_gpus_func();
1148 // gpu_util_rates=(unsigned int *)malloc(sizeof(unsigned int)*num_dev);
1149 for(i=0;i<num_dev;++i)
1150 {
1151 nvmlDeviceGetHandleByIndex(i,&dev);
1152 nvmlDeviceGetUtilizationRates(dev,&nvmlUtil);
1153 *(gpu_util_rates+i)=nvmlUtil.gpu;
1154 }
1155
1156 }
1157
gpu_free_mem_func(unsigned long long * gpu_free_mem)1158 void gpu_free_mem_func(unsigned long long *gpu_free_mem)
1159 {
1160 unsigned int num_dev,i;
1161 nvmlDevice_t dev;
1162 nvmlMemory_t mem;
1163 num_dev=num_gpus_func();
1164 // gpu_free_mem=(unsigned long long *)malloc(sizeof(unsigned long long)*num_dev);
1165 for(i=0;i<num_dev;++i)
1166 {
1167 nvmlDeviceGetHandleByIndex(i,&dev);
1168 nvmlDeviceGetMemoryInfo(dev,&mem);
1169 *(gpu_free_mem+i)=mem.free;
1170 }
1171 }
1172
gpu_total_mem_func(unsigned long long * gpu_total_mem)1173 void gpu_total_mem_func(unsigned long long *gpu_total_mem)
1174 {
1175 unsigned int num_dev,i;
1176 nvmlDevice_t dev;
1177 nvmlMemory_t mem;
1178 num_dev=num_gpus_func();
1179 // gpu_total_mem=(unsigned long long *)malloc(sizeof(unsigned long long)*num_dev);
1180 for(i=0;i<num_dev;++i)
1181 {
1182 nvmlDeviceGetHandleByIndex(i,&dev);
1183 nvmlDeviceGetMemoryInfo(dev,&mem);
1184 *(gpu_total_mem+i)=mem.total;
1185 }
1186 }
1187
gpu_used_mem_func(unsigned long long * gpu_used_mem)1188 void gpu_used_mem_func(unsigned long long *gpu_used_mem)
1189 {
1190 unsigned int num_dev,i;
1191 nvmlDevice_t dev;
1192 nvmlMemory_t mem;
1193 num_dev=num_gpus_func();
1194 // gpu_used_mem=(unsigned long long *)malloc(sizeof(unsigned long long)*num_dev);
1195 for(i=0;i<num_dev;++i)
1196 {
1197 nvmlDeviceGetHandleByIndex(i,&dev);
1198 nvmlDeviceGetMemoryInfo(dev,&mem);
1199 *(gpu_used_mem+i)=mem.used;
1200 }
1201 }
1202
gpu_temp_func(unsigned int * temp)1203 void gpu_temp_func(unsigned int *temp)
1204 {
1205 unsigned int num_dev,i,t;
1206 nvmlDevice_t dev;
1207 num_dev=num_gpus_func();
1208 // temp=(unsigned int *)malloc(sizeof(unsigned int)*num_dev);
1209 for(i=0;i<num_dev;++i)
1210 {
1211 nvmlDeviceGetHandleByIndex(i,&dev);
1212 nvmlDeviceGetTemperature(dev,NVML_TEMPERATURE_GPU,&t);
1213 *(temp+i)=t;
1214 }
1215 }
1216
gpu_power_util_func(unsigned int * power)1217 void gpu_power_util_func(unsigned int *power)
1218 {
1219 unsigned int num_dev,i,p;
1220 nvmlDevice_t dev;
1221 num_dev=num_gpus_func();
1222 // power=(unsigned int*)malloc(sizeof(unsigned int)*num_dev);
1223 for(i=0;i<num_dev;++i)
1224 {
1225 nvmlDeviceGetHandleByIndex(i,&dev);
1226 nvmlDeviceGetPowerUsage(dev,&p);
1227 *(power+i)=p;
1228 }
1229
1230 }
1231
1232 #endif
1233