Blame getloadavg.c

Packit Service 62bb50
/* Get the system load averages.
Packit Service 62bb50
Copyright (C) 1985-2016 Free Software Foundation, Inc.
Packit Service 62bb50
Packit Service 62bb50
GNU Make is free software; you can redistribute it and/or modify it under the
Packit Service 62bb50
terms of the GNU General Public License as published by the Free Software
Packit Service 62bb50
Foundation; either version 3 of the License, or (at your option) any later
Packit Service 62bb50
version.
Packit Service 62bb50
Packit Service 62bb50
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
Packit Service 62bb50
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
Packit Service 62bb50
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
Packit Service 62bb50
Packit Service 62bb50
You should have received a copy of the GNU General Public License along with
Packit Service 62bb50
this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit Service 62bb50
Packit Service 62bb50
/* Compile-time symbols that this file uses:
Packit Service 62bb50
Packit Service 62bb50
   HAVE_PSTAT_GETDYNAMIC	Define this if your system has the
Packit Service 62bb50
                                pstat_getdynamic function.  I think it
Packit Service 62bb50
				is unique to HPUX9.  The best way to get the
Packit Service 62bb50
				definition is through the AC_FUNC_GETLOADAVG
Packit Service 62bb50
				macro that comes with autoconf 2.13 or newer.
Packit Service 62bb50
				If that isn't an option, then just put
Packit Service 62bb50
				AC_CHECK_FUNCS(pstat_getdynamic) in your
Packit Service 62bb50
				configure.in file.
Packit Service 62bb50
   FIXUP_KERNEL_SYMBOL_ADDR()	Adjust address in returned struct nlist.
Packit Service 62bb50
   KERNEL_FILE			Pathname of the kernel to nlist.
Packit Service 62bb50
   LDAV_CVT()			Scale the load average from the kernel.
Packit Service 62bb50
				Returns a double.
Packit Service 62bb50
   LDAV_SYMBOL			Name of kernel symbol giving load average.
Packit Service 62bb50
   LOAD_AVE_TYPE		Type of the load average array in the kernel.
Packit Service 62bb50
				Must be defined unless one of
Packit Service 62bb50
				apollo, DGUX, NeXT, or UMAX is defined;
Packit Service 62bb50
                                or we have libkstat;
Packit Service 62bb50
				otherwise, no load average is available.
Packit Service 62bb50
   NLIST_STRUCT			Include nlist.h, not a.out.h, and
Packit Service 62bb50
				the nlist n_name element is a pointer,
Packit Service 62bb50
				not an array.
Packit Service 62bb50
   HAVE_STRUCT_NLIST_N_UN_N_NAME struct nlist has an n_un member, not n_name.
Packit Service 62bb50
   LINUX_LDAV_FILE		[__linux__]: File containing load averages.
Packit Service 62bb50
Packit Service 62bb50
   Specific system predefines this file uses, aside from setting
Packit Service 62bb50
   default values if not emacs:
Packit Service 62bb50
Packit Service 62bb50
   apollo
Packit Service 62bb50
   BSD				Real BSD, not just BSD-like.
Packit Service 62bb50
   convex
Packit Service 62bb50
   DGUX
Packit Service 62bb50
   eunice			UNIX emulator under VMS.
Packit Service 62bb50
   hpux
Packit Service 62bb50
   __MSDOS__			No-op for MSDOS.
Packit Service 62bb50
   NeXT
Packit Service 62bb50
   sgi
Packit Service 62bb50
   sequent			Sequent Dynix 3.x.x (BSD)
Packit Service 62bb50
   _SEQUENT_			Sequent DYNIX/ptx 1.x.x (SYSV)
Packit Service 62bb50
   sony_news                    NEWS-OS (works at least for 4.1C)
Packit Service 62bb50
   UMAX
Packit Service 62bb50
   UMAX4_3
Packit Service 62bb50
   VMS
Packit Service 62bb50
   WINDOWS32			No-op for Windows95/NT.
Packit Service 62bb50
   __linux__			Linux: assumes /proc filesystem mounted.
Packit Service 62bb50
   				Support from Michael K. Johnson.
Packit Service 62bb50
   __NetBSD__			NetBSD: assumes /kern filesystem mounted.
Packit Service 62bb50
Packit Service 62bb50
   In addition, to avoid nesting many #ifdefs, we internally set
Packit Service 62bb50
   LDAV_DONE to indicate that the load average has been computed.
Packit Service 62bb50
Packit Service 62bb50
   We also #define LDAV_PRIVILEGED if a program will require
Packit Service 62bb50
   special installation to be able to call getloadavg.  */
Packit Service 62bb50
Packit Service 62bb50
/* This should always be first.  */
Packit Service 62bb50
#ifdef HAVE_CONFIG_H
Packit Service 62bb50
# include <config.h>
Packit Service 62bb50
#endif
Packit Service 62bb50
Packit Service 62bb50
#include <sys/types.h>
Packit Service 62bb50
Packit Service 62bb50
/* Both the Emacs and non-Emacs sections want this.  Some
Packit Service 62bb50
   configuration files' definitions for the LOAD_AVE_CVT macro (like
Packit Service 62bb50
   sparc.h's) use macros like FSCALE, defined here.  */
Packit Service 62bb50
#if defined (unix) || defined (__unix)
Packit Service 62bb50
# include <sys/param.h>
Packit Service 62bb50
#endif
Packit Service 62bb50
Packit Service 62bb50
Packit Service 62bb50
/* Exclude all the code except the test program at the end
Packit Service 62bb50
   if the system has its own 'getloadavg' function.
Packit Service 62bb50
Packit Service 62bb50
   The declaration of 'errno' is needed by the test program
Packit Service 62bb50
   as well as the function itself, so it comes first.  */
