1 /*-
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)kvm_getloadavg.c 8.1 (Berkeley) 06/04/93";
10 #endif /* LIBC_SCCS and not lint */
11
12 #include <sys/param.h>
13 #include <sys/time.h>
14 #include <sys/resource.h>
15 #include <sys/proc.h>
16 #include <sys/sysctl.h>
17 #include <vm/vm_param.h>
18
19 #include <db.h>
20 #include <fcntl.h>
21 #include <limits.h>
22 #include <nlist.h>
23 #include <kvm.h>
24
25 #include "kvm_private.h"
26
27 static struct nlist nl[] = {
28 { "_averunnable" },
29 #define X_AVERUNNABLE 0
30 { "_fscale" },
31 #define X_FSCALE 1
32 { "" },
33 };
34
35 /*
36 * kvm_getloadavg() -- Get system load averages, from live or dead kernels.
37 *
38 * Put `nelem' samples into `loadavg' array.
39 * Return number of samples retrieved, or -1 on error.
40 */
41 int
kvm_getloadavg(kd,loadavg,nelem)42 kvm_getloadavg(kd, loadavg, nelem)
43 kvm_t *kd;
44 double loadavg[];
45 int nelem;
46 {
47 struct loadavg loadinfo;
48 struct nlist *p;
49 int fscale, i;
50
51 if (ISALIVE(kd))
52 return (getloadavg(loadavg, nelem));
53
54 if (kvm_nlist(kd, nl) != 0) {
55 for (p = nl; p->n_type != 0; ++p);
56 _kvm_err(kd, kd->program,
57 "%s: no such symbol", p->n_name);
58 return (-1);
59 }
60
61 #define KREAD(kd, addr, obj) \
62 (kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj))
63 if (KREAD(kd, nl[X_AVERUNNABLE].n_value, &loadinfo)) {
64 _kvm_err(kd, kd->program, "can't read averunnable");
65 return (-1);
66 }
67
68 /*
69 * Old kernels have fscale separately; if not found assume
70 * running new format.
71 */
72 if (!KREAD(kd, nl[X_FSCALE].n_value, &fscale))
73 loadinfo.fscale = fscale;
74
75 nelem = MIN(nelem, sizeof(loadinfo.ldavg) / sizeof(fixpt_t));
76 for (i = 0; i < nelem; i++)
77 loadavg[i] = (double) loadinfo.ldavg[i] / loadinfo.fscale;
78 return (nelem);
79 }
80