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