kstat から cpu load を取得するサンプル by C

(

)

by

in

top のソースからの切り貼り版です。



#include

#include



#include

#include

#include



#ifndef FSCALE

#define FSHIFT 8

#define FSCALE (1<<FSHIFT)

#endif /* FSCALE */

#define loadcvt(la) ((double)(la) / FSCALE)

#define UPDKCID(nk,ok)

if (nk == -1) {

perror(“kstat_read “);

break;

}

if (nk = ok)

return;



#define CPUSTATS 5

#define CPUSTAT_IOWAIT 3

#define CPUSTAT_SWAP 4



char *cpu_stat_name[] = {“idle”, “user”, “kernel”, “iowait”, “swap”, NULL};



kstat_ctl_t *kc;

kstat_t *ks;

kid_t kcid;

int ncpus;

unsigned long cs_now[CPUSTATS];

unsigned long cs_diff[CPUSTATS];

unsigned long cs_old[CPUSTATS];



void init(){

int i;

kstat_named_t *kn;



for(i = 0; i < CPUSTATS; i++){

cs_now[i] = 0L;

cs_diff[i] = 0L;

cs_old[i] = 0L;

}



kc = kstat_open();

if (!kc) {

perror(“kstat_open”);

exit(1);

}



ks = kstat_lookup(kc, “unix”, 0, “system_misc”);

if (kstat_read(kc, ks, 0) == -1) {

perror(“kstat_read”);

exit(1);

}



kn = kstat_data_lookup(ks, “ncpus”);

if (kn) { ncpus = kn->value.ui32; }



printf(“CPU:%dn”,ncpus);

}



void getStat(){

cpu_stat_t cs;

kid_t nkcid;

int i;

int cs_stat[CPUSTATS];



nkcid = kstat_chain_update(kc);

kcid = nkcid;



for(i = 0; i < CPUSTATS; i++){

cs_now[i] = 0L;

}

for (ks = kc->kc_chain; ks; ks = ks->ks_next) {

if (strncmp(ks->ks_name, “cpu_stat”, 8) == 0) {

nkcid = kstat_read(kc, ks, &cs);

/* if kcid changed, pointer might be invalid */

UPDKCID(nkcid, kcid);

for(i = 0; i < CPU_WAIT; i++){ // loop 0(idle), 1(user), 2(kernel)

cs_now[i] += cs.cpu_sysinfo.cpu[i];

}

cs_now[CPUSTAT_IOWAIT] += (long)cs.cpu_sysinfo.wait[W_IO] +

(long)cs.cpu_sysinfo.wait[W_PIO];

cs_now[CPUSTAT_SWAP] += (long)cs.cpu_sysinfo.wait[W_SWAP] ;



(void) percentages (CPUSTATS, cs_stat, cs_now, cs_old, cs_diff);



for(i = 0; i < CPUSTATS; i++){

//printf(“%s:%fn”,cpu_stat_name[i], (cs_diff[i]*100/cs_total));

// printf(“%s:%d (%d)(%d)(%d)n”,cpu_stat_name[i], (cs_diff[i]*100/cs_t

otal),cs_now[i], cs_old[i], cs_diff[i]);

printf(“%s:%dn”,cpu_stat_name[i],cs_stat[i]);

}

}

}

}



void destroy(){

(void) kstat_close(kc);

}



/*

* percentages(cnt, out, new, old, diffs) – calculate percentage change

* between array “old” and “new”, putting the percentages i “out”.

* “cnt” is size of each array and “diffs” is used for scratch space.

* The array “old” is updated on each call.

* The routine assumes modulo arithmetic. This function is especially

* useful on BSD mchines for calculating cpu state percentages.

*/



long percentages(cnt, out, new, old, diffs)



int cnt;

int *out;

register long *new;

register long *old;

long *diffs;



{

register int i;

register long change;

register long total_change;

register long *dp;

long half_total;



/* initialization */

total_change = 0;

dp = diffs;



/* calculate changes for each state and the overall change */

for (i = 0; i < cnt; i++)

{

if ((change = *new – *old) < 0)

{

/* this only happens when the counter wraps */

change = (int)

((unsigned long)*new-(unsigned long)*old);

}

total_change += (*dp++ = change);

*old++ = *new++;

}



/* avoid divide by zero potential */

if (total_change == 0)

{

total_change = 1;

}



/* calculate percentages based on overall change, rounding up */

half_total = total_change / 2l;

for (i = 0; i < cnt; i++)

{

*out++ = (int)((*diffs++ * 1000 + half_total) / total_change);

}



/* return the total in case the caller wants to use it */

return(total_change);

}





void main()

{

init();

while(1){

getStat();

sleep(5);

}

destroy();

}