[comp.mail.sendmail] 5.64/IDA-1.3.1 on Ultrix/RISC

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);
}