Packit Service 62bb50
Packit Service 62bb50
#include <errno.h>
Packit Service 62bb50
Packit Service 62bb50
#ifndef errno
Packit Service 62bb50
extern int errno;
Packit Service 62bb50
#endif
Packit Service 62bb50
Packit Service 62bb50
#if HAVE_LOCALE_H
Packit Service 62bb50
# include <locale.h>
Packit Service 62bb50
#endif
Packit Service 62bb50
#if !HAVE_SETLOCALE
Packit Service 62bb50
# define setlocale(Category, Locale) /* empty */
Packit Service 62bb50
#endif
Packit Service 62bb50
Packit Service 62bb50
#ifndef HAVE_GETLOADAVG
Packit Service 62bb50
Packit Service 62bb50
Packit Service 62bb50
/* The existing Emacs configuration files define a macro called
Packit Service 62bb50
   LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and
Packit Service 62bb50
   returns the load average multiplied by 100.  What we actually want
Packit Service 62bb50
   is a macro called LDAV_CVT, which returns the load average as an
Packit Service 62bb50
   unmultiplied double.
Packit Service 62bb50
Packit Service 62bb50
   For backwards compatibility, we'll define LDAV_CVT in terms of
Packit Service 62bb50
   LOAD_AVE_CVT, but future machine config files should just define
Packit Service 62bb50
   LDAV_CVT directly.  */
Packit Service 62bb50
Packit Service 62bb50
# if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT)
Packit Service 62bb50
#  define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0)
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if !defined (BSD) && defined (ultrix)
Packit Service 62bb50
/* Ultrix behaves like BSD on Vaxen.  */
Packit Service 62bb50
#  define BSD
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# ifdef NeXT
Packit Service 62bb50
/* NeXT in the 2.{0,1,2} releases defines BSD in <sys/param.h>, which
Packit Service 62bb50
   conflicts with the definition understood in this file, that this
Packit Service 62bb50
   really is BSD. */
Packit Service 62bb50
#  undef BSD
Packit Service 62bb50
Packit Service 62bb50
/* NeXT defines FSCALE in <sys/param.h>.  However, we take FSCALE being
Packit Service 62bb50
   defined to mean that the nlist method should be used, which is not true.  */
Packit Service 62bb50
#  undef FSCALE
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
/* Same issues as for NeXT apply to the HURD-based GNU system.  */
Packit Service 62bb50
# ifdef __GNU__
Packit Service 62bb50
#  undef BSD
Packit Service 62bb50
#  undef FSCALE
Packit Service 62bb50
# endif /* __GNU__ */
Packit Service 62bb50
Packit Service 62bb50
/* Set values that are different from the defaults, which are
Packit Service 62bb50
   set a little farther down with #ifndef.  */
Packit Service 62bb50
Packit Service 62bb50
Packit Service 62bb50
/* Some shorthands.  */
Packit Service 62bb50
Packit Service 62bb50
# if defined (HPUX) && !defined (hpux)
Packit Service 62bb50
#  define hpux
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if defined (__hpux) && !defined (hpux)
Packit Service 62bb50
#  define hpux
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if defined (__sun) && !defined (sun)
Packit Service 62bb50
#  define sun
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if defined(hp300) && !defined(hpux)
Packit Service 62bb50
#  define MORE_BSD
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if defined(ultrix) && defined(mips)
Packit Service 62bb50
#  define decstation
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if defined (__SVR4) && !defined (SVR4)
Packit Service 62bb50
#  define SVR4
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if (defined(sun) && defined(SVR4)) || defined (SOLARIS2)
Packit Service 62bb50
#  define SUNOS_5
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if defined (__osf__) && (defined (__alpha) || defined (__alpha__))
Packit Service 62bb50
#  define OSF_ALPHA
Packit Service 62bb50
#  include <sys/mbuf.h>
Packit Service 62bb50
#  include <sys/socket.h>
Packit Service 62bb50
#  include <net/route.h>
Packit Service 62bb50
#  include <sys/table.h>
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if defined (__osf__) && (defined (mips) || defined (__mips__))
Packit Service 62bb50
#  define OSF_MIPS
Packit Service 62bb50
#  include <sys/table.h>
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
/* UTek's /bin/cc on the 4300 has no architecture specific cpp define by
Packit Service 62bb50
   default, but _MACH_IND_SYS_TYPES is defined in <sys/types.h>.  Combine
Packit Service 62bb50
   that with a couple of other things and we'll have a unique match.  */
Packit Service 62bb50
# if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES)
Packit Service 62bb50
#  define tek4300			/* Define by emacs, but not by other users.  */
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
/* AC_FUNC_GETLOADAVG thinks QNX is SVR4, but it isn't. */
Packit Service 62bb50
# if defined(__QNX__)
Packit Service 62bb50
#  undef SVR4
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars.  */
Packit Service 62bb50
# ifndef LOAD_AVE_TYPE
Packit Service 62bb50
Packit Service 62bb50
#  ifdef MORE_BSD
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef sun
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef decstation
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef _SEQUENT_
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef sgi
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef SVR4
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef sony_news
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef sequent
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef OSF_ALPHA
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  if defined (ardent) && defined (titan)
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef tek4300
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  if defined(alliant) && defined(i860) /* Alliant FX/2800 */
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef _AIX
Packit Service 62bb50
#   define LOAD_AVE_TYPE long
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef convex
Packit Service 62bb50
#   define LOAD_AVE_TYPE double
Packit Service 62bb50
#   ifndef LDAV_CVT
Packit Service 62bb50
#    define LDAV_CVT(n) (n)
Packit Service 62bb50
#   endif
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
# endif /* No LOAD_AVE_TYPE.  */
Packit Service 62bb50
Packit Service 62bb50
# ifdef OSF_ALPHA
Packit Service 62bb50
/* <sys/param.h> defines an incorrect value for FSCALE on Alpha OSF/1,
Packit Service 62bb50
   according to ghazi@noc.rutgers.edu.  */
Packit Service 62bb50
#  undef FSCALE
Packit Service 62bb50
#  define FSCALE 1024.0
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if defined(alliant) && defined(i860) /* Alliant FX/2800 */
Packit Service 62bb50
/* <sys/param.h> defines an incorrect value for FSCALE on an
Packit Service 62bb50
   Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu.  */
