xref: /csrg-svn/lib/libc/gen/getloadavg.c (revision 52663)
144571Smarc /*-
238184Smckusick  * Copyright (c) 1989 The Regents of the University of California.
338184Smckusick  * All rights reserved.
438184Smckusick  *
544571Smarc  * %sccs.include.redist.c%
638184Smckusick  */
738184Smckusick 
838184Smckusick #if defined(LIBC_SCCS) && !defined(lint)
9*52663Smckusick static char sccsid[] = "@(#)getloadavg.c	6.3 (Berkeley) 02/25/92";
1044571Smarc #endif /* LIBC_SCCS and not lint */
1138184Smckusick 
1238184Smckusick #include <sys/param.h>
1338184Smckusick #include <sys/types.h>
1438184Smckusick #include <sys/file.h>
15*52663Smckusick #include <sys/kernel.h>
16*52663Smckusick #include <sys/kinfo.h>
1738184Smckusick #include <nlist.h>
1838184Smckusick 
1938184Smckusick static struct nlist nl[] = {
2038184Smckusick 	{ "_averunnable" },
2138184Smckusick #define	X_AVERUNNABLE	0
2238184Smckusick 	{ "_fscale" },
2338184Smckusick #define	X_FSCALE	1
2438184Smckusick 	{ "" },
2538184Smckusick };
2638184Smckusick 
2738184Smckusick /*
2838184Smckusick  *  getloadavg() -- Get system load averages.
2938184Smckusick  *
3038184Smckusick  *  Put `nelem' samples into `loadavg' array.
3138184Smckusick  *  Return number of samples retrieved, or -1 on error.
3238184Smckusick  */
3338184Smckusick getloadavg(loadavg, nelem)
3438184Smckusick 	double loadavg[];
3538184Smckusick 	int nelem;
3638184Smckusick {
3738184Smckusick 	static int need_nlist = 1;
38*52663Smckusick 	struct loadavg loadinfo;
39*52663Smckusick 	int size, kmemfd, i;
40*52663Smckusick 	int alreadyopen = 1;
41*52663Smckusick 	int fscale;
4238184Smckusick 
43*52663Smckusick 	size = sizeof(loadinfo);
44*52663Smckusick 	if (getkerninfo(KINFO_LOADAVG, &loadinfo, &size, 0) < 0) {
45*52663Smckusick 		if ((alreadyopen = kvm_openfiles(NULL, NULL, NULL)) == -1)
46*52663Smckusick 			return (-1);
47*52663Smckusick 		/*
48*52663Smckusick 		 * cache nlist
49*52663Smckusick 		 */
50*52663Smckusick 		if (need_nlist) {
51*52663Smckusick 			if (kvm_nlist(nl) != 0)
52*52663Smckusick 				goto bad;
53*52663Smckusick 			need_nlist = 0;
54*52663Smckusick 		}
55*52663Smckusick 		if (kvm_read((off_t)nl[X_AVERUNNABLE].n_value,
56*52663Smckusick 		    (char *)&loadinfo, sizeof(loadinfo)) != size)
5744571Smarc 			goto bad;
58*52663Smckusick 		/*
59*52663Smckusick 		 * Old kernel have fscale separately; if not found assume
60*52663Smckusick 		 * running new format.
61*52663Smckusick 		 */
62*52663Smckusick 		if (kvm_read( (off_t)nl[X_FSCALE].n_value, (char *)&fscale,
63*52663Smckusick 		    sizeof(fscale)) == sizeof(fscale))
64*52663Smckusick 			loadinfo.fscale = fscale;
6538184Smckusick 	}
66*52663Smckusick 	nelem = MIN(nelem, sizeof(loadinfo.ldavg) / sizeof(fixpt_t));
6738184Smckusick 	for (i = 0; i < nelem; i++)
68*52663Smckusick 		loadavg[i] = (double) loadinfo.ldavg[i] / loadinfo.fscale;
6944571Smarc 	if (!alreadyopen)
7044571Smarc 		kvm_close();
7138184Smckusick 	return (nelem);
7238184Smckusick 
7338184Smckusick bad:
7444571Smarc 	if (!alreadyopen)
7544571Smarc 		kvm_close();
7638184Smckusick 	return (-1);
7738184Smckusick }
78