xref: /csrg-svn/lib/libc/gen/getloadavg.c (revision 38184)
1*38184Smckusick /*
2*38184Smckusick  * Copyright (c) 1989 The Regents of the University of California.
3*38184Smckusick  * All rights reserved.
4*38184Smckusick  *
5*38184Smckusick  * Redistribution and use in source and binary forms are permitted
6*38184Smckusick  * provided that the above copyright notice and this paragraph are
7*38184Smckusick  * duplicated in all such forms and that any documentation,
8*38184Smckusick  * advertising materials, and other materials related to such
9*38184Smckusick  * distribution and use acknowledge that the software was developed
10*38184Smckusick  * by the University of California, Berkeley.  The name of the
11*38184Smckusick  * University may not be used to endorse or promote products derived
12*38184Smckusick  * from this software without specific prior written permission.
13*38184Smckusick  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*38184Smckusick  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*38184Smckusick  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16*38184Smckusick  */
17*38184Smckusick 
18*38184Smckusick #if defined(LIBC_SCCS) && !defined(lint)
19*38184Smckusick static char sccsid[] = "@(#)getloadavg.c	6.1 (Berkeley) 05/29/89";
20*38184Smckusick #endif LIBC_SCCS and not lint
21*38184Smckusick 
22*38184Smckusick #include <sys/param.h>
23*38184Smckusick #include <sys/types.h>
24*38184Smckusick #include <sys/file.h>
25*38184Smckusick 
26*38184Smckusick #include <nlist.h>
27*38184Smckusick #include <paths.h>
28*38184Smckusick 
29*38184Smckusick static char *kmem = _PATH_KMEM;
30*38184Smckusick static char *vmunix = _PATH_UNIX;
31*38184Smckusick 
32*38184Smckusick static struct nlist nl[] = {
33*38184Smckusick 	{ "_averunnable" },
34*38184Smckusick #define	X_AVERUNNABLE	0
35*38184Smckusick 	{ "_fscale" },
36*38184Smckusick #define	X_FSCALE	1
37*38184Smckusick 	{ "" },
38*38184Smckusick };
39*38184Smckusick 
40*38184Smckusick /*
41*38184Smckusick  *  getloadavg() -- Get system load averages.
42*38184Smckusick  *
43*38184Smckusick  *  Put `nelem' samples into `loadavg' array.
44*38184Smckusick  *  Return number of samples retrieved, or -1 on error.
45*38184Smckusick  */
46*38184Smckusick getloadavg(loadavg, nelem)
47*38184Smckusick 	double loadavg[];
48*38184Smckusick 	int nelem;
49*38184Smckusick {
50*38184Smckusick 	off_t lseek();
51*38184Smckusick 	static int need_nlist = 1;
52*38184Smckusick 	fixpt_t	averunnable[3];
53*38184Smckusick 	int fscale, kmemfd, i;
54*38184Smckusick 
55*38184Smckusick 	/* nlist() is slow; cache result */
56*38184Smckusick 	if (need_nlist) {
57*38184Smckusick 		if (nlist(vmunix, nl) != 0)
58*38184Smckusick 			return (-1);
59*38184Smckusick 		if (nl[X_AVERUNNABLE].n_type == 0 || nl[X_FSCALE].n_type == 0)
60*38184Smckusick 			return (-1);
61*38184Smckusick 		need_nlist = 0;
62*38184Smckusick 	}
63*38184Smckusick 
64*38184Smckusick 	if ((kmemfd = open(kmem, O_RDONLY, 0)) < 0)
65*38184Smckusick 		return (-1);
66*38184Smckusick 	if (lseek(kmemfd, (off_t)nl[X_AVERUNNABLE].n_value, L_SET) == -1)
67*38184Smckusick 		goto bad;
68*38184Smckusick 	if (read(kmemfd, (char *)averunnable, sizeof(averunnable)) < 0)
69*38184Smckusick 		goto bad;
70*38184Smckusick 	if (lseek(kmemfd, (off_t)nl[X_FSCALE].n_value, L_SET) == -1)
71*38184Smckusick 		goto bad;
72*38184Smckusick 	if (read(kmemfd, (char *)&fscale, sizeof(fscale)) < 0)
73*38184Smckusick 		goto bad;
74*38184Smckusick 	(void) close(kmemfd);
75*38184Smckusick 
76*38184Smckusick 	nelem = MIN(nelem, sizeof(averunnable) / sizeof(averunnable[0]));
77*38184Smckusick 	for (i = 0; i < nelem; i++)
78*38184Smckusick 		loadavg[i] = (double) averunnable[i] / fscale;
79*38184Smckusick 	return (nelem);
80*38184Smckusick 
81*38184Smckusick bad:
82*38184Smckusick 	(void) close(kmemfd);
83*38184Smckusick 	return (-1);
84*38184Smckusick }
85