(linenum→info "unix/slp.c:2238")

emacs/22.1/src/getloadavg.c

    1: /* Get the system load averages.
    2:    Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995,
    3:                  1997, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    4:                  Free Software Foundation, Inc.
    5: 
    6:    NOTE: The canonical source of this file is maintained with gnulib.
    7:    Bugs can be reported to bug-gnulib@gnu.org.
    8: 
    9:    This program is free software; you can redistribute it and/or modify
   10:    it under the terms of the GNU General Public License as published by
   11:    the Free Software Foundation; either version 2, or (at your option)
   12:    any later version.
   13: 
   14:    This program is distributed in the hope that it will be useful,
   15:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   16:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17:    GNU General Public License for more details.
   18: 
   19:    You should have received a copy of the GNU General Public License
   20:    along with this program; if not, write to the Free Software
   21:    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   22:    USA.  */
   23: 
   24: /* Compile-time symbols that this file uses:
   25: 
   26:    HAVE_PSTAT_GETDYNAMIC        Define this if your system has the
   27:                                 pstat_getdynamic function.  I think it
   28:                                 is unique to HPUX9.  The best way to get the
   29:                                 definition is through the AC_FUNC_GETLOADAVG
   30:                                 macro that comes with autoconf 2.13 or newer.
   31:                                 If that isn't an option, then just put
   32:                                 AC_CHECK_FUNCS(pstat_getdynamic) in your
   33:                                 configure.in file.
   34:    FIXUP_KERNEL_SYMBOL_ADDR()   Adjust address in returned struct nlist.
   35:    KERNEL_FILE                  Pathname of the kernel to nlist.
   36:    LDAV_CVT()                   Scale the load average from the kernel.
   37:                                 Returns a double.
   38:    LDAV_SYMBOL                  Name of kernel symbol giving load average.
   39:    LOAD_AVE_TYPE                Type of the load average array in the kernel.
   40:                                 Must be defined unless one of
   41:                                 apollo, DGUX, NeXT, or UMAX is defined;
   42:                                 or we have libkstat;
   43:                                 otherwise, no load average is available.
   44:    HAVE_NLIST_H                 nlist.h is available.  NLIST_STRUCT defaults
   45:                                 to this.
   46:    NLIST_STRUCT                 Include nlist.h, not a.out.h, and
   47:                                 the nlist n_name element is a pointer,
   48:                                 not an array.
   49:    HAVE_STRUCT_NLIST_N_UN_N_NAME `n_un.n_name' is member of `struct nlist'.
   50:    LINUX_LDAV_FILE              [__linux__]: File containing load averages.
   51:    HAVE_LOCALE_H                locale.h is available.
   52:    HAVE_SETLOCALE               The `setlocale' function is available.
   53: 
   54:    Specific system predefines this file uses, aside from setting
   55:    default values if not emacs:
   56: 
   57:    apollo
   58:    BSD                          Real BSD, not just BSD-like.
   59:    convex
   60:    DGUX
   61:    eunice                       UNIX emulator under VMS.
   62:    hpux
   63:    __MSDOS__                    No-op for MSDOS.
   64:    NeXT
   65:    sgi
   66:    sequent                      Sequent Dynix 3.x.x (BSD)
   67:    _SEQUENT_                    Sequent DYNIX/ptx 1.x.x (SYSV)
   68:    sony_news                    NEWS-OS (works at least for 4.1C)
   69:    UMAX
   70:    UMAX4_3
   71:    VMS
   72:    WINDOWS32                    No-op for Windows95/NT.
   73:    __linux__                    Linux: assumes /proc filesystem mounted.
   74:                                 Support from Michael K. Johnson.
   75:    __NetBSD__                   NetBSD: assumes /kern filesystem mounted.
   76: 
   77:    In addition, to avoid nesting many #ifdefs, we internally set
   78:    LDAV_DONE to indicate that the load average has been computed.
   79: 
   80:    We also #define LDAV_PRIVILEGED if a program will require
   81:    special installation to be able to call getloadavg.  */
   82: 
   83: /* This should always be first.  */
   84: #ifdef HAVE_CONFIG_H
   85: # include <config.h>
   86: #endif
   87: 
   88: #include <sys/types.h>
   89: 
   90: /* Both the Emacs and non-Emacs sections want this.  Some
   91:    configuration files' definitions for the LOAD_AVE_CVT macro (like
   92:    sparc.h's) use macros like FSCALE, defined here.  */
   93: #if defined (unix) || defined (__unix)
   94: # include <sys/param.h>
   95: #endif
   96: 
   97: 
   98: /* Exclude all the code except the test program at the end
   99:    if the system has its own `getloadavg' function.
  100: 
  101:    The declaration of `errno' is needed by the test program
  102:    as well as the function itself, so it comes first.  */
  103: 
  104: #include <errno.h>
  105: 
  106: #ifndef errno
  107: extern int errno;
  108: #endif
  109: 
  110: #ifdef HAVE_LOCALE_H
  111: # include <locale.h>
  112: #endif
  113: #ifndef HAVE_SETLOCALE
  114: # define setlocale(Category, Locale) /* empty */
  115: #endif
  116: 
  117: #ifndef HAVE_GETLOADAVG
  118: 
  119: /* The existing Emacs configuration files define a macro called
  120:    LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and
  121:    returns the load average multiplied by 100.  What we actually want
  122:    is a macro called LDAV_CVT, which returns the load average as an
  123:    unmultiplied double.
  124: 
  125:    For backwards compatibility, we'll define LDAV_CVT in terms of
  126:    LOAD_AVE_CVT, but future machine config files should just define
  127:    LDAV_CVT directly.  */
  128: 
  129: # if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT)
  130: #  define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0)
  131: # endif
  132: 
  133: # if !defined (BSD) && defined (ultrix)
  134: /* Ultrix behaves like BSD on Vaxen.  */
  135: #  define BSD
  136: # endif
  137: 
  138: # ifdef NeXT
  139: /* NeXT in the 2.{0,1,2} releases defines BSD in <sys/param.h>, which
  140:    conflicts with the definition understood in this file, that this
  141:    really is BSD. */
  142: #  undef BSD
  143: 
  144: /* NeXT defines FSCALE in <sys/param.h>.  However, we take FSCALE being
  145:    defined to mean that the nlist method should be used, which is not true.  */
  146: #  undef FSCALE
  147: # endif
  148: 
  149: /* Same issues as for NeXT apply to the HURD-based GNU system.  */
  150: # ifdef __GNU__
  151: #  undef BSD
  152: #  undef FSCALE
  153: # endif /* __GNU__ */
  154: 
  155: /* Set values that are different from the defaults, which are
  156:    set a little farther down with #ifndef.  */
  157: 
  158: 
  159: /* Some shorthands.  */
  160: 
  161: # if defined (HPUX) && !defined (hpux)
  162: #  define hpux
  163: # endif
  164: 
  165: # if defined (__hpux) && !defined (hpux)
  166: #  define hpux
  167: # endif
  168: 
  169: # if defined (__sun) && !defined (sun)
  170: #  define sun
  171: # endif
  172: 
  173: # if defined(hp300) && !defined(hpux)
  174: #  define MORE_BSD
  175: # endif
  176: 
  177: # if defined(ultrix) && defined(mips)
  178: #  define decstation
  179: # endif
  180: 
  181: # if defined (__SVR4) && !defined (SVR4)
  182: #  define SVR4
  183: # endif
  184: 
  185: # if (defined(sun) && defined(SVR4)) || defined (SOLARIS2)
  186: #  define SUNOS_5
  187: # endif
  188: 
  189: # if defined (__osf__) && (defined (__alpha) || defined (__alpha__))
  190: #  define OSF_ALPHA
  191: #  include <sys/mbuf.h>
  192: #  include <sys/socket.h>
  193: #  include <net/route.h>
  194: #  include <sys/table.h>
  195: # endif
  196: 
  197: # if defined (__osf__) && (defined (mips) || defined (__mips__))
  198: #  define OSF_MIPS
  199: #  include <sys/table.h>
  200: # endif
  201: 
  202: /* UTek's /bin/cc on the 4300 has no architecture specific cpp define by
  203:    default, but _MACH_IND_SYS_TYPES is defined in <sys/types.h>.  Combine
  204:    that with a couple of other things and we'll have a unique match.  */
  205: # if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES)
  206: #  define tek4300                       /* Define by emacs, but not by other users.  */
  207: # endif
  208: 
  209: 
  210: /* VAX C can't handle multi-line #ifs, or lines longer than 256 chars.  */
  211: # ifndef LOAD_AVE_TYPE
  212: 
  213: #  ifdef MORE_BSD
  214: #   define LOAD_AVE_TYPE long
  215: #  endif
  216: 
  217: #  ifdef sun
  218: #   define LOAD_AVE_TYPE long
  219: #  endif
  220: 
  221: #  ifdef decstation
  222: #   define LOAD_AVE_TYPE long
  223: #  endif
  224: 
  225: #  ifdef _SEQUENT_
  226: #   define LOAD_AVE_TYPE long
  227: #  endif
  228: 
  229: #  ifdef sgi
  230: #   define LOAD_AVE_TYPE long
  231: #  endif
  232: 
  233: #  ifdef SVR4
  234: #   define LOAD_AVE_TYPE long
  235: #  endif
  236: 
  237: #  ifdef sony_news
  238: #   define LOAD_AVE_TYPE long
  239: #  endif
  240: 
  241: #  ifdef sequent
  242: #   define LOAD_AVE_TYPE long
  243: #  endif
  244: 
  245: #  ifdef OSF_ALPHA
  246: #   define LOAD_AVE_TYPE long
  247: #  endif
  248: 
  249: #  if defined (ardent) && defined (titan)
  250: #   define LOAD_AVE_TYPE long
  251: #  endif
  252: 
  253: #  ifdef tek4300
  254: #   define LOAD_AVE_TYPE long
  255: #  endif
  256: 
  257: #  if defined(alliant) && defined(i860) /* Alliant FX/2800 */
  258: #   define LOAD_AVE_TYPE long
  259: #  endif
  260: 
  261: #  ifdef _AIX
  262: #   define LOAD_AVE_TYPE long
  263: #  endif
  264: 
  265: #  ifdef convex
  266: #   define LOAD_AVE_TYPE double
  267: #   ifndef LDAV_CVT
  268: #    define LDAV_CVT(n) (n)
  269: #   endif
  270: #  endif
  271: 
  272: # endif /* No LOAD_AVE_TYPE.  */
  273: 
  274: # ifdef OSF_ALPHA
  275: /* <sys/param.h> defines an incorrect value for FSCALE on Alpha OSF/1,
  276:    according to ghazi@noc.rutgers.edu.  */
  277: #  undef FSCALE
  278: #  define FSCALE 1024.0
  279: # endif
  280: 
  281: # if defined(alliant) && defined(i860) /* Alliant FX/2800 */
  282: /* <sys/param.h> defines an incorrect value for FSCALE on an
  283:    Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu.  */
  284: #  undef FSCALE
  285: #  define FSCALE 100.0
  286: # endif
  287: 
  288: 
  289: # ifndef        FSCALE
  290: 
  291: /* SunOS and some others define FSCALE in sys/param.h.  */
  292: 
  293: #  ifdef MORE_BSD
  294: #   define FSCALE 2048.0
  295: #  endif
  296: 
  297: #  if defined(MIPS) || defined(SVR4) || defined(decstation)
  298: #   define FSCALE 256
  299: #  endif
  300: 
  301: #  if defined (sgi) || defined (sequent)
  302: /* Sometimes both MIPS and sgi are defined, so FSCALE was just defined
  303:    above under #ifdef MIPS.  But we want the sgi value.  */
  304: #   undef FSCALE
  305: #   define FSCALE 1000.0
  306: #  endif
  307: 
  308: #  if defined (ardent) && defined (titan)
  309: #   define FSCALE 65536.0
  310: #  endif
  311: 
  312: #  ifdef tek4300
  313: #   define FSCALE 100.0
  314: #  endif
  315: 
  316: #  ifdef _AIX
  317: #   define FSCALE 65536.0
  318: #  endif
  319: 
  320: # endif /* Not FSCALE.  */
  321: 
  322: # if !defined (LDAV_CVT) && defined (FSCALE)
  323: #  define LDAV_CVT(n) (((double) (n)) / FSCALE)
  324: # endif
  325: 
  326: # ifndef NLIST_STRUCT
  327: #  if HAVE_NLIST_H
  328: #   define NLIST_STRUCT
  329: #  endif
  330: # endif
  331: 
  332: # if defined(sgi) || (defined(mips) && !defined(BSD))
  333: #  define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31))
  334: # endif
  335: 
  336: 
  337: # if !defined (KERNEL_FILE) && defined (sequent)
  338: #  define KERNEL_FILE "/dynix"
  339: # endif
  340: 
  341: # if !defined (KERNEL_FILE) && defined (hpux)
  342: #  define KERNEL_FILE "/hp-ux"
  343: # endif
  344: 
  345: # if !defined(KERNEL_FILE) && (defined(_SEQUENT_) || defined(MIPS) || defined(SVR4) || defined(ISC) || defined (sgi) || (defined (ardent) && defined (titan)))
  346: #  define KERNEL_FILE "/unix"
  347: # endif
  348: 
  349: 
  350: # if !defined (LDAV_SYMBOL) && defined (alliant)
  351: #  define LDAV_SYMBOL "_Loadavg"
  352: # endif
  353: 
  354: # if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX))
  355: #  define LDAV_SYMBOL "avenrun"
  356: # endif
  357: 
  358: # ifdef HAVE_UNISTD_H
  359: #  include <unistd.h>
  360: # endif
  361: 
  362: # include <stdio.h>
  363: 
  364: /* LOAD_AVE_TYPE should only get defined if we're going to use the
  365:    nlist method.  */
  366: # if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL))
  367: #  define LOAD_AVE_TYPE double
  368: # endif
  369: 
  370: # ifdef LOAD_AVE_TYPE
  371: 
  372: #  ifndef VMS
  373: #   ifndef __linux__
  374: #    ifndef NLIST_STRUCT
  375: #     include <a.out.h>
  376: #    else /* NLIST_STRUCT */
  377: #     include <nlist.h>
  378: #    endif /* NLIST_STRUCT */
  379: 
  380: #    ifdef SUNOS_5
  381: #     include <fcntl.h>
  382: #     include <kvm.h>
  383: #     include <kstat.h>
  384: #    endif
  385: 
  386: #    if defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
  387: #     include <sys/pstat.h>
  388: #    endif
  389: 
  390: #    ifndef KERNEL_FILE
  391: #     define KERNEL_FILE "/vmunix"
  392: #    endif /* KERNEL_FILE */
  393: 
  394: #    ifndef LDAV_SYMBOL
  395: #     define LDAV_SYMBOL "_avenrun"
  396: #    endif /* LDAV_SYMBOL */
  397: #   endif /* __linux__ */
  398: 
  399: #  else /* VMS */
  400: 
  401: #   ifndef eunice
  402: #    include <iodef.h>
  403: #    include <descrip.h>
  404: #   else /* eunice */
  405: #    include <vms/iodef.h>
  406: #   endif /* eunice */
  407: #  endif /* VMS */
  408: 
  409: #  ifndef LDAV_CVT
  410: #   define LDAV_CVT(n) ((double) (n))
  411: #  endif /* !LDAV_CVT */
  412: 
  413: # endif /* LOAD_AVE_TYPE */
  414: 
  415: # if defined(__GNU__) && !defined (NeXT)
  416: /* Note that NeXT Openstep defines __GNU__ even though it should not.  */
  417: /* GNU system acts much like NeXT, for load average purposes,
  418:    but not exactly.  */
  419: #  define NeXT
  420: #  define host_self mach_host_self
  421: # endif
  422: 
  423: # ifdef NeXT
  424: #  ifdef HAVE_MACH_MACH_H
  425: #   include <mach/mach.h>
  426: #  else
  427: #   include <mach.h>
  428: #  endif
  429: # endif /* NeXT */
  430: 
  431: # ifdef sgi
  432: #  include <sys/sysmp.h>
  433: # endif /* sgi */
  434: 
  435: # ifdef UMAX
  436: #  include <stdio.h>
  437: #  include <signal.h>
  438: #  include <sys/time.h>
  439: #  include <sys/wait.h>
  440: #  include <sys/syscall.h>
  441: 
  442: #  ifdef UMAX_43
  443: #   include <machine/cpu.h>
  444: #   include <inq_stats/statistics.h>
  445: #   include <inq_stats/sysstats.h>
  446: #   include <inq_stats/cpustats.h>
  447: #   include <inq_stats/procstats.h>
  448: #  else /* Not UMAX_43.  */
  449: #   include <sys/sysdefs.h>
  450: #   include <sys/statistics.h>
  451: #   include <sys/sysstats.h>
  452: #   include <sys/cpudefs.h>
  453: #   include <sys/cpustats.h>
  454: #   include <sys/procstats.h>
  455: #  endif /* Not UMAX_43.  */
  456: # endif /* UMAX */
  457: 
  458: # ifdef DGUX
  459: #  include <sys/dg_sys_info.h>
  460: # endif
  461: 
  462: # if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION)
  463: #  include <fcntl.h>
  464: # else
  465: #  include <sys/file.h>
  466: # endif
  467: ^L
  468: /* Avoid static vars inside a function since in HPUX they dump as pure.  */
  469: 
  470: # ifdef NeXT
  471: static processor_set_t default_set;
  472: static int getloadavg_initialized;
  473: # endif /* NeXT */
  474: 
  475: # ifdef UMAX
  476: static unsigned int cpus = 0;
  477: static unsigned int samples;
  478: # endif /* UMAX */
  479: 
  480: # ifdef DGUX
  481: static struct dg_sys_info_load_info load_info;  /* what-a-mouthful! */
  482: # endif /* DGUX */
  483: 
  484: #if !defined(HAVE_LIBKSTAT) && defined(LOAD_AVE_TYPE)
  485: /* File descriptor open to /dev/kmem or VMS load ave driver.  */
  486: static int channel;
  487: /* Nonzero iff channel is valid.  */
  488: static int getloadavg_initialized;
  489: /* Offset in kmem to seek to read load average, or 0 means invalid.  */
  490: static long offset;
  491: 
  492: #  if !defined(VMS) && !defined(sgi) && !defined(__linux__)
  493: static struct nlist nl[2];
  494: #  endif /* Not VMS or sgi */
  495: 
  496: #  ifdef SUNOS_5
  497: static kvm_t *kd;
  498: #  endif /* SUNOS_5 */
  499: 
  500: #endif /* LOAD_AVE_TYPE && !HAVE_LIBKSTAT */
  501: ^L
  502: /* Put the 1 minute, 5 minute and 15 minute load averages
  503:    into the first NELEM elements of LOADAVG.
  504:    Return the number written (never more than 3, but may be less than NELEM),
  505:    or -1 if an error occurred.  */
  506: 
  507: int
  508: getloadavg (loadavg, nelem)
  509:      double loadavg[];
  510:      int nelem;
  511: {
  512:   int elem = 0;                 /* Return value.  */
  513: 
  514: # ifdef NO_GET_LOAD_AVG
  515: #  define LDAV_DONE
  516:   /* Set errno to zero to indicate that there was no particular error;
  517:      this function just can't work at all on this system.  */
  518:   errno = 0;
  519:   elem = -1;
  520: # endif
  521: 
  522: # if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT)
  523: /* Use libkstat because we don't have to be root.  */
  524: #  define LDAV_DONE
  525:   kstat_ctl_t *kc;
  526:   kstat_t *ksp;
  527:   kstat_named_t *kn;
  528: 
  529:   kc = <