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.4 (Berkeley) 03/31/93"; 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/sysctl.h> 17 #include <vm/vm_param.h> 18 #include <nlist.h> 19 20 static struct nlist nl[] = { 21 { "_averunnable" }, 22 #define X_AVERUNNABLE 0 23 { "_fscale" }, 24 #define X_FSCALE 1 25 { "" }, 26 }; 27 28 /* 29 * getloadavg() -- Get system load averages. 30 * 31 * Put `nelem' samples into `loadavg' array. 32 * Return number of samples retrieved, or -1 on error. 33 */ 34 getloadavg(loadavg, nelem) 35 double loadavg[]; 36 int nelem; 37 { 38 static int need_nlist = 1; 39 struct loadavg loadinfo; 40 int size, kmemfd, i; 41 int alreadyopen = 1; 42 int mib[2], fscale; 43 44 size = sizeof(loadinfo); 45 mib[0] = CTL_VM; 46 mib[1] = VM_LOADAVG; 47 if (sysctl(mib, 2, &loadinfo, &size, NULL, 0) < 0) { 48 if ((alreadyopen = kvm_openfiles(NULL, NULL, NULL)) == -1) 49 return (-1); 50 /* 51 * cache nlist 52 */ 53 if (need_nlist) { 54 if (kvm_nlist(nl) != 0) 55 goto bad; 56 need_nlist = 0; 57 } 58 if (kvm_read((off_t)nl[X_AVERUNNABLE].n_value, 59 (char *)&loadinfo, sizeof(loadinfo)) != size) 60 goto bad; 61 /* 62 * Old kernel have fscale separately; if not found assume 63 * running new format. 64 */ 65 if (kvm_read( (off_t)nl[X_FSCALE].n_value, (char *)&fscale, 66 sizeof(fscale)) == sizeof(fscale)) 67 loadinfo.fscale = fscale; 68 } 69 nelem = MIN(nelem, sizeof(loadinfo.ldavg) / sizeof(fixpt_t)); 70 for (i = 0; i < nelem; i++) 71 loadavg[i] = (double) loadinfo.ldavg[i] / loadinfo.fscale; 72 if (!alreadyopen) 73 kvm_close(); 74 return (nelem); 75 76 bad: 77 if (!alreadyopen) 78 kvm_close(); 79 return (-1); 80 } 81