1 /*- 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)getloadavg.c 6.3 (Berkeley) 02/25/92"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/param.h> 13 #include <sys/types.h> 14 #include <sys/file.h> 15 #include <sys/kernel.h> 16 #include <sys/kinfo.h> 17 #include <nlist.h> 18 19 static struct nlist nl[] = { 20 { "_averunnable" }, 21 #define X_AVERUNNABLE 0 22 { "_fscale" }, 23 #define X_FSCALE 1 24 { "" }, 25 }; 26 27 /* 28 * getloadavg() -- Get system load averages. 29 * 30 * Put `nelem' samples into `loadavg' array. 31 * Return number of samples retrieved, or -1 on error. 32 */ 33 getloadavg(loadavg, nelem) 34 double loadavg[]; 35 int nelem; 36 { 37 static int need_nlist = 1; 38 struct loadavg loadinfo; 39 int size, kmemfd, i; 40 int alreadyopen = 1; 41 int fscale; 42 43 size = sizeof(loadinfo); 44 if (getkerninfo(KINFO_LOADAVG, &loadinfo, &size, 0) < 0) { 45 if ((alreadyopen = kvm_openfiles(NULL, NULL, NULL)) == -1) 46 return (-1); 47 /* 48 * cache nlist 49 */ 50 if (need_nlist) { 51 if (kvm_nlist(nl) != 0) 52 goto bad; 53 need_nlist = 0; 54 } 55 if (kvm_read((off_t)nl[X_AVERUNNABLE].n_value, 56 (char *)&loadinfo, sizeof(loadinfo)) != size) 57 goto bad; 58 /* 59 * Old kernel have fscale separately; if not found assume 60 * running new format. 61 */ 62 if (kvm_read( (off_t)nl[X_FSCALE].n_value, (char *)&fscale, 63 sizeof(fscale)) == sizeof(fscale)) 64 loadinfo.fscale = fscale; 65 } 66 nelem = MIN(nelem, sizeof(loadinfo.ldavg) / sizeof(fixpt_t)); 67 for (i = 0; i < nelem; i++) 68 loadavg[i] = (double) loadinfo.ldavg[i] / loadinfo.fscale; 69 if (!alreadyopen) 70 kvm_close(); 71 return (nelem); 72 73 bad: 74 if (!alreadyopen) 75 kvm_close(); 76 return (-1); 77 } 78