[comp.sys.sgi] Avenrun in IRIX 3.2

srp@babar.mmwb.ucsf.edu (Scott R. Presnell) (11/30/89)

Hi all,
	Avenrun seems to be available in the IRIX 3.2 kernel as an array of
longs.  But as in the Sun kernel it appears to need a scaling... 1024 seems
about right.  Does anyone know what and/or where the appropriate constant
might be found?

Thanks. -Scott
Scott Presnell				        +1 (415) 476-9890
Pharm. Chem., S-926				Internet: srp@cgl.ucsf.edu
University of California			UUCP: ...ucbvax!ucsfcgl!srp
San Francisco, CA. 94143-0446			Bitnet: srp@ucsfcgl.bitnet

pwolfe@kailand.kai.com (Patrick Wolfe) (12/01/89)

> Written by srp@babar.mmwb.ucsf.edu
>	Avenrun seems to be available in the IRIX 3.2 kernel as an array of
> longs.  But as in the Sun kernel it appears to need a scaling... 1024 seems
> about right.  Does anyone know what and/or where the appropriate constant
> might be found?

FSCALE is sometimes defined in <sys/param.h>, and on some machines it's
missing.  It's usually either 1 or 1000.  Here's a program that displays the
hostname and three load average numbers successfully on SGI Irix 3.2, Sequent
Dynix V3.0, Alliant Concentrix V5.0, Concurrent RTU V5.0, and (I think) SunOS
3.0.  The original load average code is from the screen program.  You need
read permissions on /dev/kmem to make it work.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  loadavg.c Makefile
# Wrapped by pwolfe@kailand on Thu Nov 30 13:07:36 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'loadavg.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'loadavg.c'\"
else
echo shar: Extracting \"'loadavg.c'\" \(2516 characters\)
sed "s/^X//" >'loadavg.c' <<'END_OF_FILE'
X/*
X *	loadavg.c - display system load average
X *
X *	Original load average code from the screen V2 program by Oliver Lauman.
X */
X
X#include <stdio.h>
X#include <nlist.h>
X#include <sys/types.h>
X#include <sys/file.h>
X
X#if defined(sun) || defined(sequent) || defined(sgi)
X#define SUNLOADAV
X#endif
X
X#ifdef SUNLOADAV
X#include <sys/param.h>
X#endif
X
X#undef FSCALE
X#ifdef SUNLOADAV
X#define FSCALE 1000.0
X#else
X#define FSCALE 1.0
X#endif
X
X#define KMEMNAME "/dev/kmem"
X
X#ifdef sequent
X#define KERNELPATH "/dynix"
X#else
X#if defined(masscomp) || defined(sgi)
X#define KERNELPATH "/unix"
X#else
X#define KERNELPATH "/vmunix"
X#endif /* masscomp or sgi */
X#endif /* sequent */
X
X#ifdef alliant
X#define LOADAVGSYMBOL "_Loadavg"
X#else
X#ifdef sgi
X#define LOADAVGSYMBOL "avenrun"
X#else
X#define LOADAVGSYMBOL "_avenrun"
X#endif /* sgi */
X#endif /* alliant */
X
X#ifdef SUNLOADAV
X#define LOADAVGTYPE long
X#else
X#ifdef alliant
X#define LOADAVGTYPE long
X#else
X#ifdef masscomp
X#define LOADAVGTYPE float
X#else
X#define LOADAVGTYPE double
X#endif /* masscomp */
X#endif /* alliant */
X#endif /* SUNLOADAV */
X
Xstatic struct nlist nl[2];
X#	Alliant actually has FOUR numbers available, the last one
X#	being the load average over the past 60 minutes.
X#	We'll ignore that for portability
Xstatic LOADAVGTYPE loadav[3];
Xstatic int kmemf;
Xstatic char KmemName[] = KMEMNAME;
Xstatic char UnixName[] = KERNELPATH;
Xstatic char AvenrunSym[] = LOADAVGSYMBOL;
Xstatic char hostname[64];
X
Xmain () {
X
X	/*
X	 *	get name of this host
X	 */
X	if (gethostname (hostname, 64) == -1) {
X		perror ("gethostname failed");
X		exit (1);
X		}
X
X	/*
X	 *	open kernel memory
X	 *	may require special priviledges
X	 */
X	if ((kmemf = open (KmemName, O_RDONLY)) == -1) {
X		perror ("open of /dev/kmem failed:");
X		exit (1);
X		}
X
X	/*
X	 *	locate load average numbers
X	 */
X	nl[0].n_name = AvenrunSym;
X	nlist (UnixName, nl);
X	if (nl[0].n_type == 0 || nl[0].n_value == 0) {
X		perror ("nlist of Unix kernel failed:");
X		exit (1);
X		}
X
X	/*
X	 *	seek into kmem
X	 */
X#ifdef sgi
X	if (lseek (kmemf, nl[0].n_value & ~0x80000000, 0) == -1) {
X#else
X	if (lseek (kmemf, nl[0].n_value, 0) == -1) {
X#endif
X		perror ("lseek into /dev/kmem failed");
X		exit (1);
X		}
X
X	/*
X	 *	read numbers from memory
X	 */
X	if (read (kmemf, loadav, sizeof (loadav)) != sizeof (loadav)) {
X		perror ("read from /dev/kmem failed");
X		exit (1);
X		}
X
X	/*
X	 *	display the numbers
X	 */
X
X	printf ("%s %04.2f %04.2f %04.2f\n", hostname, (LOADAVGTYPE)loadav[0]/FSCALE,
X	    (LOADAVGTYPE)loadav[1]/FSCALE, (LOADAVGTYPE)loadav[2]/FSCALE);
X
X	exit (0);
X	}
END_OF_FILE
if test 2516 -ne `wc -c <'loadavg.c'`; then
    echo shar: \"'loadavg.c'\" unpacked with wrong size!
fi
# end of 'loadavg.c'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(377 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#	uncommment for SGI
X#LIBS     = -lmld
X
XCFLAGS   = -g $(INCLUDES) $(DEFINES)
XBIN      = /usr/local/bin
XKMEMGRP  = kmem
XSHELL    = /bin/sh
X 
Xloadavg: loadavg.c
X	$(CC) $(CFLAGS) -o loadavg loadavg.c $(LIBS)
X
Xinstall: loadavg
X	rm -f $(BIN)/loadavg
X	cp loadavg $(BIN)/loadavg
X	-chgrp $(KMEMGRP) $(BIN)/loadavg
X	chmod 2711 $(BIN)/loadavg
X
Xclean:
X	rm -f a.out core mklog loadavg *.o
END_OF_FILE
if test 377 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
echo shar: End of shell archive.
exit 0

arc@SGI.SGI.COM (Andrew Cherenson) (12/01/89)

In article <12452@cgl.ucsf.EDU> srp@cgl.ucsf.edu (Scott R. Presnell) writes:
>Hi all,
>	Avenrun seems to be available in the IRIX 3.2 kernel as an array of
>longs.  But as in the Sun kernel it appears to need a scaling... 1024 seems
>about right.  Does anyone know what and/or where the appropriate constant
>might be found?

1024 is correct. Here's a sample program to access avenrun.

------ Cut here ----------------------------------------------
/*
 * loadavg.c --
 *
 *	Prints 1, 5, and 15 minute load averages for an 
 *	IRIS-4D running	IRIX 3.2.
 *
 *	As root, do
 *		cc loadavg.c -lmld -o loadavg
 *		chgrp sys loadavg
 *		chmod 2555 loadavg	
 *	(It must be setgid sys to read /dev/kmem.)
 *
 *	This file is in the public domain.
 *	THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND
 *	INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS
 *	FOR A PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING,
 *	USAGE OR TRADE PRACTICE.
 *	
 *	This file is provided with no support and without any
 *	obligation on the part of Silicon Graphics, Inc. to assist in
 *	its use, correction, modification or enhancement.
 *	
 *	SILICON GRAPHICS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO
 *	THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY
 *	THIS FILE OR ANY PART THEREOF.
 *	
 *	In no event will Silicon Graphics, Inc. be liable for any lost
 *	revenue or profits or other special, indirect and consequential
 *	damages, even if Silicon Graphics has been advised of the
 *	possibility of such damages.
 */

#include <stdio.h>
#include <nlist.h>

struct nlist nl[] = {
	{ "avenrun" },
	{ "" },
};

main()
{
	int kmem, i;
	long avenrun[3];

	if ((kmem = open("/dev/kmem", 0)) < 0) {
		perror("/dev/kmem");
		exit(1);
	}
	if (nlist("/unix", nl) < 0) {
		fprintf(stderr, "bad namelist\n");
		exit(1);
	}
	if (nl[0].n_type == 0) {
		fprintf(stderr, "can't find avenrun\n");
		exit(1);
        }
	if (lseek(kmem, (long)nl[0].n_value & 0x7fffffff, 0) < 0) {
		perror("lseek");
		exit(1);
	}
	(void) read(kmem, (char *) avenrun, sizeof(avenrun));

	printf("load average:");
	for (i = 0; i < (sizeof(avenrun)/sizeof(avenrun[0])); i++) {
		if (i > 0)
			printf(",");
		printf(" %.2f", ((double) avenrun[i])/1024.0);
	}
	printf("\n");
	exit(0);
}