159367Sbostic /*-
2*61278Sbostic * Copyright (c) 1993
3*61278Sbostic * The Regents of the University of California. All rights reserved.
459367Sbostic *
559367Sbostic * %sccs.include.redist.c%
659367Sbostic */
759367Sbostic
859367Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*61278Sbostic static char sccsid[] = "@(#)kvm_getloadavg.c 8.1 (Berkeley) 06/04/93";
1059367Sbostic #endif /* LIBC_SCCS and not lint */
1159367Sbostic
1259367Sbostic #include <sys/param.h>
1359367Sbostic #include <sys/time.h>
1459367Sbostic #include <sys/resource.h>
1559367Sbostic #include <sys/proc.h>
1659367Sbostic #include <sys/sysctl.h>
1759367Sbostic #include <vm/vm_param.h>
1859367Sbostic
1959367Sbostic #include <db.h>
2059367Sbostic #include <fcntl.h>
2159367Sbostic #include <limits.h>
2259367Sbostic #include <nlist.h>
2359367Sbostic #include <kvm.h>
2459367Sbostic
2559367Sbostic #include "kvm_private.h"
2659367Sbostic
2759367Sbostic static struct nlist nl[] = {
2859367Sbostic { "_averunnable" },
2959367Sbostic #define X_AVERUNNABLE 0
3059367Sbostic { "_fscale" },
3159367Sbostic #define X_FSCALE 1
3259367Sbostic { "" },
3359367Sbostic };
3459367Sbostic
3559367Sbostic /*
3659367Sbostic * kvm_getloadavg() -- Get system load averages, from live or dead kernels.
3759367Sbostic *
3859367Sbostic * Put `nelem' samples into `loadavg' array.
3959367Sbostic * Return number of samples retrieved, or -1 on error.
4059367Sbostic */
4159367Sbostic int
kvm_getloadavg(kd,loadavg,nelem)4259367Sbostic kvm_getloadavg(kd, loadavg, nelem)
4359367Sbostic kvm_t *kd;
4459367Sbostic double loadavg[];
4559367Sbostic int nelem;
4659367Sbostic {
4759367Sbostic struct loadavg loadinfo;
4859367Sbostic struct nlist *p;
4959367Sbostic int fscale, i;
5059367Sbostic
5159367Sbostic if (ISALIVE(kd))
5259367Sbostic return (getloadavg(loadavg, nelem));
5359367Sbostic
5459367Sbostic if (kvm_nlist(kd, nl) != 0) {
5559367Sbostic for (p = nl; p->n_type != 0; ++p);
5659367Sbostic _kvm_err(kd, kd->program,
5759367Sbostic "%s: no such symbol", p->n_name);
5859367Sbostic return (-1);
5959367Sbostic }
6059367Sbostic
6159367Sbostic #define KREAD(kd, addr, obj) \
6259367Sbostic (kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj))
6359367Sbostic if (KREAD(kd, nl[X_AVERUNNABLE].n_value, &loadinfo)) {
6459367Sbostic _kvm_err(kd, kd->program, "can't read averunnable");
6559367Sbostic return (-1);
6659367Sbostic }
6759367Sbostic
6859367Sbostic /*
6959367Sbostic * Old kernels have fscale separately; if not found assume
7059367Sbostic * running new format.
7159367Sbostic */
7259367Sbostic if (!KREAD(kd, nl[X_FSCALE].n_value, &fscale))
7359367Sbostic loadinfo.fscale = fscale;
7459367Sbostic
7559367Sbostic nelem = MIN(nelem, sizeof(loadinfo.ldavg) / sizeof(fixpt_t));
7659367Sbostic for (i = 0; i < nelem; i++)
7759367Sbostic loadavg[i] = (double) loadinfo.ldavg[i] / loadinfo.fscale;
7859367Sbostic return (nelem);
7959367Sbostic }
80