update nearly all FSF copyright year lists to include 2010
[gnulib.git] / lib / getloadavg.c
1 /* Get the system load averages.
2
3    Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2010 Free Software
4    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 3 of the License, or
12    (at your option) 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, see <http://www.gnu.org/licenses/>.  */
21
22 /* Compile-time symbols that this file uses:
23
24    HAVE_PSTAT_GETDYNAMIC        Define this if your system has the
25                                 pstat_getdynamic function.  I think it
26                                 is unique to HPUX9.  The best way to get the
27                                 definition is through the AC_FUNC_GETLOADAVG
28                                 macro that comes with autoconf 2.13 or newer.
29                                 If that isn't an option, then just put
30                                 AC_CHECK_FUNCS(pstat_getdynamic) in your
31                                 configure.in file.
32    HAVE_LIBPERFSTAT Define this if your system has the
33                                 perfstat_cpu_total function in libperfstat (AIX).
34    FIXUP_KERNEL_SYMBOL_ADDR()   Adjust address in returned struct nlist.
35    KERNEL_FILE                  Name of the kernel file 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.
47    N_NAME_POINTER               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__, __CYGWIN__]: File containing
51                                 load averages.
52
53    Specific system predefines this file uses, aside from setting
54    default values if not emacs:
55
56    apollo
57    BSD                          Real BSD, not just BSD-like.
58    convex
59    DGUX
60    eunice                       UNIX emulator under VMS.
61    hpux
62    __MSDOS__                    No-op for MSDOS.
63    NeXT
64    sgi
65    sequent                      Sequent Dynix 3.x.x (BSD)
66    _SEQUENT_                    Sequent DYNIX/ptx 1.x.x (SYSV)
67    sony_news                    NEWS-OS (works at least for 4.1C)
68    UMAX
69    UMAX4_3
70    VMS
71    WINDOWS32                    No-op for Windows95/NT.
72    __linux__                    Linux: assumes /proc file system mounted.
73                                 Support from Michael K. Johnson.
74    __CYGWIN__                   Cygwin emulates linux /proc/loadavg.
75    __NetBSD__                   NetBSD: assumes /kern file system 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 /* "configure" defines CONFIGURING_GETLOADAVG to sidestep problems
84    with partially-configured source directories.  */
85
86 #ifndef CONFIGURING_GETLOADAVG
87 # include <config.h>
88 # include <stdbool.h>
89 #endif
90
91 /* Specification.  */
92 #include <stdlib.h>
93
94 #include <errno.h>
95 #include <stdio.h>
96
97 /* Exclude all the code except the test program at the end
98    if the system has its own `getloadavg' function.  */
99
100 #ifndef HAVE_GETLOADAVG
101
102 # include <sys/types.h>
103
104 /* Both the Emacs and non-Emacs sections want this.  Some
105    configuration files' definitions for the LOAD_AVE_CVT macro (like
106    sparc.h's) use macros like FSCALE, defined here.  */
107 # if defined (unix) || defined (__unix)
108 #  include <sys/param.h>
109 # endif
110
111 # include "c-strtod.h"
112 # include "cloexec.h"
113 # include "intprops.h"
114 # include "xalloc.h"
115
116 /* The existing Emacs configuration files define a macro called
117    LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and
118    returns the load average multiplied by 100.  What we actually want
119    is a macro called LDAV_CVT, which returns the load average as an
120    unmultiplied double.
121
122    For backwards compatibility, we'll define LDAV_CVT in terms of
123    LOAD_AVE_CVT, but future machine config files should just define
124    LDAV_CVT directly.  */
125
126 # if !defined (LDAV_CVT) && defined (LOAD_AVE_CVT)
127 #  define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0)
128 # endif
129
130 # if !defined (BSD) && defined (ultrix)
131 /* Ultrix behaves like BSD on Vaxen.  */
132 #  define BSD
133 # endif
134
135 # ifdef NeXT
136 /* NeXT in the 2.{0,1,2} releases defines BSD in <sys/param.h>, which
137    conflicts with the definition understood in this file, that this
138    really is BSD. */
139 #  undef BSD
140
141 /* NeXT defines FSCALE in <sys/param.h>.  However, we take FSCALE being
142    defined to mean that the nlist method should be used, which is not true.  */
143 #  undef FSCALE
144 # endif
145
146 /* Same issues as for NeXT apply to the HURD-based GNU system.  */
147 # ifdef __GNU__
148 #  undef BSD
149 #  undef FSCALE
150 # endif /* __GNU__ */
151
152 /* Set values that are different from the defaults, which are
153    set a little farther down with #ifndef.  */
154
155
156 /* Some shorthands.  */
157
158 # if defined (HPUX) && !defined (hpux)
159 #  define hpux
160 # endif
161
162 # if defined (__hpux) && !defined (hpux)
163 #  define hpux
164 # endif
165
166 # if defined (__sun) && !defined (sun)
167 #  define sun
168 # endif
169
170 # if defined (hp300) && !defined (hpux)
171 #  define MORE_BSD
172 # endif
173
174 # if defined (ultrix) && defined (mips)
175 #  define decstation
176 # endif
177
178 # if defined (__SVR4) && !defined (SVR4)
179 #  define SVR4
180 # endif
181
182 # if (defined (sun) && defined (SVR4)) || defined (SOLARIS2)
183 #  define SUNOS_5
184 # endif
185
186 # if defined (__osf__) && (defined (__alpha) || defined (__alpha__))
187 #  define OSF_ALPHA
188 #  include <sys/mbuf.h>
189 #  include <sys/socket.h>
190 #  include <net/route.h>
191 #  include <sys/table.h>
192 /* Tru64 4.0D's table.h redefines sys */
193 #  undef sys
194 # endif
195
196 # if defined (__osf__) && (defined (mips) || defined (__mips__))
197 #  define OSF_MIPS
198 #  include <sys/table.h>
199 # endif
200
201 /* UTek's /bin/cc on the 4300 has no architecture specific cpp define by
202    default, but _MACH_IND_SYS_TYPES is defined in <sys/types.h>.  Combine
203    that with a couple of other things and we'll have a unique match.  */
204 # if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES)
205 #  define tek4300                       /* Define by emacs, but not by other users.  */
206 # endif
207
208
209 /* VAX C can't handle multi-line #ifs, or lines longer than 256 chars.  */
210 # ifndef LOAD_AVE_TYPE
211
212 #  ifdef MORE_BSD
213 #   define LOAD_AVE_TYPE long
214 #  endif
215
216 #  ifdef sun
217 #   define LOAD_AVE_TYPE long
218 #  endif
219
220 #  ifdef decstation
221 #   define LOAD_AVE_TYPE long
222 #  endif
223
224 #  ifdef _SEQUENT_
225 #   define LOAD_AVE_TYPE long
226 #  endif
227
228 #  ifdef sgi
229 #   define LOAD_AVE_TYPE long
230 #  endif
231
232 #  ifdef SVR4
233 #   define LOAD_AVE_TYPE long
234 #  endif
235
236 #  ifdef sony_news
237 #   define LOAD_AVE_TYPE long
238 #  endif
239
240 #  ifdef sequent
241 #   define LOAD_AVE_TYPE long
242 #  endif
243
244 #  ifdef OSF_ALPHA
245 #   define LOAD_AVE_TYPE long
246 #  endif
247
248 #  if defined (ardent) && defined (titan)
249 #   define LOAD_AVE_TYPE long
250 #  endif
251
252 #  ifdef tek4300
253 #   define LOAD_AVE_TYPE long
254 #  endif
255
256 #  if defined (alliant) && defined (i860) /* Alliant FX/2800 */
257 #   define LOAD_AVE_TYPE long
258 #  endif
259
260 #  if defined _AIX && ! defined HAVE_LIBPERFSTAT
261 #   define LOAD_AVE_TYPE long
262 #  endif
263
264 #  ifdef convex
265 #   define LOAD_AVE_TYPE double
266 #   ifndef LDAV_CVT
267 #    define LDAV_CVT(n) (n)
268 #   endif
269 #  endif
270
271 # endif /* No LOAD_AVE_TYPE.  */
272
273 # ifdef OSF_ALPHA
274 /* <sys/param.h> defines an incorrect value for FSCALE on Alpha OSF/1,
275    according to ghazi@noc.rutgers.edu.  */
276 #  undef FSCALE
277 #  define FSCALE 1024.0
278 # endif
279
280 # if defined (alliant) && defined (i860) /* Alliant FX/2800 */
281 /* <sys/param.h> defines an incorrect value for FSCALE on an
282    Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu.  */
283 #  undef FSCALE
284 #  define FSCALE 100.0
285 # endif
286
287
288 # ifndef FSCALE
289
290 /* SunOS and some others define FSCALE in sys/param.h.  */
291
292 #  ifdef MORE_BSD
293 #   define FSCALE 2048.0
294 #  endif
295
296 #  if defined (MIPS) || defined (SVR4) || defined (decstation)
297 #   define FSCALE 256
298 #  endif
299
300 #  if defined (sgi) || defined (sequent)
301 /* Sometimes both MIPS and sgi are defined, so FSCALE was just defined
302    above under #ifdef MIPS.  But we want the sgi value.  */
303 #   undef FSCALE
304 #   define FSCALE 1000.0
305 #  endif
306
307 #  if defined (ardent) && defined (titan)
308 #   define FSCALE 65536.0
309 #  endif
310
311 #  ifdef tek4300
312 #   define FSCALE 100.0
313 #  endif
314
315 #  if defined _AIX && !defined HAVE_LIBPERFSTAT
316 #   define FSCALE 65536.0
317 #  endif
318
319 # endif /* Not FSCALE.  */
320
321 # if !defined (LDAV_CVT) && defined (FSCALE)
322 #  define LDAV_CVT(n) (((double) (n)) / FSCALE)
323 # endif
324
325 # ifndef NLIST_STRUCT
326 #  if HAVE_NLIST_H
327 #   define NLIST_STRUCT
328 #  endif
329 # endif
330
331 # if defined (sgi) || (defined (mips) && !defined (BSD))
332 #  define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31))
333 # endif
334
335
336 # if !defined (KERNEL_FILE) && defined (sequent)
337 #  define KERNEL_FILE "/dynix"
338 # endif
339
340 # if !defined (KERNEL_FILE) && defined (hpux)
341 #  define KERNEL_FILE "/hp-ux"
342 # endif
343
344 # if !defined (KERNEL_FILE) && (defined (_SEQUENT_) || defined (MIPS) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan)))
345 #  define KERNEL_FILE "/unix"
346 # endif
347
348
349 # if !defined (LDAV_SYMBOL) && defined (alliant)
350 #  define LDAV_SYMBOL "_Loadavg"
351 # endif
352
353 # if !defined (LDAV_SYMBOL) && ((defined (hpux) && !defined (hp9000s300)) || defined (_SEQUENT_) || defined (SVR4) || defined (ISC) || defined (sgi) || (defined (ardent) && defined (titan)) || (defined (_AIX) && !defined(HAVE_LIBPERFSTAT)))
354 #  define LDAV_SYMBOL "avenrun"
355 # endif
356
357 # include <unistd.h>
358
359 /* LOAD_AVE_TYPE should only get defined if we're going to use the
360    nlist method.  */
361 # if !defined (LOAD_AVE_TYPE) && (defined (BSD) || defined (LDAV_CVT) || defined (KERNEL_FILE) || defined (LDAV_SYMBOL))
362 #  define LOAD_AVE_TYPE double
363 # endif
364
365 # ifdef LOAD_AVE_TYPE
366
367 #  ifndef __VMS
368 #   ifndef __linux__
369 #    ifndef NLIST_STRUCT
370 #     include <a.out.h>
371 #    else /* NLIST_STRUCT */
372 #     include <nlist.h>
373 #    endif /* NLIST_STRUCT */
374
375 #    ifdef SUNOS_5
376 #     include <fcntl.h>
377 #     include <kvm.h>
378 #     include <kstat.h>
379 #    endif
380
381 #    if defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
382 #     include <sys/pstat.h>
383 #    endif
384
385 #    ifndef KERNEL_FILE
386 #     define KERNEL_FILE "/vmunix"
387 #    endif /* KERNEL_FILE */
388
389 #    ifndef LDAV_SYMBOL
390 #     define LDAV_SYMBOL "_avenrun"
391 #    endif /* LDAV_SYMBOL */
392 #   endif /* __linux__ */
393
394 #  else /* __VMS */
395
396 #   ifndef eunice
397 #    include <iodef.h>
398 #    include <descrip.h>
399 #   else /* eunice */
400 #    include <vms/iodef.h>
401 #   endif /* eunice */
402 #  endif /* __VMS */
403
404 #  ifndef LDAV_CVT
405 #   define LDAV_CVT(n) ((double) (n))
406 #  endif /* !LDAV_CVT */
407
408 # endif /* LOAD_AVE_TYPE */
409
410 # if defined HAVE_LIBPERFSTAT
411 #  include <sys/protosw.h>
412 #  include <libperfstat.h>
413 #  include <sys/proc.h>
414 #  ifndef SBITS
415 #   define SBITS 16
416 #  endif
417 # endif
418
419 # if defined (__GNU__) && !defined (NeXT)
420 /* Note that NeXT Openstep defines __GNU__ even though it should not.  */
421 /* GNU system acts much like NeXT, for load average purposes,
422    but not exactly.  */
423 #  define NeXT
424 #  define host_self mach_host_self
425 # endif
426
427 # ifdef NeXT
428 #  ifdef HAVE_MACH_MACH_H
429 #   include <mach/mach.h>
430 #  else
431 #   include <mach.h>
432 #  endif
433 # endif /* NeXT */
434
435 # ifdef sgi
436 #  include <sys/sysmp.h>
437 # endif /* sgi */
438
439 # ifdef UMAX
440 #  include <signal.h>
441 #  include <sys/time.h>
442 #  include <sys/wait.h>
443 #  include <sys/syscall.h>
444
445 #  ifdef UMAX_43
446 #   include <machine/cpu.h>
447 #   include <inq_stats/statistics.h>
448 #   include <inq_stats/sysstats.h>
449 #   include <inq_stats/cpustats.h>
450 #   include <inq_stats/procstats.h>
451 #  else /* Not UMAX_43.  */
452 #   include <sys/sysdefs.h>
453 #   include <sys/statistics.h>
454 #   include <sys/sysstats.h>
455 #   include <sys/cpudefs.h>
456 #   include <sys/cpustats.h>
457 #   include <sys/procstats.h>
458 #  endif /* Not UMAX_43.  */
459 # endif /* UMAX */
460
461 # ifdef DGUX
462 #  include <sys/dg_sys_info.h>
463 # endif
464
465 # include "fcntl--.h"
466 \f
467 /* Avoid static vars inside a function since in HPUX they dump as pure.  */
468
469 # ifdef NeXT
470 static processor_set_t default_set;
471 static bool getloadavg_initialized;
472 # endif /* NeXT */
473
474 # ifdef UMAX
475 static unsigned int cpus = 0;
476 static unsigned int samples;
477 # endif /* UMAX */
478
479 # ifdef DGUX
480 static struct dg_sys_info_load_info load_info;  /* what-a-mouthful! */
481 # endif /* DGUX */
482
483 # if !defined (HAVE_LIBKSTAT) && defined (LOAD_AVE_TYPE)
484 /* File descriptor open to /dev/kmem or VMS load ave driver.  */
485 static int channel;
486 /* True iff channel is valid.  */
487 static bool getloadavg_initialized;
488 /* Offset in kmem to seek to read load average, or 0 means invalid.  */
489 static long offset;
490
491 #  if ! defined __VMS && ! defined sgi && ! defined __linux__
492 static struct nlist nl[2];
493 #  endif
494
495 #  ifdef SUNOS_5
496 static kvm_t *kd;
497 #  endif /* SUNOS_5 */
498
499 # endif /* LOAD_AVE_TYPE && !HAVE_LIBKSTAT */
500 \f
501 /* Put the 1 minute, 5 minute and 15 minute load averages
502    into the first NELEM elements of LOADAVG.
503    Return the number written (never more than 3, but may be less than NELEM),
504    or -1 if an error occurred.  */
505
506 int
507 getloadavg (double loadavg[], int nelem)
508 {
509   int elem = 0;                 /* Return value.  */
510
511 # ifdef NO_GET_LOAD_AVG
512 #  define LDAV_DONE
513   /* Set errno to zero to indicate that there was no particular error;
514      this function just can't work at all on this system.  */
515   errno = 0;
516   elem = -1;
517 # endif
518
519 # if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT)
520 /* Use libkstat because we don't have to be root.  */
521 #  define LDAV_DONE
522   kstat_ctl_t *kc;
523   kstat_t *ksp;
524   kstat_named_t *kn;
525
526   kc = kstat_open ();
527   if (kc == 0)
528     return -1;
529   ksp = kstat_lookup (kc, "unix", 0, "system_misc");
530   if (ksp == 0)
531     return -1;
532   if (kstat_read (kc, ksp, 0) == -1)
533     return -1;
534
535
536   kn = kstat_data_lookup (ksp, "avenrun_1min");
537   if (kn == 0)
538     {
539       /* Return -1 if no load average information is available.  */
540       nelem = 0;
541       elem = -1;
542     }
543
544   if (nelem >= 1)
545     loadavg[elem++] = (double) kn->value.ul / FSCALE;
546
547   if (nelem >= 2)
548     {
549       kn = kstat_data_lookup (ksp, "avenrun_5min");
550       if (kn != 0)
551         {
552           loadavg[elem++] = (double) kn->value.ul / FSCALE;
553
554           if (nelem >= 3)
555             {
556               kn = kstat_data_lookup (ksp, "avenrun_15min");
557               if (kn != 0)
558                 loadavg[elem++] = (double) kn->value.ul / FSCALE;
559             }
560         }
561     }
562
563   kstat_close (kc);
564 # endif /* HAVE_LIBKSTAT */
565
566 # if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
567 /* Use pstat_getdynamic() because we don't have to be root.  */
568 #  define LDAV_DONE
569 #  undef LOAD_AVE_TYPE
570
571   struct pst_dynamic dyn_info;
572   if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0)
573     return -1;
574   if (nelem > 0)
575     loadavg[elem++] = dyn_info.psd_avg_1_min;
576   if (nelem > 1)
577     loadavg[elem++] = dyn_info.psd_avg_5_min;
578   if (nelem > 2)
579     loadavg[elem++] = dyn_info.psd_avg_15_min;
580
581 # endif /* hpux && HAVE_PSTAT_GETDYNAMIC */
582
583 # if ! defined LDAV_DONE && defined HAVE_LIBPERFSTAT
584 #  define LDAV_DONE
585 #  undef LOAD_AVE_TYPE
586 /* Use perfstat_cpu_total because we don't have to be root. */
587   {
588     perfstat_cpu_total_t cpu_stats;
589     int result = perfstat_cpu_total (NULL, &cpu_stats, sizeof cpu_stats, 1);
590     if (result == -1)
591       return result;
592     loadavg[0] = cpu_stats.loadavg[0] / (double)(1 << SBITS);
593     loadavg[1] = cpu_stats.loadavg[1] / (double)(1 << SBITS);
594     loadavg[2] = cpu_stats.loadavg[2] / (double)(1 << SBITS);
595     elem = 3;
596   }
597 # endif
598
599 # if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__))
600 #  define LDAV_DONE
601 #  undef LOAD_AVE_TYPE
602
603 #  ifndef LINUX_LDAV_FILE
604 #   define LINUX_LDAV_FILE "/proc/loadavg"
605 #  endif
606
607   char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")];
608   char const *ptr = ldavgbuf;
609   int fd, count;
610
611   fd = open (LINUX_LDAV_FILE, O_RDONLY);
612   if (fd == -1)
613     return -1;
614   count = read (fd, ldavgbuf, sizeof ldavgbuf - 1);
615   (void) close (fd);
616   if (count <= 0)
617     return -1;
618   ldavgbuf[count] = '\0';
619
620   for (elem = 0; elem < nelem; elem++)
621     {
622       char *endptr;
623       double d;
624
625       errno = 0;
626       d = c_strtod (ptr, &endptr);
627       if (ptr == endptr || (d == 0 && errno != 0))
628         {
629           if (elem == 0)
630             return -1;
631           break;
632         }
633       loadavg[elem] = d;
634       ptr = endptr;
635     }
636
637   return elem;
638
639 # endif /* __linux__ || __CYGWIN__ */
640
641 # if !defined (LDAV_DONE) && defined (__NetBSD__)
642 #  define LDAV_DONE
643 #  undef LOAD_AVE_TYPE
644
645 #  ifndef NETBSD_LDAV_FILE
646 #   define NETBSD_LDAV_FILE "/kern/loadavg"
647 #  endif
648
649   unsigned long int load_ave[3], scale;
650   int count;
651   FILE *fp;
652
653   fp = fopen (NETBSD_LDAV_FILE, "r");
654   if (fp == NULL)
655     return -1;
656   count = fscanf (fp, "%lu %lu %lu %lu\n",
657                   &load_ave[0], &load_ave[1], &load_ave[2],
658                   &scale);
659   (void) fclose (fp);
660   if (count != 4)
661     return -1;
662
663   for (elem = 0; elem < nelem; elem++)
664     loadavg[elem] = (double) load_ave[elem] / (double) scale;
665
666   return elem;
667
668 # endif /* __NetBSD__ */
669
670 # if !defined (LDAV_DONE) && defined (NeXT)
671 #  define LDAV_DONE
672   /* The NeXT code was adapted from iscreen 3.2.  */
673
674   host_t host;
675   struct processor_set_basic_info info;
676   unsigned int info_count;
677
678   /* We only know how to get the 1-minute average for this system,
679      so even if the caller asks for more than 1, we only return 1.  */
680
681   if (!getloadavg_initialized)
682     {
683       if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
684         getloadavg_initialized = true;
685     }
686
687   if (getloadavg_initialized)
688     {
689       info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
690       if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
691                               (processor_set_info_t) &info, &info_count)
692           != KERN_SUCCESS)
693         getloadavg_initialized = false;
694       else
695         {
696           if (nelem > 0)
697             loadavg[elem++] = (double) info.load_average / LOAD_SCALE;
698         }
699     }
700
701   if (!getloadavg_initialized)
702     return -1;
703 # endif /* NeXT */
704
705 # if !defined (LDAV_DONE) && defined (UMAX)
706 #  define LDAV_DONE
707 /* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
708    have a /dev/kmem.  Information about the workings of the running kernel
709    can be gathered with inq_stats system calls.
710    We only know how to get the 1-minute average for this system.  */
711
712   struct proc_summary proc_sum_data;
713   struct stat_descr proc_info;
714   double load;
715   register unsigned int i, j;
716
717   if (cpus == 0)
718     {
719       register unsigned int c, i;
720       struct cpu_config conf;
721       struct stat_descr desc;
722
723       desc.sd_next = 0;
724       desc.sd_subsys = SUBSYS_CPU;
725       desc.sd_type = CPUTYPE_CONFIG;
726       desc.sd_addr = (char *) &conf;
727       desc.sd_size = sizeof conf;
728
729       if (inq_stats (1, &desc))
730         return -1;
731
732       c = 0;
733       for (i = 0; i < conf.config_maxclass; ++i)
734         {
735           struct class_stats stats;
736           bzero ((char *) &stats, sizeof stats);
737
738           desc.sd_type = CPUTYPE_CLASS;
739           desc.sd_objid = i;
740           desc.sd_addr = (char *) &stats;
741           desc.sd_size = sizeof stats;
742
743           if (inq_stats (1, &desc))
744             return -1;
745
746           c += stats.class_numcpus;
747         }
748       cpus = c;
749       samples = cpus < 2 ? 3 : (2 * cpus / 3);
750     }
751
752   proc_info.sd_next = 0;
753   proc_info.sd_subsys = SUBSYS_PROC;
754   proc_info.sd_type = PROCTYPE_SUMMARY;
755   proc_info.sd_addr = (char *) &proc_sum_data;
756   proc_info.sd_size = sizeof (struct proc_summary);
757   proc_info.sd_sizeused = 0;
758
759   if (inq_stats (1, &proc_info) != 0)
760     return -1;
761
762   load = proc_sum_data.ps_nrunnable;
763   j = 0;
764   for (i = samples - 1; i > 0; --i)
765     {
766       load += proc_sum_data.ps_nrun[j];
767       if (j++ == PS_NRUNSIZE)
768         j = 0;
769     }
770
771   if (nelem > 0)
772     loadavg[elem++] = load / samples / cpus;
773 # endif /* UMAX */
774
775 # if !defined (LDAV_DONE) && defined (DGUX)
776 #  define LDAV_DONE
777   /* This call can return -1 for an error, but with good args
778      it's not supposed to fail.  The first argument is for no
779      apparent reason of type `long int *'.  */
780   dg_sys_info ((long int *) &load_info,
781                DG_SYS_INFO_LOAD_INFO_TYPE,
782                DG_SYS_INFO_LOAD_VERSION_0);
783
784   if (nelem > 0)
785     loadavg[elem++] = load_info.one_minute;
786   if (nelem > 1)
787     loadavg[elem++] = load_info.five_minute;
788   if (nelem > 2)
789     loadavg[elem++] = load_info.fifteen_minute;
790 # endif /* DGUX */
791
792 # if !defined (LDAV_DONE) && defined (apollo)
793 #  define LDAV_DONE
794 /* Apollo code from lisch@mentorg.com (Ray Lischner).
795
796    This system call is not documented.  The load average is obtained as
797    three long integers, for the load average over the past minute,
798    five minutes, and fifteen minutes.  Each value is a scaled integer,
799    with 16 bits of integer part and 16 bits of fraction part.
800
801    I'm not sure which operating system first supported this system call,
802    but I know that SR10.2 supports it.  */
803
804   extern void proc1_$get_loadav ();
805   unsigned long load_ave[3];
806
807   proc1_$get_loadav (load_ave);
808
809   if (nelem > 0)
810     loadavg[elem++] = load_ave[0] / 65536.0;
811   if (nelem > 1)
812     loadavg[elem++] = load_ave[1] / 65536.0;
813   if (nelem > 2)
814     loadavg[elem++] = load_ave[2] / 65536.0;
815 # endif /* apollo */
816
817 # if !defined (LDAV_DONE) && defined (OSF_MIPS)
818 #  define LDAV_DONE
819
820   struct tbl_loadavg load_ave;
821   table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
822   loadavg[elem++]
823     = (load_ave.tl_lscale == 0
824        ? load_ave.tl_avenrun.d[0]
825        : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
826 # endif /* OSF_MIPS */
827
828 # if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32))
829 #  define LDAV_DONE
830
831   /* A faithful emulation is going to have to be saved for a rainy day.  */
832   for ( ; elem < nelem; elem++)
833     {
834       loadavg[elem] = 0.0;
835     }
836 # endif  /* __MSDOS__ || WINDOWS32 */
837
838 # if !defined (LDAV_DONE) && defined (OSF_ALPHA)
839 #  define LDAV_DONE
840
841   struct tbl_loadavg load_ave;
842   table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
843   for (elem = 0; elem < nelem; elem++)
844     loadavg[elem]
845       = (load_ave.tl_lscale == 0
846          ? load_ave.tl_avenrun.d[elem]
847          : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
848 # endif /* OSF_ALPHA */
849
850 # if ! defined LDAV_DONE && defined __VMS
851   /* VMS specific code -- read from the Load Ave driver.  */
852
853   LOAD_AVE_TYPE load_ave[3];
854   static bool getloadavg_initialized;
855 #  ifdef eunice
856   struct
857   {
858     int dsc$w_length;
859     char *dsc$a_pointer;
860   } descriptor;
861 #  endif
862
863   /* Ensure that there is a channel open to the load ave device.  */
864   if (!getloadavg_initialized)
865     {
866       /* Attempt to open the channel.  */
867 #  ifdef eunice
868       descriptor.dsc$w_length = 18;
869       descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE";
870 #  else
871       $DESCRIPTOR (descriptor, "LAV0:");
872 #  endif
873       if (sys$assign (&descriptor, &channel, 0, 0) & 1)
874         getloadavg_initialized = true;
875     }
876
877   /* Read the load average vector.  */
878   if (getloadavg_initialized
879       && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0,
880                      load_ave, 12, 0, 0, 0, 0) & 1))
881     {
882       sys$dassgn (channel);
883       getloadavg_initialized = false;
884     }
885
886   if (!getloadavg_initialized)
887     return -1;
888 # endif /* ! defined LDAV_DONE && defined __VMS */
889
890 # if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS
891
892   /* UNIX-specific code -- read the average from /dev/kmem.  */
893
894 #  define LDAV_PRIVILEGED               /* This code requires special installation.  */
895
896   LOAD_AVE_TYPE load_ave[3];
897
898   /* Get the address of LDAV_SYMBOL.  */
899   if (offset == 0)
900     {
901 #  ifndef sgi
902 #   if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER
903       strcpy (nl[0].n_name, LDAV_SYMBOL);
904       strcpy (nl[1].n_name, "");
905 #   else /* NLIST_STRUCT */
906 #    ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
907       nl[0].n_un.n_name = LDAV_SYMBOL;
908       nl[1].n_un.n_name = 0;
909 #    else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
910       nl[0].n_name = LDAV_SYMBOL;
911       nl[1].n_name = 0;
912 #    endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
913 #   endif /* NLIST_STRUCT */
914
915 #   ifndef SUNOS_5
916       if (
917 #    if !(defined (_AIX) && !defined (ps2))
918           nlist (KERNEL_FILE, nl)
919 #    else  /* _AIX */
920           knlist (nl, 1, sizeof (nl[0]))
921 #    endif
922           >= 0)
923           /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i.  */
924           {
925 #    ifdef FIXUP_KERNEL_SYMBOL_ADDR
926             FIXUP_KERNEL_SYMBOL_ADDR (nl);
927 #    endif
928             offset = nl[0].n_value;
929           }
930 #   endif /* !SUNOS_5 */
931 #  else  /* sgi */
932       int ldav_off;
933
934       ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
935       if (ldav_off != -1)
936         offset = (long int) ldav_off & 0x7fffffff;
937 #  endif /* sgi */
938     }
939
940   /* Make sure we have /dev/kmem open.  */
941   if (!getloadavg_initialized)
942     {
943 #  ifndef SUNOS_5
944       channel = open ("/dev/kmem", O_RDONLY);
945       if (channel >= 0)
946         {
947           /* Set the channel to close on exec, so it does not
948              litter any child's descriptor table.  */
949           set_cloexec_flag (channel, true);
950           getloadavg_initialized = true;
951         }
952 #  else /* SUNOS_5 */
953       /* We pass 0 for the kernel, corefile, and swapfile names
954          to use the currently running kernel.  */
955       kd = kvm_open (0, 0, 0, O_RDONLY, 0);
956       if (kd != 0)
957         {
958           /* nlist the currently running kernel.  */
959           kvm_nlist (kd, nl);
960           offset = nl[0].n_value;
961           getloadavg_initialized = true;
962         }
963 #  endif /* SUNOS_5 */
964     }
965
966   /* If we can, get the load average values.  */
967   if (offset && getloadavg_initialized)
968     {
969       /* Try to read the load.  */
970 #  ifndef SUNOS_5
971       if (lseek (channel, offset, 0) == -1L
972           || read (channel, (char *) load_ave, sizeof (load_ave))
973           != sizeof (load_ave))
974         {
975           close (channel);
976           getloadavg_initialized = false;
977         }
978 #  else  /* SUNOS_5 */
979       if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
980           != sizeof (load_ave))
981         {
982           kvm_close (kd);
983           getloadavg_initialized = false;
984         }
985 #  endif /* SUNOS_5 */
986     }
987
988   if (offset == 0 || !getloadavg_initialized)
989     return -1;
990 # endif /* ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS */
991
992 # if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS.  */
993   if (nelem > 0)
994     loadavg[elem++] = LDAV_CVT (load_ave[0]);
995   if (nelem > 1)
996     loadavg[elem++] = LDAV_CVT (load_ave[1]);
997   if (nelem > 2)
998     loadavg[elem++] = LDAV_CVT (load_ave[2]);
999
1000 #  define LDAV_DONE
1001 # endif /* !LDAV_DONE && LOAD_AVE_TYPE */
1002
1003 # if !defined LDAV_DONE
1004   /* Set errno to zero to indicate that there was no particular error;
1005      this function just can't work at all on this system.  */
1006   errno = 0;
1007   elem = -1;
1008 # endif
1009   return elem;
1010 }
1011
1012 #endif /* ! HAVE_GETLOADAVG */
1013 \f
1014 #ifdef TEST
1015 int
1016 main (int argc, char **argv)
1017 {
1018   int naptime = 0;
1019
1020   if (argc > 1)
1021     naptime = atoi (argv[1]);
1022
1023   while (1)
1024     {
1025       double avg[3];
1026       int loads;
1027
1028       errno = 0;                /* Don't be misled if it doesn't set errno.  */
1029       loads = getloadavg (avg, 3);
1030       if (loads == -1)
1031         {
1032           perror ("Error getting load average");
1033           return EXIT_FAILURE;
1034         }
1035       if (loads > 0)
1036         printf ("1-minute: %f  ", avg[0]);
1037       if (loads > 1)
1038         printf ("5-minute: %f  ", avg[1]);
1039       if (loads > 2)
1040         printf ("15-minute: %f  ", avg[2]);
1041       if (loads > 0)
1042         putchar ('\n');
1043
1044       if (naptime == 0)
1045         break;
1046       sleep (naptime);
1047     }
1048
1049   return EXIT_SUCCESS;
1050 }
1051 #endif /* TEST */