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*58899Smckusick static char sccsid[] = "@(#)getloadavg.c 6.4 (Berkeley) 03/31/93"; 1044571Smarc #endif /* LIBC_SCCS and not lint */ 1138184Smckusick 1238184Smckusick #include <sys/param.h> 1338184Smckusick #include <sys/types.h> 1438184Smckusick #include <sys/file.h> 1552663Smckusick #include <sys/kernel.h> 16*58899Smckusick #include <sys/sysctl.h> 17*58899Smckusick #include <vm/vm_param.h> 1838184Smckusick #include <nlist.h> 1938184Smckusick 2038184Smckusick static struct nlist nl[] = { 2138184Smckusick { "_averunnable" }, 2238184Smckusick #define X_AVERUNNABLE 0 2338184Smckusick { "_fscale" }, 2438184Smckusick #define X_FSCALE 1 2538184Smckusick { "" }, 2638184Smckusick }; 2738184Smckusick 2838184Smckusick /* 2938184Smckusick * getloadavg() -- Get system load averages. 3038184Smckusick * 3138184Smckusick * Put `nelem' samples into `loadavg' array. 3238184Smckusick * Return number of samples retrieved, or -1 on error. 3338184Smckusick */ 3438184Smckusick getloadavg(loadavg, nelem) 3538184Smckusick double loadavg[]; 3638184Smckusick int nelem; 3738184Smckusick { 3838184Smckusick static int need_nlist = 1; 3952663Smckusick struct loadavg loadinfo; 4052663Smckusick int size, kmemfd, i; 4152663Smckusick int alreadyopen = 1; 42*58899Smckusick int mib[2], fscale; 4338184Smckusick 4452663Smckusick size = sizeof(loadinfo); 45*58899Smckusick mib[0] = CTL_VM; 46*58899Smckusick mib[1] = VM_LOADAVG; 47*58899Smckusick if (sysctl(mib, 2, &loadinfo, &size, NULL, 0) < 0) { 4852663Smckusick if ((alreadyopen = kvm_openfiles(NULL, NULL, NULL)) == -1) 4952663Smckusick return (-1); 5052663Smckusick /* 5152663Smckusick * cache nlist 5252663Smckusick */ 5352663Smckusick if (need_nlist) { 5452663Smckusick if (kvm_nlist(nl) != 0) 5552663Smckusick goto bad; 5652663Smckusick need_nlist = 0; 5752663Smckusick } 5852663Smckusick if (kvm_read((off_t)nl[X_AVERUNNABLE].n_value, 5952663Smckusick (char *)&loadinfo, sizeof(loadinfo)) != size) 6044571Smarc goto bad; 6152663Smckusick /* 6252663Smckusick * Old kernel have fscale separately; if not found assume 6352663Smckusick * running new format. 6452663Smckusick */ 6552663Smckusick if (kvm_read( (off_t)nl[X_FSCALE].n_value, (char *)&fscale, 6652663Smckusick sizeof(fscale)) == sizeof(fscale)) 6752663Smckusick loadinfo.fscale = fscale; 6838184Smckusick } 6952663Smckusick nelem = MIN(nelem, sizeof(loadinfo.ldavg) / sizeof(fixpt_t)); 7038184Smckusick for (i = 0; i < nelem; i++) 7152663Smckusick loadavg[i] = (double) loadinfo.ldavg[i] / loadinfo.fscale; 7244571Smarc if (!alreadyopen) 7344571Smarc kvm_close(); 7438184Smckusick return (nelem); 7538184Smckusick 7638184Smckusick bad: 7744571Smarc if (!alreadyopen) 7844571Smarc kvm_close(); 7938184Smckusick return (-1); 8038184Smckusick } 81