comparison src/getloadavg.c @ 48:56c54cf7c5b6 r19-16b90

Import from CVS: tag r19-16b90
author cvs
date Mon, 13 Aug 2007 08:56:04 +0200
parents 0293115a14e9
children 131b0175ea99
comparison
equal deleted inserted replaced
47:11c6df210d7f 48:56c54cf7c5b6
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to 18 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */ 20 Boston, MA 02111-1307, USA. */
21 21
22 /* Synched up with: FSF 19.31. */
23 22
24 /* Compile-time symbols that this file uses: 23 /* Compile-time symbols that this file uses:
25 24
26 FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist. 25 FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist.
27 KERNEL_FILE Pathname of the kernel to nlist. 26 KERNEL_FILE Pathname of the kernel to nlist.
30 LDAV_SYMBOL Name of kernel symbol giving load average. 29 LDAV_SYMBOL Name of kernel symbol giving load average.
31 LOAD_AVE_TYPE Type of the load average array in the kernel. 30 LOAD_AVE_TYPE Type of the load average array in the kernel.
32 Must be defined unless one of 31 Must be defined unless one of
33 apollo, DGUX, NeXT, or UMAX is defined; 32 apollo, DGUX, NeXT, or UMAX is defined;
34 otherwise, no load average is available. 33 otherwise, no load average is available.
35 Does not need to be defined if HPUX is
36 defined and HPUX_PRE_8_0 is not defined.
37 NLIST_STRUCT Include nlist.h, not a.out.h, and 34 NLIST_STRUCT Include nlist.h, not a.out.h, and
38 the nlist n_name element is a pointer, 35 the nlist n_name element is a pointer,
39 not an array. 36 not an array.
40 NLIST_NAME_UNION struct nlist has an n_un member, not n_name. 37 NLIST_NAME_UNION struct nlist has an n_un member, not n_name.
41 LINUX_LDAV_FILE [__linux__]: File containing load averages. 38 LINUX_LDAV_FILE [__linux__]: File containing load averages.
81 sparc.h's) use macros like FSCALE, defined here. */ 78 sparc.h's) use macros like FSCALE, defined here. */
82 #ifdef unix 79 #ifdef unix
83 #include <sys/param.h> 80 #include <sys/param.h>
84 #endif 81 #endif
85 82
86 83 #ifdef XEMACS
87 #ifdef emacs
88 #include "lisp.h" /* for encapsulated open, close, read, write */ 84 #include "lisp.h" /* for encapsulated open, close, read, write */
89 #endif 85 #endif /* XEMACS */
90 86
91 /* Exclude all the code except the test program at the end 87 /* Exclude all the code except the test program at the end
92 if the system has its own `getloadavg' function. 88 if the system has its own `getloadavg' function.
93 89
94 The declaration of `errno' is needed by the test program 90 The declaration of `errno' is needed by the test program
114 110
115 #if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT) 111 #if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT)
116 #define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0) 112 #define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0)
117 #endif 113 #endif
118 114
115 #ifdef XEMACS
116 #if defined (HAVE_KSTAT_H)
117 #include <kstat.h>
118 #endif /* HAVE_KSTAT_H */
119 #endif /* XEMACS */
120
119 #if !defined (BSD) && defined (ultrix) 121 #if !defined (BSD) && defined (ultrix)
120 /* Ultrix behaves like BSD on Vaxen. */ 122 /* Ultrix behaves like BSD on Vaxen. */
121 #define BSD 123 #define BSD
122 #endif 124 #endif
123 125
148 150
149 #if defined(ultrix) && defined(mips) 151 #if defined(ultrix) && defined(mips)
150 #define decstation 152 #define decstation
151 #endif 153 #endif
152 154
153 #if (defined(sun) && defined(USG)) || defined (SOLARIS2) 155 #if (defined(sun) && defined(SVR4)) || defined (SOLARIS2)
154 #define SUNOS_5 156 #define SUNOS_5
155 #endif 157 #endif
156 158
157 #if defined (__osf__) && (defined (__alpha) || defined (__alpha__)) 159 #if defined (__osf__) && (defined (__alpha) || defined (__alpha__))
158 #define OSF_ALPHA 160 #define OSF_ALPHA
289 #endif 291 #endif
290 292
291 /* VAX C can't handle multi-line #ifs, or lines longer that 256 characters. */ 293 /* VAX C can't handle multi-line #ifs, or lines longer that 256 characters. */
292 #ifndef NLIST_STRUCT 294 #ifndef NLIST_STRUCT
293 295
294 /* XEmacs addition */
295 #ifdef _AIX
296 #define NLIST_STRUCT
297 #endif
298
299 #ifdef MORE_BSD 296 #ifdef MORE_BSD
300 #define NLIST_STRUCT 297 #define NLIST_STRUCT
301 #endif 298 #endif
302 299
303 #ifdef sun 300 #ifdef sun
379 376
380 #if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX)) 377 #if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX))
381 #define LDAV_SYMBOL "avenrun" 378 #define LDAV_SYMBOL "avenrun"
382 #endif 379 #endif
383 380
384 #include <stdlib.h> 381 #ifdef HAVE_UNISTD_H
385 #include <unistd.h> 382 #include <unistd.h>
383 #endif
386 384
387 #include <stdio.h> 385 #include <stdio.h>
388 386
389 /* LOAD_AVE_TYPE should only get defined if we're going to use the 387 /* LOAD_AVE_TYPE should only get defined if we're going to use the
390 nlist method. */ 388 nlist method. */
429 #endif /* !LDAV_CVT */ 427 #endif /* !LDAV_CVT */
430 428
431 #endif /* LOAD_AVE_TYPE */ 429 #endif /* LOAD_AVE_TYPE */
432 430
433 #ifdef NeXT 431 #ifdef NeXT
434 /* This undef is needed to shut up the NeXT compiler about a stupid
435 non-problem. */
436 #undef index
437 #ifdef HAVE_MACH_MACH_H 432 #ifdef HAVE_MACH_MACH_H
438 #include <mach/mach.h> 433 #include <mach/mach.h>
439 #else 434 #else
440 #include <mach.h> 435 #include <mach.h>
441 #endif 436 #endif
470 465
471 #ifdef DGUX 466 #ifdef DGUX
472 #include <sys/dg_sys_info.h> 467 #include <sys/dg_sys_info.h>
473 #endif 468 #endif
474 469
475 /* XEmacs addition */ 470 #ifdef XEMACS
476 #if !defined(LDAV_DONE) && defined(HPUX) && !defined (HPUX_PRE_8_0) 471 #if defined (HAVE_SYS_PSTAT_H)
477 #include <sys/pstat.h> 472 #include <sys/pstat.h>
478 #endif 473 #endif /* HAVE_SYS_PSTAT_H (on HPUX) */
474 #endif /* XEMACS */
479 475
480 #if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION) 476 #if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION)
481 #include <fcntl.h> 477 #include <fcntl.h>
482 #else 478 #else
483 #include <sys/file.h> 479 #include <sys/file.h>
498 #ifdef DGUX 494 #ifdef DGUX
499 static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */ 495 static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */
500 #endif /* DGUX */ 496 #endif /* DGUX */
501 497
502 #ifdef LOAD_AVE_TYPE 498 #ifdef LOAD_AVE_TYPE
503 #if defined (VMS) || !defined (SUNOS_5)
504 /* File descriptor open to /dev/kmem or VMS load ave driver. */ 499 /* File descriptor open to /dev/kmem or VMS load ave driver. */
505 static int channel; 500 static int channel;
506 #endif /* VMS || !SUNOS_5 */
507 /* Nonzero iff channel is valid. */ 501 /* Nonzero iff channel is valid. */
508 static int getloadavg_initialized; 502 static int getloadavg_initialized;
509 /* Offset in kmem to seek to read load average, or 0 means invalid. */ 503 /* Offset in kmem to seek to read load average, or 0 means invalid. */
510 static long offset; 504 static long offset;
511 505
534 /* Set errno to zero to indicate that there was no particular error; 528 /* Set errno to zero to indicate that there was no particular error;
535 this function just can't work at all on this system. */ 529 this function just can't work at all on this system. */
536 errno = 0; 530 errno = 0;
537 elem = -1; 531 elem = -1;
538 #endif 532 #endif
533
534 #ifdef XEMACS
535 #if ! defined (LDAV_DONE) && defined (HAVE_KSTAT_H) && defined (HAVE_LIBKSTAT)
536 #define LDAV_DONE
537
538 /* getloadavg is best implemented using kstat (kernel stats),
539 on systems (like SunOS5) that support it,
540 since you don't have to be superusers to use it.
541 Thanks to Zlatko Calusic <zcalusic@srce.hr>.
542 Integrated to XEmacs by Hrvoje Niksic <hniksic@srce.hr>. */
543 static kstat_ctl_t *kc;
544 static kstat_t *ksp;
545 static kstat_named_t *buf;
546
547 if (!getloadavg_initialized)
548 {
549 kc = kstat_open();
550 if (!kc)
551 return -1;
552 getloadavg_initialized = 1;
553 }
554 ksp = kstat_lookup(kc, "unix", 0, "system_misc");
555 if (!ksp)
556 return -1;
557 if (kstat_read(kc, ksp, ksp->ks_data) < 0)
558 return -1;
559 buf = malloc(ksp->ks_data_size);
560 if (!buf)
561 return -1;
562 memcpy(buf, ksp->ks_data, ksp->ks_data_size);
563 if (nelem > 3)
564 nelem = 3;
565 for (elem = 0; elem < nelem; elem++)
566 loadavg[elem] = (buf + 6 + elem)->value.ul / 256.0;
567 free(buf);
568
569 #endif /* HAVE_KSTAT_H && HAVE_LIBKSTAT */
570
571 #if !defined (LDAV_DONE) && defined (HAVE_SYS_PSTAT_H)
572 #define LDAV_DONE
573 /* This is totally undocumented, and is not guaranteed to work, but
574 mayhap it might .... If it does work, it will work only on HP-UX
575 8.0 or later. -- Darryl Okahata <darrylo@sr.hp.com> */
576 #undef LOAD_AVE_TYPE /* Make sure these don't exist. */
577 #undef LOAD_AVE_CVT
578 #undef LDAV_SYMBOL
579 struct pst_dynamic procinfo;
580 union pstun statbuf;
581
582 statbuf.pst_dynamic = &procinfo;
583 if (pstat (PSTAT_DYNAMIC, statbuf, sizeof (struct pst_dynamic), 0, 0) == -1)
584 return (-1);
585 loadavg[elem++] = procinfo.psd_avg_1_min;
586 loadavg[elem++] = procinfo.psd_avg_5_min;
587 loadavg[elem++] = procinfo.psd_avg_15_min;
588 #endif /* HPUX */
589
590 #endif /* XEMACS */
539 591
540 #if !defined (LDAV_DONE) && defined (__linux__) 592 #if !defined (LDAV_DONE) && defined (__linux__)
541 #define LDAV_DONE 593 #define LDAV_DONE
542 #undef LOAD_AVE_TYPE 594 #undef LOAD_AVE_TYPE
543 595
604 656
605 host_t host; 657 host_t host;
606 struct processor_set_basic_info info; 658 struct processor_set_basic_info info;
607 unsigned info_count; 659 unsigned info_count;
608 660
609 if (nelem > 1) 661 /* We only know how to get the 1-minute average for this system,
610 { 662 so even if the caller asks for more than 1, we only return 1. */
611 /* We only know how to get the 1-minute average for this system. */
612 errno = EINVAL;
613 return -1;
614 }
615 663
616 if (!getloadavg_initialized) 664 if (!getloadavg_initialized)
617 { 665 {
618 if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS) 666 if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
619 getloadavg_initialized = 1; 667 getloadavg_initialized = 1;
645 We only know how to get the 1-minute average for this system. */ 693 We only know how to get the 1-minute average for this system. */
646 694
647 struct proc_summary proc_sum_data; 695 struct proc_summary proc_sum_data;
648 struct stat_descr proc_info; 696 struct stat_descr proc_info;
649 double load; 697 double load;
650 unsigned int i, j; 698 register unsigned int i, j;
651 699
652 if (cpus == 0) 700 if (cpus == 0)
653 { 701 {
654 unsigned int c, i; 702 register unsigned int c, i;
655 struct cpu_config conf; 703 struct cpu_config conf;
656 struct stat_descr desc; 704 struct stat_descr desc;
657 705
658 desc.sd_next = 0; 706 desc.sd_next = 0;
659 desc.sd_subsys = SUBSYS_CPU; 707 desc.sd_subsys = SUBSYS_CPU;
752 #if !defined (LDAV_DONE) && defined (OSF_MIPS) 800 #if !defined (LDAV_DONE) && defined (OSF_MIPS)
753 #define LDAV_DONE 801 #define LDAV_DONE
754 802
755 struct tbl_loadavg load_ave; 803 struct tbl_loadavg load_ave;
756 table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); 804 table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
757 while (elem < nelem && elem < 3) 805 loadavg[elem++]
758 { 806 = (load_ave.tl_lscale == 0
759 loadavg[elem++] = (load_ave.tl_lscale == 0 807 ? load_ave.tl_avenrun.d[0]
760 ? load_ave.tl_avenrun.d[0] 808 : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
761 : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
762 }
763 #endif /* OSF_MIPS */ 809 #endif /* OSF_MIPS */
764 810
765 #if !defined (LDAV_DONE) && (defined (MSDOS) || defined (WIN32)) 811 #if !defined (LDAV_DONE) && (defined (MSDOS) || defined (WIN32))
766 #define LDAV_DONE 812 #define LDAV_DONE
767 813
821 } 867 }
822 868
823 if (!getloadavg_initialized) 869 if (!getloadavg_initialized)
824 return -1; 870 return -1;
825 #endif /* VMS */ 871 #endif /* VMS */
826
827 #if !defined (LDAV_DONE) && defined (HPUX) && !defined (HPUX_PRE_8_0)
828 #define LDAV_DONE
829 /*
830 * This is totally undocumented, and is not guaranteed to work, but
831 * mayhap it might .... If it does work, it will work only on HP-UX
832 * 8.0 or later. -- Darryl Okahata <darrylo@sr.hp.com>
833 */
834 #undef LOAD_AVE_TYPE /* Make sure these don't exist. */
835 #undef LOAD_AVE_CVT
836 #undef LDAV_SYMBOL
837 struct pst_dynamic procinfo;
838 union pstun statbuf;
839
840 statbuf.pst_dynamic = &procinfo;
841 if (pstat (PSTAT_DYNAMIC, statbuf, sizeof (struct pst_dynamic), 0, 0) == -1)
842 return (-1);
843 loadavg[elem++] = procinfo.psd_avg_1_min;
844 loadavg[elem++] = procinfo.psd_avg_5_min;
845 loadavg[elem++] = procinfo.psd_avg_15_min;
846 #endif /* HPUX */
847 872
848 #if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS) 873 #if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS)
849 874
850 /* UNIX-specific code -- read the average from /dev/kmem. */ 875 /* UNIX-specific code -- read the average from /dev/kmem. */
851 876