ccfb6f0d72d623ca3dbe95b386756d415d337fed
[gnulib.git] / lib / getloadavg.c
1 /* Get the system load averages.
2
3    Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994,
4    1995, 1997, 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008 Free Software
5    Foundation, Inc.
6
7    NOTE: The canonical source of this file is maintained with gnulib.
8    Bugs can be reported to bug-gnulib@gnu.org.
9
10    This program is free software: you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
23 /* Compile-time symbols that this file uses:
24
25    HAVE_PSTAT_GETDYNAMIC        Define this if your system has the
26                                 pstat_getdynamic function.  I think it
27                                 is unique to HPUX9.  The best way to get the
28                                 definition is through the AC_FUNC_GETLOADAVG
29                                 macro that comes with autoconf 2.13 or newer.
30                                 If that isn't an option, then just put
31                                 AC_CHECK_FUNCS(pstat_getdynamic) in your
32                                 configure.in file.
33    HAVE_LIBPERFSTAT Define this if your system has the
34                                 perfstat_cpu_total function in libperfstat (AIX).
35    FIXUP_KERNEL_SYMBOL_ADDR()   Adjust address in returned struct nlist.
36    KERNEL_FILE                  Name of the kernel file to nlist.
37    LDAV_CVT()                   Scale the load average from the kernel.
38                                 Returns a double.
39    LDAV_SYMBOL                  Name of kernel symbol giving load average.
40    LOAD_AVE_TYPE                Type of the load average array in the kernel.
41                                 Must be defined unless one of
42                                 apollo, DGUX, NeXT, or UMAX is defined;
43                                 or we have libkstat;
44                                 otherwise, no load average is available.
45    HAVE_NLIST_H                 nlist.h is available.  NLIST_STRUCT defaults
46                                 to this.
47    NLIST_STRUCT                 Include nlist.h, not a.out.h, and
48                                 the nlist n_name element is a pointer,
49                                 not an array.
50    HAVE_STRUCT_NLIST_N_UN_N_NAME `n_un.n_name' is member of `struct nlist'.
51    LINUX_LDAV_FILE              [__linux__, __CYGWIN__]: File containing
52                                 load averages.
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 file system mounted.
74                                 Support from Michael K. Johnson.
75    __CYGWIN__                   Cygwin emulates linux /proc/loadavg.
76    __NetBSD__                   NetBSD: assumes /kern file system mounted.
77
78    In addition, to avoid nesting many #ifdefs, we internally set
79    LDAV_DONE to indicate that the load average has been computed.
80
81    We also #define LDAV_PRIVILEGED if a program will require
82    special installation to be able to call getloadavg.  */
83
84 /* "configure" defines CONFIGURING_GETLOADAVG to sidestep problems
85    with partially-configured source directories.  */
86
87 #ifndef CONFIGURING_GETLOADAVG
88 # include <config.h>
89 # include <stdbool.h>
90 #endif
91
92 /* Specification.  */
93 #include <stdlib.h>
94
95 #include <errno.h>
96 #include <stdio.h>
97
98 /* Exclude all the code except the test program at the end
99    if the system has its own `getloadavg' function.  */
100
101 #ifndef HAVE_GETLOADAVG
102
103 # include <sys/types.h>
104
105 /* Both the Emacs and non-Emacs sections want this.  Some
106    configuration files' definitions for the LOAD_AVE_CVT macro (like
107    sparc.h's) use macros like FSCALE, defined here.  */
108 # if defined (unix) || defined (__unix)
109 #  include <sys/param.h>
110 # endif
111
112 # include "c-strtod.h"
113 # include "cloexec.h"
114 # include "intprops.h"
115 # include "xalloc.h"
116
117 /* The existing Emacs configuration files define a macro called
118    LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and
119    returns the load average multiplied by 100.  What we actually want
120    is a macro called LDAV_CVT, which returns the load average as an
121    unmultiplied double.
122
123    For backwards compatibility, we'll define LDAV_CVT in terms of
124    LOAD_AVE_CVT, but future machine config files should just define
125    LDAV_CVT directly.  */
126
127 # if !defined (LDAV_CVT) && defined (LOAD_AVE_CVT)
128 #  define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0)
129 # endif
130
131 # if !defined (BSD) && defined (ultrix)
132 /* Ultrix behaves like BSD on Vaxen.  */
133 #  define BSD
134 # endif
135
136 # ifdef NeXT
137 /* NeXT in the 2.{0,1,2} releases defines BSD in <sys/param.h>, which
138    conflicts with the definition understood in this file, that this
139    really is BSD. */
140 #  undef BSD
141
142 /* NeXT defines FSCALE in <sys/param.h>.  However, we take FSCALE being
143    defined to mean that the nlist method should be used, which is not true.  */
144 #  undef FSCALE
145 # endif
146
147 /* Same issues as for NeXT apply to the HURD-based GNU system.  */
148 # ifdef __GNU__
149 #  undef BSD
150 #  undef FSCALE
151 # endif /* __GNU__ */
152
153 /* Set values that are different from the defaults, which are
154    set a little farther down with #ifndef.  */
155
156
157 /* Some shorthands.  */
158
159 # if defined (HPUX) && !defined (hpux)
160 #  define hpux
161 # endif
162
163 # if defined (__hpux) && !defined (hpux)
164 #  define hpux
165 # endif
166
167 # if defined (__sun) && !defined (sun)
168 #  define sun
169 # endif
170
171 # if defined (hp300) && !defined (hpux)
172 #  define MORE_BSD
173 # endif
174
175 # if defined (ultrix) && defined (mips)
176 #  define decstation
177 # endif
178
179 # if defined (__SVR4) && !defined (SVR4)
180 #  define SVR4
181 # endif
182
183 # if (defined (sun) && defined (SVR4)) || defined (SOLARIS2)
184 #  define SUNOS_5
185 # endif
186
187 # if defined (__osf__) && (defined (__alpha) || defined (__alpha__))
188 #  define OSF_ALPHA
189 #  include <sys/mbuf.h>
190 #  include <sys/socket.h>
191 #  include <net/route.h>
192 #  include <sys/table.h>
193 /* Tru64 4.0D's table.h redefines sys */
194 #  undef sys
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 #  if defined _AIX && ! defined HAVE_LIBPERFSTAT
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 #  if defined _AIX && !defined HAVE_LIBPERFSTAT
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) && !defined(HAVE_LIBPERFSTAT)))
355 #  define LDAV_SYMBOL "avenrun"
356 # endif
357
358 # include <unistd.h>
359
360 /* LOAD_AVE_TYPE should only get defined if we're going to use the
361    nlist method.  */
362 # if !defined (LOAD_AVE_TYPE) && (defined (BSD) || defined (LDAV_CVT) || defined (KERNEL_FILE) || defined (LDAV_SYMBOL))
363 #  define LOAD_AVE_TYPE double
364 # endif
365
366 # ifdef LOAD_AVE_TYPE
367
368 #  ifndef __VMS
369 #   ifndef __linux__
370 #    ifndef NLIST_STRUCT
371 #     include <a.out.h>
372 #    else /* NLIST_STRUCT */
373 #     include <nlist.h>
374 #    endif /* NLIST_STRUCT */
375
376 #    ifdef SUNOS_5
377 #     include <fcntl.h>
378 #     include <kvm.h>
379 #     include <kstat.h>
380 #    endif
381
382 #    if defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
383 #     include <sys/pstat.h>
384 #    endif
385
386 #    ifndef KERNEL_FILE
387 #     define KERNEL_FILE "/vmunix"
388 #    endif /* KERNEL_FILE */
389
390 #    ifndef LDAV_SYMBOL
391 #     define LDAV_SYMBOL "_avenrun"
392 #    endif /* LDAV_SYMBOL */
393 #   endif /* __linux__ */
394
395 #  else /* __VMS */
396
397 #   ifndef eunice
398 #    include <iodef.h>
399 #    include <descrip.h>
400 #   else /* eunice */
401 #    include <vms/iodef.h>
402 #   endif /* eunice */
403 #  endif /* __VMS */
404
405 #  ifndef LDAV_CVT
406 #   define LDAV_CVT(n) ((double) (n))
407 #  endif /* !LDAV_CVT */
408
409 # endif /* LOAD_AVE_TYPE */
410
411 # if defined HAVE_LIBPERFSTAT
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 = c_strtod (ptr, &endptr);
624       if (ptr == endptr)
625         {
626           if (elem == 0)
627             return -1;
628           break;
629         }
630       loadavg[elem] = d;
631       ptr = endptr;
632     }
633
634   return elem;
635
636 # endif /* __linux__ || __CYGWIN__ */
637
638 # if !defined (LDAV_DONE) && defined (__NetBSD__)
639 #  define LDAV_DONE
640 #  undef LOAD_AVE_TYPE
641
642 #  ifndef NETBSD_LDAV_FILE
643 #   define NETBSD_LDAV_FILE "/kern/loadavg"
644 #  endif
645
646   unsigned long int load_ave[3], scale;
647   int count;
648   FILE *fp;
649
650   fp = fopen (NETBSD_LDAV_FILE, "r");
651   if (fp == NULL)
652     return -1;
653   count = fscanf (fp, "%lu %lu %lu %lu\n",
654                   &load_ave[0], &load_ave[1], &load_ave[2],
655                   &scale);
656   (void) fclose (fp);
657   if (count != 4)
658     return -1;
659
660   for (elem = 0; elem < nelem; elem++)
661     loadavg[elem] = (double) load_ave[elem] / (double) scale;
662
663   return elem;
664
665 # endif /* __NetBSD__ */
666
667 # if !defined (LDAV_DONE) && defined (NeXT)
668 #  define LDAV_DONE
669   /* The NeXT code was adapted from iscreen 3.2.  */
670
671   host_t host;
672   struct processor_set_basic_info info;
673   unsigned int info_count;
674
675   /* We only know how to get the 1-minute average for this system,
676      so even if the caller asks for more than 1, we only return 1.  */
677
678   if (!getloadavg_initialized)
679     {
680       if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
681         getloadavg_initialized = true;
682     }
683
684   if (getloadavg_initialized)
685     {
686       info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
687       if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
688                               (processor_set_info_t) &info, &info_count)
689           != KERN_SUCCESS)
690         getloadavg_initialized = false;
691       else
692         {
693           if (nelem > 0)
694             loadavg[elem++] = (double) info.load_average / LOAD_SCALE;
695         }
696     }
697
698   if (!getloadavg_initialized)
699     return -1;
700 # endif /* NeXT */
701
702 # if !defined (LDAV_DONE) && defined (UMAX)
703 #  define LDAV_DONE
704 /* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
705    have a /dev/kmem.  Information about the workings of the running kernel
706    can be gathered with inq_stats system calls.
707    We only know how to get the 1-minute average for this system.  */
708
709   struct proc_summary proc_sum_data;
710   struct stat_descr proc_info;
711   double load;
712   register unsigned int i, j;
713
714   if (cpus == 0)
715     {
716       register unsigned int c, i;
717       struct cpu_config conf;
718       struct stat_descr desc;
719
720       desc.sd_next = 0;
721       desc.sd_subsys = SUBSYS_CPU;
722       desc.sd_type = CPUTYPE_CONFIG;
723       desc.sd_addr = (char *) &conf;
724       desc.sd_size = sizeof conf;
725
726       if (inq_stats (1, &desc))
727         return -1;
728
729       c = 0;
730       for (i = 0; i < conf.config_maxclass; ++i)
731         {
732           struct class_stats stats;
733           bzero ((char *) &stats, sizeof stats);
734
735           desc.sd_type = CPUTYPE_CLASS;
736           desc.sd_objid = i;
737           desc.sd_addr = (char *) &stats;
738           desc.sd_size = sizeof stats;
739
740           if (inq_stats (1, &desc))
741             return -1;
742
743           c += stats.class_numcpus;
744         }
745       cpus = c;
746       samples = cpus < 2 ? 3 : (2 * cpus / 3);
747     }
748
749   proc_info.sd_next = 0;
750   proc_info.sd_subsys = SUBSYS_PROC;
751   proc_info.sd_type = PROCTYPE_SUMMARY;
752   proc_info.sd_addr = (char *) &proc_sum_data;
753   proc_info.sd_size = sizeof (struct proc_summary);
754   proc_info.sd_sizeused = 0;
755
756   if (inq_stats (1, &proc_info) != 0)
757     return -1;
758
759   load = proc_sum_data.ps_nrunnable;
760   j = 0;
761   for (i = samples - 1; i > 0; --i)
762     {
763       load += proc_sum_data.ps_nrun[j];
764       if (j++ == PS_NRUNSIZE)
765         j = 0;
766     }
767
768   if (nelem > 0)
769     loadavg[elem++] = load / samples / cpus;
770 # endif /* UMAX */
771
772 # if !defined (LDAV_DONE) && defined (DGUX)
773 #  define LDAV_DONE
774   /* This call can return -1 for an error, but with good args
775      it's not supposed to fail.  The first argument is for no
776      apparent reason of type `long int *'.  */
777   dg_sys_info ((long int *) &load_info,
778                DG_SYS_INFO_LOAD_INFO_TYPE,
779                DG_SYS_INFO_LOAD_VERSION_0);
780
781   if (nelem > 0)
782     loadavg[elem++] = load_info.one_minute;
783   if (nelem > 1)
784     loadavg[elem++] = load_info.five_minute;
785   if (nelem > 2)
786     loadavg[elem++] = load_info.fifteen_minute;
787 # endif /* DGUX */
788
789 # if !defined (LDAV_DONE) && defined (apollo)
790 #  define LDAV_DONE
791 /* Apollo code from lisch@mentorg.com (Ray Lischner).
792
793    This system call is not documented.  The load average is obtained as
794    three long integers, for the load average over the past minute,
795    five minutes, and fifteen minutes.  Each value is a scaled integer,
796    with 16 bits of integer part and 16 bits of fraction part.
797
798    I'm not sure which operating system first supported this system call,
799    but I know that SR10.2 supports it.  */
800
801   extern void proc1_$get_loadav ();
802   unsigned long load_ave[3];
803
804   proc1_$get_loadav (load_ave);
805
806   if (nelem > 0)
807     loadavg[elem++] = load_ave[0] / 65536.0;
808   if (nelem > 1)
809     loadavg[elem++] = load_ave[1] / 65536.0;
810   if (nelem > 2)
811     loadavg[elem++] = load_ave[2] / 65536.0;
812 # endif /* apollo */
813
814 # if !defined (LDAV_DONE) && defined (OSF_MIPS)
815 #  define LDAV_DONE
816
817   struct tbl_loadavg load_ave;
818   table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
819   loadavg[elem++]
820     = (load_ave.tl_lscale == 0
821        ? load_ave.tl_avenrun.d[0]
822        : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
823 # endif /* OSF_MIPS */
824
825 # if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32))
826 #  define LDAV_DONE
827
828   /* A faithful emulation is going to have to be saved for a rainy day.  */
829   for ( ; elem < nelem; elem++)
830     {
831       loadavg[elem] = 0.0;
832     }
833 # endif  /* __MSDOS__ || WINDOWS32 */
834
835 # if !defined (LDAV_DONE) && defined (OSF_ALPHA)
836 #  define LDAV_DONE
837
838   struct tbl_loadavg load_ave;
839   table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
840   for (elem = 0; elem < nelem; elem++)
841     loadavg[elem]
842       = (load_ave.tl_lscale == 0
843          ? load_ave.tl_avenrun.d[elem]
844          : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
845 # endif /* OSF_ALPHA */
846
847 # if ! defined LDAV_DONE && defined __VMS
848   /* VMS specific code -- read from the Load Ave driver.  */
849
850   LOAD_AVE_TYPE load_ave[3];
851   static bool getloadavg_initialized;
852 #  ifdef eunice
853   struct
854   {
855     int dsc$w_length;
856     char *dsc$a_pointer;
857   } descriptor;
858 #  endif
859
860   /* Ensure that there is a channel open to the load ave device.  */
861   if (!getloadavg_initialized)
862     {
863       /* Attempt to open the channel.  */
864 #  ifdef eunice
865       descriptor.dsc$w_length = 18;
866       descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE";
867 #  else
868       $DESCRIPTOR (descriptor, "LAV0:");
869 #  endif
870       if (sys$assign (&descriptor, &channel, 0, 0) & 1)
871         getloadavg_initialized = true;
872     }
873
874   /* Read the load average vector.  */
875   if (getloadavg_initialized
876       && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0,
877                      load_ave, 12, 0, 0, 0, 0) & 1))
878     {
879       sys$dassgn (channel);
880       getloadavg_initialized = false;
881     }
882
883   if (!getloadavg_initialized)
884     return -1;
885 # endif /* ! defined LDAV_DONE && defined __VMS */
886
887 # if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS
888
889   /* UNIX-specific code -- read the average from /dev/kmem.  */
890
891 #  define LDAV_PRIVILEGED               /* This code requires special installation.  */
892
893   LOAD_AVE_TYPE load_ave[3];
894
895   /* Get the address of LDAV_SYMBOL.  */
896   if (offset == 0)
897     {
898 #  ifndef sgi
899 #   ifndef NLIST_STRUCT
900       strcpy (nl[0].n_name, LDAV_SYMBOL);
901       strcpy (nl[1].n_name, "");
902 #   else /* NLIST_STRUCT */
903 #    ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
904       nl[0].n_un.n_name = LDAV_SYMBOL;
905       nl[1].n_un.n_name = 0;
906 #    else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
907       nl[0].n_name = LDAV_SYMBOL;
908       nl[1].n_name = 0;
909 #    endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
910 #   endif /* NLIST_STRUCT */
911
912 #   ifndef SUNOS_5
913       if (
914 #    if !(defined (_AIX) && !defined (ps2))
915           nlist (KERNEL_FILE, nl)
916 #    else  /* _AIX */
917           knlist (nl, 1, sizeof (nl[0]))
918 #    endif
919           >= 0)
920           /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i.  */
921           {
922 #    ifdef FIXUP_KERNEL_SYMBOL_ADDR
923             FIXUP_KERNEL_SYMBOL_ADDR (nl);
924 #    endif
925             offset = nl[0].n_value;
926           }
927 #   endif /* !SUNOS_5 */
928 #  else  /* sgi */
929       int ldav_off;
930
931       ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
932       if (ldav_off != -1)
933         offset = (long int) ldav_off & 0x7fffffff;
934 #  endif /* sgi */
935     }
936
937   /* Make sure we have /dev/kmem open.  */
938   if (!getloadavg_initialized)
939     {
940 #  ifndef SUNOS_5
941       channel = open ("/dev/kmem", O_RDONLY);
942       if (channel >= 0)
943         {
944           /* Set the channel to close on exec, so it does not
945              litter any child's descriptor table.  */
946           set_cloexec_flag (channel, true);
947           getloadavg_initialized = true;
948         }
949 #  else /* SUNOS_5 */
950       /* We pass 0 for the kernel, corefile, and swapfile names
951          to use the currently running kernel.  */
952       kd = kvm_open (0, 0, 0, O_RDONLY, 0);
953       if (kd != 0)
954         {
955           /* nlist the currently running kernel.  */
956           kvm_nlist (kd, nl);
957           offset = nl[0].n_value;
958           getloadavg_initialized = true;
959         }
960 #  endif /* SUNOS_5 */
961     }
962
963   /* If we can, get the load average values.  */
964   if (offset && getloadavg_initialized)
965     {
966       /* Try to read the load.  */
967 #  ifndef SUNOS_5
968       if (lseek (channel, offset, 0) == -1L
969           || read (channel, (char *) load_ave, sizeof (load_ave))
970           != sizeof (load_ave))
971         {
972           close (channel);
973           getloadavg_initialized = false;
974         }
975 #  else  /* SUNOS_5 */
976       if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
977           != sizeof (load_ave))
978         {
979           kvm_close (kd);
980           getloadavg_initialized = false;
981         }
982 #  endif /* SUNOS_5 */
983     }
984
985   if (offset == 0 || !getloadavg_initialized)
986     return -1;
987 # endif /* ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS */
988
989 # if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS.  */
990   if (nelem > 0)
991     loadavg[elem++] = LDAV_CVT (load_ave[0]);
992   if (nelem > 1)
993     loadavg[elem++] = LDAV_CVT (load_ave[1]);
994   if (nelem > 2)
995     loadavg[elem++] = LDAV_CVT (load_ave[2]);
996
997 #  define LDAV_DONE
998 # endif /* !LDAV_DONE && LOAD_AVE_TYPE */
999
1000 # if !defined LDAV_DONE
1001   /* Set errno to zero to indicate that there was no particular error;
1002      this function just can't work at all on this system.  */
1003   errno = 0;
1004   elem = -1;
1005 # endif
1006   return elem;
1007 }
1008
1009 #endif /* ! HAVE_GETLOADAVG */
1010 \f
1011 #ifdef TEST
1012 int
1013 main (int argc, char **argv)
1014 {
1015   int naptime = 0;
1016
1017   if (argc > 1)
1018     naptime = atoi (argv[1]);
1019
1020   while (1)
1021     {
1022       double avg[3];
1023       int loads;
1024
1025       errno = 0;                /* Don't be misled if it doesn't set errno.  */
1026       loads = getloadavg (avg, 3);
1027       if (loads == -1)
1028         {
1029           perror ("Error getting load average");
1030           return EXIT_FAILURE;
1031         }
1032       if (loads > 0)
1033         printf ("1-minute: %f  ", avg[0]);
1034       if (loads > 1)
1035         printf ("5-minute: %f  ", avg[1]);
1036       if (loads > 2)
1037         printf ("15-minute: %f  ", avg[2]);
1038       if (loads > 0)
1039         putchar ('\n');
1040
1041       if (naptime == 0)
1042         break;
1043       sleep (naptime);
1044     }
1045
1046   return EXIT_SUCCESS;
1047 }
1048 #endif /* TEST */