From owner-freebsd-hackers Fri Oct 6 17:17: 2 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from kzsu.stanford.edu (KZSU.Stanford.EDU [171.66.118.90]) by hub.freebsd.org (Postfix) with ESMTP id 472A837B503 for ; Fri, 6 Oct 2000 17:16:59 -0700 (PDT) Received: (from romain@localhost) by kzsu.stanford.edu (8.9.3/8.9.3) id RAA17529 for freebsd-hackers@FreeBSD.ORG; Fri, 6 Oct 2000 17:16:59 -0700 (PDT) (envelope-from romain) Date: Fri, 6 Oct 2000 17:16:59 -0700 (PDT) From: Romain Kang Message-Id: <200010070016.RAA17529@kzsu.stanford.edu> To: rh@matriplex.com Subject: Re: A decent way to get CPU idle time? Reply-To: romain@kzsu.stanford.edu Organization: KZSU 90.1 FM, Stanford, Calif. USA Cc: freebsd-hackers@FreeBSD.ORG X-Newsreader: NN version 6.5.3 (NOV) Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG I am loathe to call kmem readers clean and decent, but I coincidentally did something similar today, ripping out code from vmstat. See below. It doesn't look difficult to implement a sysctl() interface, but I guess if someone considered the data really important, it would have been done already. IMHO, getloadavg() is flagrantly meaningless. There are plenty of ways to skew the numbers without actually changing CPU activity. Romain Kang Disclaimer: I speak for myself alone, romain@kzsu.stanford.edu except when indicated otherwise. | Is there a clean and decent way to find out the percentage | of CPU idle time, like top and systat give? I have browsed | the source for both, and neither appear to have a simple | way of finding this information. | I have already tried and rejected getloadavg. In my | application, two main processes will always account | for 95% or more of the activity. | I suppose I could use RDTSC to grab the clock on my system | calls, and figure a rudimentary sum of CPU activity, but | that won't help me with the expensive file and socket calls. | And I would pretty much have to guess about the CPU time spent | in the kernel. | Any ideas? Thanks. #include #include #include #include #include #include #include struct nlist namelist[] = { #define X_CPTIME 0 { "_cp_time" }, {""} }; char *nlistf = NULL, *memf = NULL; kvm_t *kd; void kread(); void cpu_init(); void cpu_idle(); main() { cpu_init(); cpu_idle(); } void cpu_init() { int c; static char errbuf[BUFSIZ]; /* * Discard setgid privileges if not the running kernel so that bad * guys can't print interesting stuff from kernel memory. */ if (nlistf != NULL || memf != NULL) setgid(getgid()); kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); if (kd == 0) errx(1, "kvm_openfiles: %s", errbuf); if ((c = kvm_nlist(kd, namelist)) != 0) { if (c > 0) { warnx("undefined symbols:"); for (c = 0; c < sizeof(namelist)/sizeof(namelist[0]); c++) if (namelist[c].n_type == 0) fprintf(stderr, " %s", namelist[c].n_name); (void)fputc('\n', stderr); } else warnx("kvm_nlist: %s", kvm_geterr(kd)); exit(1); } } void cpu_idle() { register int state; double pct, total; long cp_time[CPUSTATES]; int idle_percent; kread(X_CPTIME, cp_time, sizeof(cp_time)); total = 0; for (state = 0; state < CPUSTATES; ++state) total += cp_time[state]; if (total) pct = 100 / total; else pct = 0; idle_percent = cp_time[CP_IDLE] * pct; printf("idle%%=%d\n", idle_percent); } /* * kread reads something from the kernel, given its nlist index. */ void kread(nlx, addr, size) int nlx; void *addr; size_t size; { char *sym; if (namelist[nlx].n_type == 0 || namelist[nlx].n_value == 0) { sym = namelist[nlx].n_name; if (*sym == '_') ++sym; errx(1, "symbol %s not defined", sym); } if (kvm_read(kd, namelist[nlx].n_value, addr, size) != size) { sym = namelist[nlx].n_name; if (*sym == '_') ++sym; errx(1, "%s: %s", sym, kvm_geterr(kd)); } } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message