Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
netcpu_kstat.c
Package: netperf-2.4.4.tar.gz [view]
Upload User: kvgkvg
Upload Date: 2015-05-07
Package Size: 1129k
Code Size: 9k
Category:
Linux-Unix program
Development Platform:
C/C++
- char netcpu_kstat_id[]="
- @(#)netcpu_kstat.c Version 2.4.0";
- #if HAVE_CONFIG_H
- # include <config.h>
- #endif
- #include <stdio.h>
- #if HAVE_INTTYPES_H
- # include <inttypes.h>
- #else
- # if HAVE_STDINT_H
- # include <stdint.h>
- # endif
- #endif
- #if HAVE_UNISTD_H
- # include <unistd.h>
- #endif
- #if HAVE_STRINGS_H
- # include <strings.h>
- #endif
- #if STDC_HEADERS
- # include <stdlib.h>
- # include <stddef.h>
- #else
- # if HAVE_STDLIB_H
- # include <stdlib.h>
- # endif
- #endif
- #include <kstat.h>
- #include <sys/sysinfo.h>
- #include "netsh.h"
- #include "netlib.h"
- /* the lib_start_count and lib_end_count arrays hold the starting
- and ending values of whatever is counting when the system is
- idle. The rate at which this increments during a test is compared
- with a previous calibrarion to arrive at a CPU utilization
- percentage. raj 2005-01-26 */
- static uint64_t lib_start_count[MAXCPUS];
- static uint64_t lib_end_count[MAXCPUS];
- static kstat_t *cpu_ks[MAXCPUS]; /* the addresses that kstat will
- need to pull the cpu info from
- the kstat interface. at least I
- think that is what this is :) raj
- 8/2000 */
- #define UPDKCID(nk,ok)
- if (nk == -1) {
- perror("kstat_read ");
- exit(1);
- }
- if (nk != ok)
- goto kcid_changed;
- static kstat_ctl_t *kc = NULL;
- static kid_t kcid = 0;
- /* do the initial open of the kstat interface, get the chain id's all
- straightened-out and set-up the addresses for get_kstat_idle to do
- its thing. liberally borrowed from the sources to TOP. raj 8/2000 */
- static int
- open_kstat()
- {
- kstat_t *ks;
- kid_t nkcid;
- int i;
- int changed = 0;
- static int ncpu = 0;
- kstat_named_t *kn;
- if (debug) {
- fprintf(where,"open_kstat: entern");
- fflush(where);
- }
- /*
- * 0. kstat_open
- */
- if (!kc)
- {
- kc = kstat_open();
- if (!kc)
- {
- perror("kstat_open ");
- exit(1);
- }
- changed = 1;
- kcid = kc->kc_chain_id;
- }
- #ifdef rickwasstupid
- else {
- fprintf(where,"open_kstat double open!n");
- fflush(where);
- exit(1);
- }
- #endif
- /* keep doing it until no more changes */
- kcid_changed:
- if (debug) {
- fprintf(where,"passing kcid_changedn");
- fflush(where);
- }
- /*
- * 1. kstat_chain_update
- */
- nkcid = kstat_chain_update(kc);
- if (nkcid)
- {
- /* UPDKCID will abort if nkcid is -1, so no need to check */
- changed = 1;
- kcid = nkcid;
- }
- UPDKCID(nkcid,0);
- if (debug) {
- fprintf(where,"kstat_lookup for unix/system_miscn");
- fflush(where);
- }
- ks = kstat_lookup(kc, "unix", 0, "system_misc");
- if (kstat_read(kc, ks, 0) == -1) {
- perror("kstat_read");
- exit(1);
- }
- if (changed) {
- /*
- * 2. get data addresses
- */
- ncpu = 0;
- kn = kstat_data_lookup(ks, "ncpus");
- if (kn && kn->value.ui32 > lib_num_loc_cpus) {
- fprintf(stderr,"number of CPU's mismatch!");
- exit(1);
- }
- for (ks = kc->kc_chain; ks;
- ks = ks->ks_next)
- {
- if (strncmp(ks->ks_name, "cpu_stat", 8) == 0)
- {
- nkcid = kstat_read(kc, ks, NULL);
- /* if kcid changed, pointer might be invalid. we'll deal
- wtih changes at this stage, but will not accept them
- when we are actually in the middle of reading
- values. hopefully this is not going to be a big
- issue. raj 8/2000 */
- UPDKCID(nkcid, kcid);
- if (debug) {
- fprintf(where,"cpu_ks[%d] getting %pn",ncpu,ks);
- fflush(where);
- }
- cpu_ks[ncpu] = ks;
- ncpu++;
- if (ncpu > lib_num_loc_cpus)
- {
- /* with the check above, would we ever hit this? */
- fprintf(stderr,
- "kstat finds too many cpus %d: should be %dn",
- ncpu,lib_num_loc_cpus);
- exit(1);
- }
- }
- }
- /* note that ncpu could be less than ncpus, but that's okay */
- changed = 0;
- }
- }
- /* return the value of the idle tick counter for the specified CPU */
- static long
- get_kstat_idle(cpu)
- int cpu;
- {
- cpu_stat_t cpu_stat;
- kid_t nkcid;
- if (debug) {
- fprintf(where,
- "get_kstat_idle reading with kc %x and ks %pn",
- kc,
- cpu_ks[cpu]);
- }
- nkcid = kstat_read(kc, cpu_ks[cpu], &cpu_stat);
- /* if kcid changed, pointer might be invalid, fail the test */
- UPDKCID(nkcid, kcid);
- return(cpu_stat.cpu_sysinfo.cpu[CPU_IDLE]);
- kcid_changed:
- perror("kcid changed midstream and I cannot deal with that!");
- exit(1);
- }
- void
- cpu_util_init(void)
- {
- open_kstat();
- return;
- }
- void
- cpu_util_terminate(void)
- {
- return;
- }
- int
- get_cpu_method(void)
- {
- return KSTAT;
- }
- void
- get_cpu_idle(uint64_t *res)
- {
- int i;
- /* this open may be redundant */
- open_kstat();
- for (i = 0; i < lib_num_loc_cpus; i++){
- res[i] = get_kstat_idle(i);
- }
- return;
- }
- float
- calibrate_idle_rate(int iterations, int interval)
- {
- long
- firstcnt[MAXCPUS],
- secondcnt[MAXCPUS];
- float
- elapsed,
- temp_rate,
- rate[MAXTIMES],
- local_maxrate;
- long
- sec,
- usec;
- int
- i,
- j;
- struct timeval time1, time2 ;
- struct timezone tz;
- if (debug) {
- fprintf(where,"calling open_kstat from calibrate_kstatn");
- fflush(where);
- }
- open_kstat();
- if (iterations > MAXTIMES) {
- iterations = MAXTIMES;
- }
- local_maxrate = (float)-1.0;
- for(i = 0; i < iterations; i++) {
- rate[i] = (float)0.0;
- for (j = 0; j < lib_num_loc_cpus; j++) {
- firstcnt[j] = get_kstat_idle(j);
- }
- gettimeofday (&time1, &tz);
- sleep(interval);
- gettimeofday (&time2, &tz);
- if (time2.tv_usec < time1.tv_usec)
- {
- time2.tv_usec += 1000000;
- time2.tv_sec -=1;
- }
- sec = time2.tv_sec - time1.tv_sec;
- usec = time2.tv_usec - time1.tv_usec;
- elapsed = (float)sec + ((float)usec/(float)1000000.0);
- if(debug) {
- fprintf(where, "Calibration for kstat counter run: %dn",i);
- fprintf(where,"tsec = %ld usec = %ldn",sec,usec);
- fprintf(where,"telapsed time = %gn",elapsed);
- }
- for (j = 0; j < lib_num_loc_cpus; j++) {
- secondcnt[j] = get_kstat_idle(j);
- if(debug) {
- /* I know that there are situations where compilers know about */
- /* long long, but the library functions do not... raj 4/95 */
- fprintf(where,
- "tfirstcnt[%d] = 0x%8.8lx%8.8lx secondcnt[%d] = 0x%8.8lx%8.8lxn",
- j,
- firstcnt[j],
- firstcnt[j],
- j,
- secondcnt[j],
- secondcnt[j]);
- }
- /* we assume that it would wrap no more than once. we also */
- /* assume that the result of subtracting will "fit" raj 4/95 */
- temp_rate = (secondcnt[j] >= firstcnt[j]) ?
- (float)(secondcnt[j] - firstcnt[j])/elapsed :
- (float)(secondcnt[j]-firstcnt[j]+MAXLONG)/elapsed;
- if (temp_rate > rate[i]) rate[i] = temp_rate;
- if(debug) {
- fprintf(where,"trate[%d] = %gn",i,rate[i]);
- fflush(where);
- }
- if (local_maxrate < rate[i]) local_maxrate = rate[i];
- }
- }
- if(debug) {
- fprintf(where,"tlocal maxrate = %g per sec. n",local_maxrate);
- fflush(where);
- }
- return local_maxrate;
- }
- float
- calc_cpu_util_internal(float elapsed_time)
- {
- int i;
- float correction_factor;
- float actual_rate;
- lib_local_cpu_util = (float)0.0;
- /* It is possible that the library measured a time other than */
- /* the one that the user want for the cpu utilization */
- /* calculations - for example, tests that were ended by */
- /* watchdog timers such as the udp stream test. We let these */
- /* tests tell up what the elapsed time should be. */
- if (elapsed_time != 0.0) {
- correction_factor = (float) 1.0 +
- ((lib_elapsed - elapsed_time) / elapsed_time);
- }
- else {
- correction_factor = (float) 1.0;
- }
- for (i = 0; i < lib_num_loc_cpus; i++) {
- /* it would appear that on some systems, in loopback, nice is
- *very* effective, causing the looper process to stop dead in its
- tracks. if this happens, we need to ensure that the calculation
- does not go south. raj 6/95 and if we run completely out of idle,
- the same thing could in theory happen to the USE_KSTAT path. raj
- 8/2000 */
- if (lib_end_count[i] == lib_start_count[i]) {
- lib_end_count[i]++;
- }
- actual_rate = (lib_end_count[i] > lib_start_count[i]) ?
- (float)(lib_end_count[i] - lib_start_count[i])/lib_elapsed :
- (float)(lib_end_count[i] - lib_start_count[i] +
- MAXLONG)/ lib_elapsed;
- if (debug) {
- fprintf(where,
- "calc_cpu_util: actual_rate on processor %d is %f start %lx end %lxn",
- i,
- actual_rate,
- lib_start_count[i],
- lib_end_count[i]);
- }
- lib_local_per_cpu_util[i] = (lib_local_maxrate - actual_rate) /
- lib_local_maxrate * 100;
- lib_local_cpu_util += lib_local_per_cpu_util[i];
- }
- /* we want the average across all n processors */
- lib_local_cpu_util /= (float)lib_num_loc_cpus;
- lib_local_cpu_util *= correction_factor;
- return lib_local_cpu_util;
- }
- void
- cpu_start_internal(void)
- {
- get_cpu_idle(lib_start_count);
- return;
- }
- void
- cpu_stop_internal(void)
- {
- get_cpu_idle(lib_end_count);
- }