Packit Service 62bb50
#  undef FSCALE
Packit Service 62bb50
#  define FSCALE 100.0
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
Packit Service 62bb50
# ifndef	FSCALE
Packit Service 62bb50
Packit Service 62bb50
/* SunOS and some others define FSCALE in sys/param.h.  */
Packit Service 62bb50
Packit Service 62bb50
#  ifdef MORE_BSD
Packit Service 62bb50
#   define FSCALE 2048.0
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  if defined(MIPS) || defined(SVR4) || defined(decstation)
Packit Service 62bb50
#   define FSCALE 256
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  if defined (sgi) || defined (sequent)
Packit Service 62bb50
/* Sometimes both MIPS and sgi are defined, so FSCALE was just defined
Packit Service 62bb50
   above under #ifdef MIPS.  But we want the sgi value.  */
Packit Service 62bb50
#   undef FSCALE
Packit Service 62bb50
#   define	FSCALE 1000.0
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  if defined (ardent) && defined (titan)
Packit Service 62bb50
#   define FSCALE 65536.0
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef tek4300
Packit Service 62bb50
#   define FSCALE 100.0
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
#  ifdef _AIX
Packit Service 62bb50
#   define FSCALE 65536.0
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
# endif	/* Not FSCALE.  */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_CVT) && defined (FSCALE)
Packit Service 62bb50
#  define	LDAV_CVT(n) (((double) (n)) / FSCALE)
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
Packit Service 62bb50
# if defined(sgi) || (defined(mips) && !defined(BSD))
Packit Service 62bb50
#  define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31))
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
Packit Service 62bb50
# if !defined (KERNEL_FILE) && defined (sequent)
Packit Service 62bb50
#  define KERNEL_FILE "/dynix"
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if !defined (KERNEL_FILE) && defined (hpux)
Packit Service 62bb50
#  define KERNEL_FILE "/hp-ux"
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if !defined(KERNEL_FILE) && (defined(_SEQUENT_) || defined(MIPS) || defined(SVR4) || defined(ISC) || defined (sgi) || (defined (ardent) && defined (titan)))
Packit Service 62bb50
#  define KERNEL_FILE "/unix"
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_SYMBOL) && defined (alliant)
Packit Service 62bb50
#  define LDAV_SYMBOL "_Loadavg"
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX))
Packit Service 62bb50
#  define LDAV_SYMBOL "avenrun"
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# ifdef HAVE_UNISTD_H
Packit Service 62bb50
#  include <unistd.h>
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# include <stdio.h>
Packit Service 62bb50
Packit Service 62bb50
/* LOAD_AVE_TYPE should only get defined if we're going to use the
Packit Service 62bb50
   nlist method.  */
Packit Service 62bb50
# if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL)) && !defined(__riscos__)
Packit Service 62bb50
#  define LOAD_AVE_TYPE double
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# ifdef LOAD_AVE_TYPE
Packit Service 62bb50
Packit Service 62bb50
#  ifndef VMS
Packit Service 62bb50
#   ifndef __linux__
Packit Service 62bb50
#    ifdef HAVE_NLIST_H
Packit Service 62bb50
#     include <nlist.h>
Packit Service 62bb50
#    else
Packit Service 62bb50
#     include <a.out.h>
Packit Service 62bb50
#    endif
Packit Service 62bb50
Packit Service 62bb50
#    ifdef SUNOS_5
Packit Service 62bb50
#     include <fcntl.h>
Packit Service 62bb50
#     include <kvm.h>
Packit Service 62bb50
#     include <kstat.h>
Packit Service 62bb50
#    endif
Packit Service 62bb50
Packit Service 62bb50
#    if defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
Packit Service 62bb50
#     include <sys/pstat.h>
Packit Service 62bb50
#    endif
Packit Service 62bb50
Packit Service 62bb50
#    ifndef KERNEL_FILE
Packit Service 62bb50
#     define KERNEL_FILE "/vmunix"
Packit Service 62bb50
#    endif /* KERNEL_FILE */
Packit Service 62bb50
Packit Service 62bb50
#    ifndef LDAV_SYMBOL
Packit Service 62bb50
#     define LDAV_SYMBOL "_avenrun"
Packit Service 62bb50
#    endif /* LDAV_SYMBOL */
Packit Service 62bb50
#   endif /* __linux__ */
Packit Service 62bb50
Packit Service 62bb50
#  else /* VMS */
Packit Service 62bb50
Packit Service 62bb50
#   ifndef eunice
Packit Service 62bb50
#    include <iodef.h>
Packit Service 62bb50
#    include <descrip.h>
Packit Service 62bb50
#   else /* eunice */
Packit Service 62bb50
#    include <vms/iodef.h>
Packit Service 62bb50
#   endif /* eunice */
Packit Service 62bb50
#  endif /* VMS */
Packit Service 62bb50
Packit Service 62bb50
#  ifndef LDAV_CVT
Packit Service 62bb50
#   define LDAV_CVT(n) ((double) (n))
Packit Service 62bb50
#  endif /* !LDAV_CVT */
Packit Service 62bb50
Packit Service 62bb50
# endif /* LOAD_AVE_TYPE */
Packit Service 62bb50
Packit Service 62bb50
# if defined(__GNU__) && !defined (NeXT)
Packit Service 62bb50
/* Note that NeXT Openstep defines __GNU__ even though it should not.  */
Packit Service 62bb50
/* GNU system acts much like NeXT, for load average purposes,
Packit Service 62bb50
   but not exactly.  */
