int kupdate(int avenrun[3]) { kstat_t *ks; kid_t nkcid; int i; int changed = 0; static int ncpu = 0; static kid_t kcid = 0; kstat_named_t *kn; /* * 0. kstat_open */ if (!kc) { kc = kstat_open(); if (!kc) { perror("kstat_open "); return -1; } changed = 1; kcid = kc->kc_chain_id; } /* keep doing it until no more changes */ kcid_changed: /* * 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); ks = kstat_lookup(kc, "unix", 0, "system_misc"); if (kstat_read(kc, ks, 0) == -1) { perror("kstat_read"); return -1; } #if 0 /* load average */ kn = kstat_data_lookup(ks, "avenrun_1min"); if (kn) avenrun[0] = kn->value.ui32; kn = kstat_data_lookup(ks, "avenrun_5min"); if (kn) avenrun[1] = kn->value.ui32; kn = kstat_data_lookup(ks, "avenrun_15min"); if (kn) avenrun[2] = kn->value.ui32; /* nproc */ kn = kstat_data_lookup(ks, "nproc"); if (kn) { nproc = kn->value.ui32; #ifdef NO_NPROC if (nproc > maxprocs) reallocproc(2 * nproc); #endif } #endif if (changed) { int ncpus = 0; /* * 2. get data addresses */ ncpu = 0; kn = kstat_data_lookup(ks, "ncpus"); if (kn && kn->value.ui32 > ncpus) { ncpus = kn->value.ui32; cpu_ks = (kstat_t **)sge_realloc(cpu_ks, ncpus * sizeof(kstat_t *), 1); cpu_stat = (cpu_stat_t *)sge_realloc(cpu_stat, ncpus * sizeof(cpu_stat_t), 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 */ UPDKCID(nkcid, kcid); cpu_ks[ncpu] = ks; ncpu++; if (ncpu >= ncpus) { break; } } } /* note that ncpu could be less than ncpus, but that's okay */ changed = 0; } /* * 3. get data */ for (i = 0; i < ncpu; i++) { nkcid = kstat_read(kc, cpu_ks[i], &cpu_stat[i]); /* if kcid changed, pointer might be invalid */ UPDKCID(nkcid, kcid); } /* return the number of cpus found */ return(ncpu); }
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: enter\n"); 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_changed\n"); 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_misc\n"); 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 %p\n",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 %d\n", ncpu,lib_num_loc_cpus); exit(1); } } } /* note that ncpu could be less than ncpus, but that's okay */ changed = 0; } }