netcpu_perfstat.c
Upload User: kvgkvg
Upload Date: 2015-05-07
Package Size: 1129k
Code Size: 8k
Development Platform:

C/C++

  1. char   netcpu_perfstat_id[]="
  2. @(#)netcpu_perfstat.c Version 2.4.0";
  3. #if HAVE_CONFIG_H
  4. # include <config.h>
  5. #endif
  6. #include <stdio.h>
  7. #if HAVE_INTTYPES_H
  8. # include <inttypes.h>
  9. #else
  10. # if HAVE_STDINT_H
  11. #  include <stdint.h>
  12. # endif
  13. #endif
  14. #if TIME_WITH_SYS_TIME
  15. # include <sys/time.h>
  16. # include <time.h>
  17. #else
  18. # if HAVE_SYS_TIME_H
  19. #  include <sys/time.h>
  20. # else
  21. #  include <time.h>
  22. # endif
  23. #endif
  24. #if HAVE_LIMITS_H
  25. # include <limits.h>
  26. # ifndef LONG_LONG_MAX
  27. #  define LONG_LONG_MAX LLONG_MAX
  28. # endif /* LONG_LONG_MAX */
  29. #endif 
  30. #include <errno.h>
  31. #include "netsh.h"
  32. #include "netlib.h"
  33. /* the lib_start_count and lib_end_count arrays hold the starting
  34.    and ending values of whatever is counting when the system is
  35.    idle. The rate at which this increments during a test is compared
  36.    with a previous calibration to arrive at a CPU utilization
  37.    percentage. raj 2005-01-26 */
  38. static uint64_t  lib_start_count[MAXCPUS];
  39. static uint64_t  lib_end_count[MAXCPUS];
  40. void
  41. cpu_util_init(void) 
  42. {
  43.   return;
  44. }
  45. void
  46. cpu_util_terminate(void)
  47. {
  48.   return;
  49. }
  50. int
  51. get_cpu_method(void)
  52. {
  53.   return PERFSTAT;
  54. }
  55. void
  56. get_cpu_idle(uint64_t *res)
  57. {
  58.   perfstat_cpu_t *perfstat_buffer;
  59.   perfstat_cpu_t *per_cpu_pointer;
  60.   perfstat_id_t  name;
  61.   int i,ret;
  62.   
  63.   /* a name of "" will cause us to start from the beginning */
  64.   strcpy(name.name,"");
  65.   perfstat_buffer = (perfstat_cpu_t *)malloc(lib_num_loc_cpus *
  66.      sizeof(perfstat_cpu_t));
  67.   if (perfstat_buffer == NULL) {
  68.     fprintf(where,
  69.     "cpu_start: malloc failed errno %dn",
  70.     errno);
  71.     fflush(where);
  72.     exit(-1);
  73.   }
  74.   
  75.   /* happiness and joy, keep going */
  76.   ret = perfstat_cpu(&name,
  77.      perfstat_buffer,
  78.      sizeof(perfstat_cpu_t),
  79.      lib_num_loc_cpus);
  80.   
  81.   if ((ret == -1) || 
  82.       (ret != lib_num_loc_cpus)) {
  83.     fprintf(where,
  84.     "cpu_start: perfstat_cpu failed/count off; errno %d cpus %d count %dn",
  85.     errno,
  86.     lib_num_loc_cpus,
  87.     ret);
  88.     fflush(where);
  89.     exit(-1);
  90.   }
  91.   
  92.   per_cpu_pointer = perfstat_buffer;
  93.   for (i = 0; i < lib_num_loc_cpus; i++){
  94.     res[i] = per_cpu_pointer->idle;
  95.     per_cpu_pointer++;
  96.   }
  97.   free(perfstat_buffer);
  98.   
  99.   return;
  100. }
  101. float
  102. calibrate_idle_rate(int iterations, int interval)
  103. {
  104.   unsigned long long
  105.     firstcnt[MAXCPUS],
  106.     secondcnt[MAXCPUS];
  107.   float 
  108.     elapsed,
  109.     temp_rate,
  110.     rate[MAXTIMES],
  111.     local_maxrate;
  112.   long  
  113.     sec,
  114.     usec;
  115.   int   
  116.     i,
  117.     j;
  118.   
  119.   struct  timeval time1, time2 ;
  120.   struct  timezone tz;
  121.   perfstat_cpu_t  *perfstat_buffer;
  122.   perfstat_cpu_t  *per_cpu_pointer;
  123.   perfstat_id_t   name;
  124.   int ret;
  125.   
  126.   if (debug) {
  127.     fprintf(where,"enter calibrate_perfstatn");
  128.     fflush(where);
  129.   }
  130.   if (iterations > MAXTIMES) {
  131.     iterations = MAXTIMES;
  132.   }
  133.   local_maxrate = (float)-1.0;
  134.   
  135.   perfstat_buffer = (perfstat_cpu_t *)malloc(lib_num_loc_cpus *
  136.                                              sizeof(perfstat_cpu_t));
  137.   if (perfstat_buffer == NULL) {
  138.     fprintf(where,
  139.             "calibrate_perfstat: malloc failed errno %dn",
  140.             errno);
  141.     fflush(where);
  142.     exit(-1);
  143.   }
  144.   for(i = 0; i < iterations; i++) {
  145.     rate[i] = (float)0.0;
  146.     /* a name of "" will cause us to start from the beginning */
  147.     strcpy(name.name,"");
  148.      
  149.     /* happiness and joy, keep going */
  150.     ret = perfstat_cpu(&name,
  151.                        perfstat_buffer,
  152.                        sizeof(perfstat_cpu_t),
  153.                        lib_num_loc_cpus);
  154.     
  155.     if ((ret == -1) || 
  156.         (ret != lib_num_loc_cpus)) {
  157.       fprintf(where,
  158.               "calibrate_perfstat: perfstat_cpu failed/count off; errno %d cpus %d count %dn",
  159.               errno,
  160.               lib_num_loc_cpus,
  161.               ret);
  162.       fflush(where);
  163.       exit(-1);
  164.     }
  165.     per_cpu_pointer = perfstat_buffer;
  166.     for (j = 0; j < lib_num_loc_cpus; j++) {
  167.       firstcnt[j] = per_cpu_pointer->idle;
  168.       per_cpu_pointer++;
  169.     }
  170.     gettimeofday (&time1, &tz);
  171.     sleep(interval);
  172.     gettimeofday (&time2, &tz);
  173.     if (time2.tv_usec < time1.tv_usec)
  174.       {
  175.         time2.tv_usec += 1000000;
  176.         time2.tv_sec -=1;
  177.       }
  178.     sec = time2.tv_sec - time1.tv_sec;
  179.     usec = time2.tv_usec - time1.tv_usec;
  180.     elapsed = (float)sec + ((float)usec/(float)1000000.0);
  181.     /* happiness and joy, keep going */
  182.     ret = perfstat_cpu(&name,
  183.                        perfstat_buffer,
  184.                        sizeof(perfstat_cpu_t),
  185.                        lib_num_loc_cpus);
  186.     
  187.     if ((ret == -1) || 
  188.         (ret != lib_num_loc_cpus)) {
  189.       fprintf(where,
  190.               "calibrate_perfstat: perfstat_cpu failed/count off; errno %d cpus %d count %dn",
  191.               errno,
  192.               lib_num_loc_cpus,
  193.               ret);
  194.       fflush(where);
  195.       exit(-1);
  196.     }
  197.     per_cpu_pointer = perfstat_buffer;
  198.     
  199.     if(debug) {
  200.       fprintf(where, "Calibration for perfstat counter run: %dn",i);
  201.       fprintf(where,"tsec = %ld usec = %ldn",sec,usec);
  202.       fprintf(where,"telapsed time = %gn",elapsed);
  203.     }
  204.     for (j = 0; j < lib_num_loc_cpus; j++) {
  205.       secondcnt[j] = per_cpu_pointer->idle;
  206.       per_cpu_pointer++;
  207.       if(debug) {
  208.         /* I know that there are situations where compilers know about */
  209.         /* long long, but the library functions do not... raj 4/95 */
  210.         fprintf(where,
  211.                 "tfirstcnt[%d] = 0x%8.8lx%8.8lx secondcnt[%d] = 0x%8.8lx%8.8lxn",
  212.                 j,
  213.                 firstcnt[j],
  214.                 firstcnt[j],
  215.                 j,
  216.                 secondcnt[j],
  217.                 secondcnt[j]);
  218.       }
  219.       /* we assume that it would wrap no more than once. we also */
  220.       /* assume that the result of subtracting will "fit" raj 4/95 */
  221.       temp_rate = (secondcnt[j] >= firstcnt[j]) ?
  222.         (float)(secondcnt[j] - firstcnt[j])/elapsed : 
  223.           (float)(secondcnt[j]-firstcnt[j]+MAXLONG)/elapsed;
  224.       if (temp_rate > rate[i]) rate[i] = temp_rate;
  225.       if(debug) {
  226.         fprintf(where,"trate[%d] = %gn",i,rate[i]);
  227.         fflush(where);
  228.       }
  229.       if (local_maxrate < rate[i]) local_maxrate = rate[i];
  230.     }
  231.   }
  232.   if(debug) {
  233.     fprintf(where,"tlocal maxrate = %g per sec. n",local_maxrate);
  234.     fflush(where);
  235.   }
  236.   free(perfstat_buffer);
  237.   return local_maxrate;
  238. }
  239. float
  240. calc_cpu_util_internal(float elapsed_time)
  241. {
  242.   int i;
  243.   float actual_rate;
  244.   float correction_factor;
  245.   lib_local_cpu_util = (float)0.0;
  246.   /* It is possible that the library measured a time other than */
  247.   /* the one that the user want for the cpu utilization */
  248.   /* calculations - for example, tests that were ended by */
  249.   /* watchdog timers such as the udp stream test. We let these */
  250.   /* tests tell up what the elapsed time should be. */
  251.   if (elapsed_time != 0.0) {
  252.     correction_factor = (float) 1.0 +
  253.       ((lib_elapsed - elapsed_time) / elapsed_time);
  254.   }
  255.   else {
  256.     correction_factor = (float) 1.0;
  257.   }
  258.   /* this looks just like the looper case. at least I think it */
  259.   /* should :) raj 4/95 */
  260.   for (i = 0; i < lib_num_loc_cpus; i++) {
  261.     /* we assume that the two are not more than a long apart. I */
  262.     /* know that this is bad, but trying to go from long longs to */
  263.     /* a float (perhaps a double) is boggling my mind right now. */
  264.     /* raj 4/95 */
  265.     long long
  266.       diff;
  267.     if (lib_end_count[i] >= lib_start_count[i]) {
  268.       diff = lib_end_count[i] - lib_start_count[i];
  269.     }
  270.     else {
  271.       diff = lib_end_count[i] - lib_start_count[i] + LONG_LONG_MAX;
  272.     }
  273.     actual_rate = (float) diff / lib_elapsed;
  274.     lib_local_per_cpu_util[i] = (lib_local_maxrate - actual_rate) /
  275.       lib_local_maxrate * 100;
  276.     lib_local_cpu_util += lib_local_per_cpu_util[i];
  277.     if (debug) {
  278.       fprintf(where,
  279.               "calc_cpu_util: actual_rate on cpu %d is %g max_rate %g cpu %6.2fn",
  280.               i,
  281.               actual_rate,
  282.               lib_local_maxrate,
  283.               lib_local_per_cpu_util[i]);
  284.     }
  285.   }
  286.   /* we want the average across all n processors */
  287.   lib_local_cpu_util /= (float)lib_num_loc_cpus;
  288.   
  289.   if (debug) {
  290.     fprintf(where,
  291.             "calc_cpu_util: average across CPUs is %gn",lib_local_cpu_util);
  292.   }
  293.   lib_local_cpu_util *= correction_factor;
  294.   if (debug) {
  295.     fprintf(where,
  296.             "calc_cpu_util: returning %gn",lib_local_cpu_util);
  297.   }
  298.   return lib_local_cpu_util;
  299. }
  300. void
  301. cpu_start_internal(void)
  302. {
  303.   get_cpu_idle(lib_start_count);
  304.   return;
  305. }
  306.  
  307. void
  308. cpu_stop_internal(void)
  309. {
  310.   get_cpu_idle(lib_end_count);
  311. }