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