Packit Service 62bb50
#  define NeXT
Packit Service 62bb50
#  define host_self mach_host_self
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# ifdef NeXT
Packit Service 62bb50
#  ifdef HAVE_MACH_MACH_H
Packit Service 62bb50
#   include <mach/mach.h>
Packit Service 62bb50
#  else
Packit Service 62bb50
#   include <mach.h>
Packit Service 62bb50
#  endif
Packit Service 62bb50
# endif /* NeXT */
Packit Service 62bb50
Packit Service 62bb50
# ifdef sgi
Packit Service 62bb50
#  include <sys/sysmp.h>
Packit Service 62bb50
# endif /* sgi */
Packit Service 62bb50
Packit Service 62bb50
# ifdef UMAX
Packit Service 62bb50
#  include <stdio.h>
Packit Service 62bb50
#  include <signal.h>
Packit Service 62bb50
#  include <sys/time.h>
Packit Service 62bb50
#  include <sys/wait.h>
Packit Service 62bb50
#  include <sys/syscall.h>
Packit Service 62bb50
Packit Service 62bb50
#  ifdef UMAX_43
Packit Service 62bb50
#   include <machine/cpu.h>
Packit Service 62bb50
#   include <inq_stats/statistics.h>
Packit Service 62bb50
#   include <inq_stats/sysstats.h>
Packit Service 62bb50
#   include <inq_stats/cpustats.h>
Packit Service 62bb50
#   include <inq_stats/procstats.h>
Packit Service 62bb50
#  else /* Not UMAX_43.  */
Packit Service 62bb50
#   include <sys/sysdefs.h>
Packit Service 62bb50
#   include <sys/statistics.h>
Packit Service 62bb50
#   include <sys/sysstats.h>
Packit Service 62bb50
#   include <sys/cpudefs.h>
Packit Service 62bb50
#   include <sys/cpustats.h>
Packit Service 62bb50
#   include <sys/procstats.h>
Packit Service 62bb50
#  endif /* Not UMAX_43.  */
Packit Service 62bb50
# endif /* UMAX */
Packit Service 62bb50
Packit Service 62bb50
# ifdef DGUX
Packit Service 62bb50
#  include <sys/dg_sys_info.h>
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION)
Packit Service 62bb50
#  include <fcntl.h>
Packit Service 62bb50
# else
Packit Service 62bb50
#  include <sys/file.h>
Packit Service 62bb50
# endif
Packit Service 62bb50

Packit Service 62bb50
Packit Service 62bb50
/* Avoid static vars inside a function since in HPUX they dump as pure.  */
Packit Service 62bb50
Packit Service 62bb50
# ifdef NeXT
Packit Service 62bb50
static processor_set_t default_set;
Packit Service 62bb50
static int getloadavg_initialized;
Packit Service 62bb50
# endif /* NeXT */
Packit Service 62bb50
Packit Service 62bb50
# ifdef UMAX
Packit Service 62bb50
static unsigned int cpus = 0;
Packit Service 62bb50
static unsigned int samples;
Packit Service 62bb50
# endif /* UMAX */
Packit Service 62bb50
Packit Service 62bb50
# ifdef DGUX
Packit Service 62bb50
static struct dg_sys_info_load_info load_info;	/* what-a-mouthful! */
Packit Service 62bb50
# endif /* DGUX */
Packit Service 62bb50
Packit Service 62bb50
#if !defined(HAVE_LIBKSTAT) && defined(LOAD_AVE_TYPE)
Packit Service 62bb50
/* File descriptor open to /dev/kmem or VMS load ave driver.  */
Packit Service 62bb50
static int channel;
Packit Service 62bb50
/* Nonzero iff channel is valid.  */
Packit Service 62bb50
static int getloadavg_initialized;
Packit Service 62bb50
/* Offset in kmem to seek to read load average, or 0 means invalid.  */
Packit Service 62bb50
static long offset;
Packit Service 62bb50
Packit Service 62bb50
#if !defined(VMS) && !defined(sgi) && !defined(__linux__)
Packit Service 62bb50
static struct nlist nl[2];
Packit Service 62bb50
#endif /* Not VMS or sgi */
Packit Service 62bb50
Packit Service 62bb50
#ifdef SUNOS_5
Packit Service 62bb50
static kvm_t *kd;
Packit Service 62bb50
#endif /* SUNOS_5 */
Packit Service 62bb50
Packit Service 62bb50
#endif /* LOAD_AVE_TYPE && !HAVE_LIBKSTAT */
Packit Service 62bb50

Packit Service 62bb50
/* Put the 1 minute, 5 minute and 15 minute load averages
Packit Service 62bb50
   into the first NELEM elements of LOADAVG.
Packit Service 62bb50
   Return the number written (never more than 3, but may be less than NELEM),
Packit Service 62bb50
   or -1 if an error occurred.  */
Packit Service 62bb50
Packit Service 62bb50
int
Packit Service 62bb50
getloadavg (double loadavg[], int nelem)
Packit Service 62bb50
{
Packit Service 62bb50
  int elem = 0;			/* Return value.  */
Packit Service 62bb50
Packit Service 62bb50
# ifdef NO_GET_LOAD_AVG
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
  /* Set errno to zero to indicate that there was no particular error;
Packit Service 62bb50
     this function just can't work at all on this system.  */
Packit Service 62bb50
  errno = 0;
Packit Service 62bb50
  elem = -1;
Packit Service 62bb50
# endif
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT)
Packit Service 62bb50
/* Use libkstat because we don't have to be root.  */
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
  kstat_ctl_t *kc;
Packit Service 62bb50
  kstat_t *ksp;
Packit Service 62bb50
  kstat_named_t *kn;
Packit Service 62bb50
Packit Service 62bb50
  kc = kstat_open ();
Packit Service 62bb50
  if (kc == 0)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
  ksp = kstat_lookup (kc, "unix", 0, "system_misc");
Packit Service 62bb50
  if (ksp == 0 )
Packit Service 62bb50
    return -1;
Packit Service 62bb50
  if (kstat_read (kc, ksp, 0) == -1)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
Packit Service 62bb50
Packit Service 62bb50
  kn = kstat_data_lookup (ksp, "avenrun_1min");
Packit Service 62bb50
  if (kn == 0)
