Andy.Linton@comp.vuw.ac.nz (Andy Linton) (06/29/90)
In article <1990Jun25.223131.28782@ulrik.uio.no>, obh@mai.uio.no (Ole Bj|rn Hessen) writes: |> Had the same problem, the problem disappeared when |> I rewrote the getla() routine. Try see what happen |> if getla just return zero (do not call nlist). Rather than have getla() just return zero I modified getloadavg.c to do the 'right' thing. I also include changes for HP-UX. I have posted the file as the diffs are bigger than the file itself. Wouldn't it be nice if all systems had a getloadavg() routine in the library! This has been tested on a DEC 5400 but not on a mips box that has the bytes ordered properly. andy -- /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)getloadavg.c 6.1 (Berkeley) 5/29/89"; #endif LIBC_SCCS and not lint #include <sys/param.h> #include <sys/types.h> #include <sys/file.h> #include <nlist.h> /* #include <paths.h> */ #include <pathnames.h> # if defined(mips) # include <sys/fixpoint.h> # endif /* mips */ static char *kmem = _PATH_KMEM; static char *vmunix = _PATH_UNIX; #if defined(mips) || defined(hpux) static struct nlist nl[] = { #ifdef hp9000s800 {"avenrun"}, #else {"_avenrun"}, #endif hp9000s800 #define X_AVERUNNABLE 0 { "" }, }; #else /* default */ static struct nlist nl[] = { { "_averunnable" }, #define X_AVERUNNABLE 0 { "_fscale" }, #define X_FSCALE 1 { "" }, }; #endif /* mips || hpux */ /* * getloadavg() -- Get system load averages. * * Put `nelem' samples into `loadavg' array. * Return number of samples retrieved, or -1 on error. */ getloadavg(loadavg, nelem) double loadavg[]; int nelem; { off_t lseek(); static int need_nlist = 1; #if defined(hpux) double averunnable[3]; #else u_long averunnable[3]; #endif /* hpux */ int fscale, kmemfd, i; char *a_ptr; /* nlist() is slow; cache result */ if (need_nlist) { if (nlist(vmunix, nl) != 0) return (-1); #if defined(mips) || defined(hpux) if (nl[X_AVERUNNABLE].n_type == 0) #else if (nl[X_AVERUNNABLE].n_type == 0 || nl[X_FSCALE].n_type == 0) #endif /* mips || hpux */ return (-1); need_nlist = 0; } if ((kmemfd = open(kmem, O_RDONLY, 0)) < 0) return (-1); if (lseek(kmemfd, (off_t)nl[X_AVERUNNABLE].n_value, L_SET) == -1) goto bad; if (read(kmemfd, (char *)averunnable, sizeof(averunnable)) < sizeof(averunnable)) goto bad; #if !defined(mips) && !defined(hpux) if (lseek(kmemfd, (off_t)nl[X_FSCALE].n_value, L_SET) == -1) goto bad; if (read(kmemfd, (char *)&fscale, sizeof(fscale)) < 0) goto bad; #endif /* !mips && !hpux */ (void) close(kmemfd); nelem = MIN(nelem, sizeof(averunnable) / sizeof(averunnable[0])); for (i = 0; i < nelem; i++) #if defined(mips) loadavg[i] = FIX_TO_DBL(averunnable[i]); #else if defined(hpux) loadavg[i] = averunnable[i]; #else loadavg[i] = (double) averunnable[i] / fscale; #endif /* mips || hpux */ return (nelem); bad: (void) close(kmemfd); return (-1); }