1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #if defined(LIBC_SCCS) && !defined(lint) 19 static char sccsid[] = "@(#)getloadavg.c 6.1 (Berkeley) 05/29/89"; 20 #endif LIBC_SCCS and not lint 21 22 #include <sys/param.h> 23 #include <sys/types.h> 24 #include <sys/file.h> 25 26 #include <nlist.h> 27 #include <paths.h> 28 29 static char *kmem = _PATH_KMEM; 30 static char *vmunix = _PATH_UNIX; 31 32 static struct nlist nl[] = { 33 { "_averunnable" }, 34 #define X_AVERUNNABLE 0 35 { "_fscale" }, 36 #define X_FSCALE 1 37 { "" }, 38 }; 39 40 /* 41 * getloadavg() -- Get system load averages. 42 * 43 * Put `nelem' samples into `loadavg' array. 44 * Return number of samples retrieved, or -1 on error. 45 */ 46 getloadavg(loadavg, nelem) 47 double loadavg[]; 48 int nelem; 49 { 50 off_t lseek(); 51 static int need_nlist = 1; 52 fixpt_t averunnable[3]; 53 int fscale, kmemfd, i; 54 55 /* nlist() is slow; cache result */ 56 if (need_nlist) { 57 if (nlist(vmunix, nl) != 0) 58 return (-1); 59 if (nl[X_AVERUNNABLE].n_type == 0 || nl[X_FSCALE].n_type == 0) 60 return (-1); 61 need_nlist = 0; 62 } 63 64 if ((kmemfd = open(kmem, O_RDONLY, 0)) < 0) 65 return (-1); 66 if (lseek(kmemfd, (off_t)nl[X_AVERUNNABLE].n_value, L_SET) == -1) 67 goto bad; 68 if (read(kmemfd, (char *)averunnable, sizeof(averunnable)) < 0) 69 goto bad; 70 if (lseek(kmemfd, (off_t)nl[X_FSCALE].n_value, L_SET) == -1) 71 goto bad; 72 if (read(kmemfd, (char *)&fscale, sizeof(fscale)) < 0) 73 goto bad; 74 (void) close(kmemfd); 75 76 nelem = MIN(nelem, sizeof(averunnable) / sizeof(averunnable[0])); 77 for (i = 0; i < nelem; i++) 78 loadavg[i] = (double) averunnable[i] / fscale; 79 return (nelem); 80 81 bad: 82 (void) close(kmemfd); 83 return (-1); 84 } 85