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