Packit Service 62bb50
    {
Packit Service 62bb50
      /* Return -1 if no load average information is available.  */
Packit Service 62bb50
      nelem = 0;
Packit Service 62bb50
      elem = -1;
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  if (nelem >= 1)
Packit Service 62bb50
    loadavg[elem++] = (double) kn->value.ul/FSCALE;
Packit Service 62bb50
Packit Service 62bb50
  if (nelem >= 2)
Packit Service 62bb50
    {
Packit Service 62bb50
      kn = kstat_data_lookup (ksp, "avenrun_5min");
Packit Service 62bb50
      if (kn != 0)
Packit Service 62bb50
	{
Packit Service 62bb50
	  loadavg[elem++] = (double) kn->value.ul/FSCALE;
Packit Service 62bb50
Packit Service 62bb50
	  if (nelem >= 3)
Packit Service 62bb50
	    {
Packit Service 62bb50
	      kn = kstat_data_lookup (ksp, "avenrun_15min");
Packit Service 62bb50
	      if (kn != 0)
Packit Service 62bb50
		loadavg[elem++] = (double) kn->value.ul/FSCALE;
Packit Service 62bb50
	    }
Packit Service 62bb50
	}
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  kstat_close (kc);
Packit Service 62bb50
# endif /* HAVE_LIBKSTAT */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
Packit Service 62bb50
/* Use pstat_getdynamic() because we don't have to be root.  */
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
#  undef LOAD_AVE_TYPE
Packit Service 62bb50
Packit Service 62bb50
  struct pst_dynamic dyn_info;
Packit Service 62bb50
  if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
  if (nelem > 0)
Packit Service 62bb50
    loadavg[elem++] = dyn_info.psd_avg_1_min;
Packit Service 62bb50
  if (nelem > 1)
Packit Service 62bb50
    loadavg[elem++] = dyn_info.psd_avg_5_min;
Packit Service 62bb50
  if (nelem > 2)
Packit Service 62bb50
    loadavg[elem++] = dyn_info.psd_avg_15_min;
Packit Service 62bb50
Packit Service 62bb50
# endif /* hpux && HAVE_PSTAT_GETDYNAMIC */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (__linux__)
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
#  undef LOAD_AVE_TYPE
Packit Service 62bb50
Packit Service 62bb50
#  ifndef LINUX_LDAV_FILE
Packit Service 62bb50
#   define LINUX_LDAV_FILE "/proc/loadavg"
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
  char ldavgbuf[40];
Packit Service 62bb50
  double load_ave[3];
Packit Service 62bb50
  int fd, count;
Packit Service 62bb50
Packit Service 62bb50
  fd = open (LINUX_LDAV_FILE, O_RDONLY);
Packit Service 62bb50
  if (fd == -1)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
  count = read (fd, ldavgbuf, 40);
Packit Service 62bb50
  (void) close (fd);
Packit Service 62bb50
  if (count <= 0)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
Packit Service 62bb50
  /* The following sscanf must use the C locale.  */
Packit Service 62bb50
  setlocale (LC_NUMERIC, "C");
Packit Service 62bb50
  count = sscanf (ldavgbuf, "%lf %lf %lf",
Packit Service 62bb50
		  &load_ave[0], &load_ave[1], &load_ave[2]);
Packit Service 62bb50
  setlocale (LC_NUMERIC, "");
Packit Service 62bb50
  if (count < 1)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
Packit Service 62bb50
  for (elem = 0; elem < nelem && elem < count; elem++)
Packit Service 62bb50
    loadavg[elem] = load_ave[elem];
Packit Service 62bb50
Packit Service 62bb50
  return elem;
Packit Service 62bb50
Packit Service 62bb50
# endif /* __linux__ */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (__NetBSD__)
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
#  undef LOAD_AVE_TYPE
Packit Service 62bb50
Packit Service 62bb50
#  ifndef NETBSD_LDAV_FILE
Packit Service 62bb50
#   define NETBSD_LDAV_FILE "/kern/loadavg"
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
  unsigned long int load_ave[3], scale;
Packit Service 62bb50
  int count;
Packit Service 62bb50
  FILE *fp;
Packit Service 62bb50
Packit Service 62bb50
  fp = fopen (NETBSD_LDAV_FILE, "r");
Packit Service 62bb50
  if (fp == NULL)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
  count = fscanf (fp, "%lu %lu %lu %lu\n",
Packit Service 62bb50
		  &load_ave[0], &load_ave[1], &load_ave[2],
Packit Service 62bb50
		  &scale);
Packit Service 62bb50
  (void) fclose (fp);
Packit Service 62bb50
  if (count != 4)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
Packit Service 62bb50
  for (elem = 0; elem < nelem; elem++)
Packit Service 62bb50
    loadavg[elem] = (double) load_ave[elem] / (double) scale;
Packit Service 62bb50
Packit Service 62bb50
  return elem;
Packit Service 62bb50
Packit Service 62bb50
# endif /* __NetBSD__ */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (NeXT)
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
  /* The NeXT code was adapted from iscreen 3.2.  */
Packit Service 62bb50
Packit Service 62bb50
  host_t host;
Packit Service 62bb50
  struct processor_set_basic_info info;
Packit Service 62bb50
  unsigned info_count;
Packit Service 62bb50
Packit Service 62bb50
  /* We only know how to get the 1-minute average for this system,
Packit Service 62bb50
     so even if the caller asks for more than 1, we only return 1.  */
Packit Service 62bb50
Packit Service 62bb50
  if (!getloadavg_initialized)
Packit Service 62bb50
    {
Packit Service 62bb50
      if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
Packit Service 62bb50
	getloadavg_initialized = 1;
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  if (getloadavg_initialized)
Packit Service 62bb50
    {
Packit Service 62bb50
      info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
Packit Service 62bb50
      if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
Packit Service 62bb50
			      (processor_set_info_t) &info, &info_count)
Packit Service 62bb50
	  != KERN_SUCCESS)
Packit Service 62bb50
	getloadavg_initialized = 0;
Packit Service 62bb50
      else
Packit Service 62bb50
	{
Packit Service 62bb50
	  if (nelem > 0)
Packit Service 62bb50
	    loadavg[elem++] = (double) info.load_average / LOAD_SCALE;
Packit Service 62bb50
	}
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  if (!getloadavg_initialized)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
# endif /* NeXT */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (UMAX)
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
/* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
Packit Service 62bb50
   have a /dev/kmem.  Information about the workings of the running kernel
Packit Service 62bb50
   can be gathered with inq_stats system calls.
Packit Service 62bb50
   We only know how to get the 1-minute average for this system.  */
Packit Service 62bb50
Packit Service 62bb50
  struct proc_summary proc_sum_data;
Packit Service 62bb50
  struct stat_descr proc_info;
Packit Service 62bb50
  double load;
Packit Service 62bb50
  register unsigned int i, j;
Packit Service 62bb50
Packit Service 62bb50
  if (cpus == 0)
Packit Service 62bb50
    {
Packit Service 62bb50
      register unsigned int c, i;
Packit Service 62bb50
      struct cpu_config conf;
Packit Service 62bb50
      struct stat_descr desc;
Packit Service 62bb50
Packit Service 62bb50
      desc.sd_next = 0;
Packit Service 62bb50
      desc.sd_subsys = SUBSYS_CPU;
Packit Service 62bb50
      desc.sd_type = CPUTYPE_CONFIG;
Packit Service 62bb50
      desc.sd_addr = (char *) &conf;
Packit Service 62bb50
      desc.sd_size = sizeof conf;
Packit Service 62bb50
Packit Service 62bb50
      if (inq_stats (1, &desc))
Packit Service 62bb50
	return -1;
Packit Service 62bb50
Packit Service 62bb50
      c = 0;
Packit Service 62bb50
      for (i = 0; i < conf.config_maxclass; ++i)
Packit Service 62bb50
	{
Packit Service 62bb50
	  struct class_stats stats;
Packit Service 62bb50
	  memset (&stats, '\0', sizeof stats);
Packit Service 62bb50
Packit Service 62bb50
	  desc.sd_type = CPUTYPE_CLASS;
Packit Service 62bb50
	  desc.sd_objid = i;
Packit Service 62bb50
	  desc.sd_addr = (char *) &stat;;
Packit Service 62bb50
	  desc.sd_size = sizeof stats;
Packit Service 62bb50
Packit Service 62bb50
	  if (inq_stats (1, &desc))
Packit Service 62bb50
	    return -1;
Packit Service 62bb50
Packit Service 62bb50
	  c += stats.class_numcpus;
Packit Service 62bb50
	}
Packit Service 62bb50
      cpus = c;
Packit Service 62bb50
      samples = cpus < 2 ? 3 : (2 * cpus / 3);
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  proc_info.sd_next = 0;
Packit Service 62bb50
  proc_info.sd_subsys = SUBSYS_PROC;
Packit Service 62bb50
  proc_info.sd_type = PROCTYPE_SUMMARY;
Packit Service 62bb50
  proc_info.sd_addr = (char *) &proc_sum_data;
Packit Service 62bb50
  proc_info.sd_size = sizeof (struct proc_summary);
Packit Service 62bb50
  proc_info.sd_sizeused = 0;
Packit Service 62bb50
Packit Service 62bb50
  if (inq_stats (1, &proc_info) != 0)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
Packit Service 62bb50
  load = proc_sum_data.ps_nrunnable;
Packit Service 62bb50
  j = 0;
Packit Service 62bb50
  for (i = samples - 1; i > 0; --i)
Packit Service 62bb50
    {
Packit Service 62bb50
      load += proc_sum_data.ps_nrun[j];
Packit Service 62bb50
      if (j++ == PS_NRUNSIZE)
Packit Service 62bb50
	j = 0;
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  if (nelem > 0)
Packit Service 62bb50
    loadavg[elem++] = load / samples / cpus;
Packit Service 62bb50
# endif /* UMAX */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (DGUX)
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
  /* This call can return -1 for an error, but with good args
Packit Service 62bb50
     it's not supposed to fail.  The first argument is for no
Packit Service 62bb50
     apparent reason of type 'long int *'.  */
Packit Service 62bb50
  dg_sys_info ((long int *) &load_info,
Packit Service 62bb50
	       DG_SYS_INFO_LOAD_INFO_TYPE,
Packit Service 62bb50
	       DG_SYS_INFO_LOAD_VERSION_0);
Packit Service 62bb50
Packit Service 62bb50
  if (nelem > 0)
Packit Service 62bb50
    loadavg[elem++] = load_info.one_minute;
Packit Service 62bb50
  if (nelem > 1)
Packit Service 62bb50
    loadavg[elem++] = load_info.five_minute;
Packit Service 62bb50
  if (nelem > 2)
Packit Service 62bb50
    loadavg[elem++] = load_info.fifteen_minute;
Packit Service 62bb50
# endif /* DGUX */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (apollo)
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
/* Apollo code from lisch@mentorg.com (Ray Lischner).
Packit Service 62bb50
Packit Service 62bb50
   This system call is not documented.  The load average is obtained as
Packit Service 62bb50
   three long integers, for the load average over the past minute,
Packit Service 62bb50
   five minutes, and fifteen minutes.  Each value is a scaled integer,
Packit Service 62bb50
   with 16 bits of integer part and 16 bits of fraction part.
Packit Service 62bb50
Packit Service 62bb50
   I'm not sure which operating system first supported this system call,
Packit Service 62bb50
   but I know that SR10.2 supports it.  */
Packit Service 62bb50
Packit Service 62bb50
  extern void proc1_$get_loadav ();
Packit Service 62bb50
  unsigned long load_ave[3];
Packit Service 62bb50
Packit Service 62bb50
  proc1_$get_loadav (load_ave);
Packit Service 62bb50
Packit Service 62bb50
  if (nelem > 0)
Packit Service 62bb50
    loadavg[elem++] = load_ave[0] / 65536.0;
Packit Service 62bb50
  if (nelem > 1)
Packit Service 62bb50
    loadavg[elem++] = load_ave[1] / 65536.0;
Packit Service 62bb50
  if (nelem > 2)
Packit Service 62bb50
    loadavg[elem++] = load_ave[2] / 65536.0;
Packit Service 62bb50
# endif /* apollo */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (OSF_MIPS)
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
Packit Service 62bb50
  struct tbl_loadavg load_ave;
Packit Service 62bb50
  table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
Packit Service 62bb50
  loadavg[elem++]
Packit Service 62bb50
    = (load_ave.tl_lscale == 0
Packit Service 62bb50
       ? load_ave.tl_avenrun.d[0]
Packit Service 62bb50
       : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
Packit Service 62bb50
# endif	/* OSF_MIPS */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32))
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
Packit Service 62bb50
  /* A faithful emulation is going to have to be saved for a rainy day.  */
Packit Service 62bb50
  for ( ; elem < nelem; elem++)
Packit Service 62bb50
    {
Packit Service 62bb50
      loadavg[elem] = 0.0;
Packit Service 62bb50
    }
Packit Service 62bb50
# endif  /* __MSDOS__ || WINDOWS32 */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (OSF_ALPHA)
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
Packit Service 62bb50
  struct tbl_loadavg load_ave;
Packit Service 62bb50
  table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
Packit Service 62bb50
  for (elem = 0; elem < nelem; elem++)
Packit Service 62bb50
    loadavg[elem]
Packit Service 62bb50
      = (load_ave.tl_lscale == 0
Packit Service 62bb50
       ? load_ave.tl_avenrun.d[elem]
Packit Service 62bb50
       : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
Packit Service 62bb50
# endif /* OSF_ALPHA */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (VMS)
Packit Service 62bb50
  /* VMS specific code -- read from the Load Ave driver.  */
Packit Service 62bb50
Packit Service 62bb50
  LOAD_AVE_TYPE load_ave[3];
Packit Service 62bb50
  static int getloadavg_initialized = 0;
Packit Service 62bb50
#  ifdef eunice
Packit Service 62bb50
  struct
Packit Service 62bb50
  {
Packit Service 62bb50
    int dsc$w_length;
Packit Service 62bb50
    char *dsc$a_pointer;
Packit Service 62bb50
  } descriptor;
Packit Service 62bb50
#  endif
Packit Service 62bb50
Packit Service 62bb50
  /* Ensure that there is a channel open to the load ave device.  */
Packit Service 62bb50
  if (!getloadavg_initialized)
Packit Service 62bb50
    {
Packit Service 62bb50
      /* Attempt to open the channel.  */
Packit Service 62bb50
#  ifdef eunice
Packit Service 62bb50
      descriptor.dsc$w_length = 18;
Packit Service 62bb50
      descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE";
Packit Service 62bb50
#  else
Packit Service 62bb50
      $DESCRIPTOR (descriptor, "LAV0:");
Packit Service 62bb50
#  endif
Packit Service 62bb50
      if (sys$assign (&descriptor, &channel, 0, 0) & 1)
Packit Service 62bb50
	getloadavg_initialized = 1;
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  /* Read the load average vector.  */
Packit Service 62bb50
  if (getloadavg_initialized
Packit Service 62bb50
      && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0,
Packit Service 62bb50
		     load_ave, 12, 0, 0, 0, 0) & 1))
Packit Service 62bb50
    {
Packit Service 62bb50
      sys$dassgn (channel);
Packit Service 62bb50
      getloadavg_initialized = 0;
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  if (!getloadavg_initialized)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
# endif /* VMS */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS)
Packit Service 62bb50
Packit Service 62bb50
  /* UNIX-specific code -- read the average from /dev/kmem.  */
Packit Service 62bb50
Packit Service 62bb50
#  define LDAV_PRIVILEGED		/* This code requires special installation.  */
Packit Service 62bb50
Packit Service 62bb50
  LOAD_AVE_TYPE load_ave[3];
Packit Service 62bb50
Packit Service 62bb50
  /* Get the address of LDAV_SYMBOL.  */
Packit Service 62bb50
  if (offset == 0)
Packit Service 62bb50
    {
Packit Service 62bb50
#  ifndef sgi
Packit Service 62bb50
#   ifndef NLIST_STRUCT
Packit Service 62bb50
      strcpy (nl[0].n_name, LDAV_SYMBOL);
Packit Service 62bb50
      strcpy (nl[1].n_name, "");
Packit Service 62bb50
#   else /* NLIST_STRUCT */
Packit Service 62bb50
#    ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
Packit Service 62bb50
      nl[0].n_un.n_name = LDAV_SYMBOL;
Packit Service 62bb50
      nl[1].n_un.n_name = 0;
Packit Service 62bb50
#    else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
Packit Service 62bb50
      nl[0].n_name = LDAV_SYMBOL;
Packit Service 62bb50
      nl[1].n_name = 0;
Packit Service 62bb50
#    endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
Packit Service 62bb50
#   endif /* NLIST_STRUCT */
Packit Service 62bb50
Packit Service 62bb50
#   ifndef SUNOS_5
Packit Service 62bb50
      if (
Packit Service 62bb50
#    if !(defined (_AIX) && !defined (ps2))
Packit Service 62bb50
	  nlist (KERNEL_FILE, nl)
Packit Service 62bb50
#    else  /* _AIX */
Packit Service 62bb50
	  knlist (nl, 1, sizeof (nl[0]))
Packit Service 62bb50
#    endif
Packit Service 62bb50
	  >= 0)
Packit Service 62bb50
	  /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i.  */
Packit Service 62bb50
	  {
Packit Service 62bb50
#    ifdef FIXUP_KERNEL_SYMBOL_ADDR
Packit Service 62bb50
	    FIXUP_KERNEL_SYMBOL_ADDR (nl);
Packit Service 62bb50
#    endif
Packit Service 62bb50
	    offset = nl[0].n_value;
Packit Service 62bb50
	  }
Packit Service 62bb50
#   endif /* !SUNOS_5 */
Packit Service 62bb50
#  else  /* sgi */
Packit Service 62bb50
      int ldav_off;
Packit Service 62bb50
Packit Service 62bb50
      ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
Packit Service 62bb50
      if (ldav_off != -1)
Packit Service 62bb50
	offset = (long) ldav_off & 0x7fffffff;
Packit Service 62bb50
#  endif /* sgi */
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  /* Make sure we have /dev/kmem open.  */
Packit Service 62bb50
  if (!getloadavg_initialized)
Packit Service 62bb50
    {
Packit Service 62bb50
#  ifndef SUNOS_5
Packit Service 62bb50
      channel = open ("/dev/kmem", 0);
Packit Service 62bb50
      if (channel >= 0)
Packit Service 62bb50
	{
Packit Service 62bb50
	  /* Set the channel to close on exec, so it does not
Packit Service 62bb50
	     litter any child's descriptor table.  */
Packit Service 62bb50
#   ifdef F_SETFD
Packit Service 62bb50
#    ifndef FD_CLOEXEC
Packit Service 62bb50
#     define FD_CLOEXEC 1
Packit Service 62bb50
#    endif
Packit Service 62bb50
	  (void) fcntl (channel, F_SETFD, FD_CLOEXEC);
Packit Service 62bb50
#   endif
Packit Service 62bb50
	  getloadavg_initialized = 1;
Packit Service 62bb50
	}
Packit Service 62bb50
#  else /* SUNOS_5 */
Packit Service 62bb50
      /* We pass 0 for the kernel, corefile, and swapfile names
Packit Service 62bb50
	 to use the currently running kernel.  */
Packit Service 62bb50
      kd = kvm_open (0, 0, 0, O_RDONLY, 0);
Packit Service 62bb50
      if (kd != 0)
Packit Service 62bb50
	{
Packit Service 62bb50
	  /* nlist the currently running kernel.  */
Packit Service 62bb50
	  kvm_nlist (kd, nl);
Packit Service 62bb50
	  offset = nl[0].n_value;
Packit Service 62bb50
	  getloadavg_initialized = 1;
Packit Service 62bb50
	}
Packit Service 62bb50
#  endif /* SUNOS_5 */
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  /* If we can, get the load average values.  */
Packit Service 62bb50
  if (offset && getloadavg_initialized)
Packit Service 62bb50
    {
Packit Service 62bb50
      /* Try to read the load.  */
Packit Service 62bb50
#  ifndef SUNOS_5
Packit Service 62bb50
      if (lseek (channel, offset, 0) == -1L
Packit Service 62bb50
	  || read (channel, (char *) load_ave, sizeof (load_ave))
Packit Service 62bb50
	  != sizeof (load_ave))
Packit Service 62bb50
	{
Packit Service 62bb50
	  close (channel);
Packit Service 62bb50
	  getloadavg_initialized = 0;
Packit Service 62bb50
	}
Packit Service 62bb50
#  else  /* SUNOS_5 */
Packit Service 62bb50
      if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
Packit Service 62bb50
	  != sizeof (load_ave))
Packit Service 62bb50
        {
Packit Service 62bb50
          kvm_close (kd);
Packit Service 62bb50
          getloadavg_initialized = 0;
Packit Service 62bb50
	}
Packit Service 62bb50
#  endif /* SUNOS_5 */
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  if (offset == 0 || !getloadavg_initialized)
Packit Service 62bb50
    return -1;
Packit Service 62bb50
# endif /* LOAD_AVE_TYPE and not VMS */
Packit Service 62bb50
Packit Service 62bb50
# if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS.  */
Packit Service 62bb50
  if (nelem > 0)
Packit Service 62bb50
    loadavg[elem++] = LDAV_CVT (load_ave[0]);
Packit Service 62bb50
  if (nelem > 1)
Packit Service 62bb50
    loadavg[elem++] = LDAV_CVT (load_ave[1]);
Packit Service 62bb50
  if (nelem > 2)
Packit Service 62bb50
    loadavg[elem++] = LDAV_CVT (load_ave[2]);
Packit Service 62bb50
Packit Service 62bb50
#  define LDAV_DONE
Packit Service 62bb50
# endif /* !LDAV_DONE && LOAD_AVE_TYPE */
Packit Service 62bb50
Packit Service 62bb50
# ifdef LDAV_DONE
Packit Service 62bb50
  return elem;
Packit Service 62bb50
# else
Packit Service 62bb50
  /* Set errno to zero to indicate that there was no particular error;
Packit Service 62bb50
     this function just can't work at all on this system.  */
Packit Service 62bb50
  errno = 0;
Packit Service 62bb50
  return -1;
Packit Service 62bb50
# endif
Packit Service 62bb50
}
Packit Service 62bb50
Packit Service 62bb50
#endif /* ! HAVE_GETLOADAVG */
Packit Service 62bb50

Packit Service 62bb50
#ifdef TEST
Packit Service 62bb50
#include "makeint.h"
Packit Service 62bb50
Packit Service 62bb50
int
Packit Service 62bb50
main (int argc, char **argv)
Packit Service 62bb50
{
Packit Service 62bb50
  int naptime = 0;
Packit Service 62bb50
Packit Service 62bb50
  if (argc > 1)
Packit Service 62bb50
    naptime = atoi (argv[1]);
Packit Service 62bb50
Packit Service 62bb50
  while (1)
Packit Service 62bb50
    {
Packit Service 62bb50
      double avg[3];
Packit Service 62bb50
      int loads;
Packit Service 62bb50
Packit Service 62bb50
      errno = 0;		/* Don't be misled if it doesn't set errno.  */
Packit Service 62bb50
      loads = getloadavg (avg, 3);
Packit Service 62bb50
      if (loads == -1)
Packit Service 62bb50
	{
Packit Service 62bb50
	  perror ("Error getting load average");
Packit Service 62bb50
	  exit (1);
Packit Service 62bb50
	}
Packit Service 62bb50
      if (loads > 0)
Packit Service 62bb50
	printf ("1-minute: %f  ", avg[0]);
Packit Service 62bb50
      if (loads > 1)
Packit Service 62bb50
	printf ("5-minute: %f  ", avg[1]);
Packit Service 62bb50
      if (loads > 2)
Packit Service 62bb50
	printf ("15-minute: %f  ", avg[2]);
Packit Service 62bb50
      if (loads > 0)
Packit Service 62bb50
	putchar ('\n');
Packit Service 62bb50
Packit Service 62bb50
      if (naptime == 0)
Packit Service 62bb50
	break;
Packit Service 62bb50
      sleep (naptime);
Packit Service 62bb50
    }
Packit Service 62bb50
Packit Service 62bb50
  exit (0);
Packit Service 62bb50
}
Packit Service 62bb50
#endif /* TEST */