This is loadave.c in view mode; [Download] [Up]
/* Copyright 1991, 1994 Scott Hess. Permission to use, copy, modify,
* and distribute this software and its documentation for any purpose
* and without fee is hereby granted, provided that this copyright
* notice appear in all copies. The copyright notice need not appear
* on binary-only distributions - just in source code.
*
* Scott Hess makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express
* or implied warranty.
*/
/* Get the current load average from the kernel. Uses the undocumented
* (and nearly non-existant in NS3.0) table() call if available.
* Otherwise, is capable of falling back to direct /dev/kmem reading
* if KMEM is defined (note that this requires the program to run
* setgid to group kmem).
*/
#import "loadave.h"
/* Preliminary gunk the routines want to see. */
#ifdef KMEM
#import <libc.h>
#import <nlist.h>
#import <grp.h>
static struct nlist nl[]={
{{"_cp_time"}, 0, 0, 0, 0}, {{""}, 0, 0, 0, 0}
};
int kmem; /* File descriptor for /dev/kmem. */
#else
#import <strings.h>
#if 0
#import <sys/table.h>
#else
/* NS3.0 doesn't include the <sys/table.h> file. Sigh.
* So, I've snarfed the following without permission from
* <sys/table.h> on an NS2.1 system. The structure, prototype,
* and #define could also likely be found in Mach documentation
* somewhere.
*/
#define TBL_CPUINFO 12 /* (no index), generic CPU info */
/*
* TBL_CPUINFO data layout
*/
struct tbl_cpuinfo
{
int ci_swtch; /* # context switches */
int ci_intr; /* # interrupts */
int ci_syscall; /* # system calls */
int ci_traps; /* # system traps */
int ci_hz; /* # ticks per second */
int ci_phz; /* profiling hz */
int ci_cptime[CPUSTATES]; /* cpu state times */
};
#endif
extern int table( int, int, void *, int, int);
#endif
/* Initialize the package and return the current CPU time values. */
int la_init( long *times)
{
#ifdef KMEM
/* For reading kmem, have to poke through /mach to find
* locations for cp_time, and then open the kmem device for
* reading.
*/
if( nlist( "/mach", nl)) {
return LA_NLIST;
}
if( (kmem=open( "/dev/kmem", O_RDONLY))<0) {
gid_t gid=getegid();
struct group *kmemgr=getgrnam( "kmem");
if( kmemgr->gr_gid!=gid) {
return LA_PERM;
} else {
return LA_KMEM;
}
}
#endif
return la_read( times);
}
/* Return the current CPU time values. */
int la_read( long *times)
{
#ifdef KMEM
/* Seek in kmem to the location of cp_time. */
if( lseek( kmem, nl[ 0].n_value, L_SET)!=nl[ 0].n_value) {
return LA_SEEK;
}
/* Read the values for cp_time. */
if( read( kmem, times, sizeof( long)*CPUSTATES)!=sizeof( long)*CPUSTATES) {
return LA_READ;
}
#else
/* The table() version is a bit simpler - just ask table()
* for the appropriate values.
*/
struct tbl_cpuinfo tc;
if( table( TBL_CPUINFO, 0, &tc, 1, sizeof( tc))>=0) {
bcopy( tc.ci_cptime, times, sizeof( long)*CPUSTATES);
} else {
return LA_TABLE;
}
#endif
return LA_NOERR;
}
/* Clean up after ourselves. */
void la_finish( void)
{
#ifdef KMEM
/* Close up kmem and nuke the fd. */
if( kmem>-1) {
close( kmem);
kmem=-1;
}
#endif
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.