summaryrefslogtreecommitdiffstats
path: root/gl/getloadavg.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/getloadavg.c')
-rw-r--r--gl/getloadavg.c226
1 files changed, 83 insertions, 143 deletions
diff --git a/gl/getloadavg.c b/gl/getloadavg.c
index 752ec1f5..73b2ee28 100644
--- a/gl/getloadavg.c
+++ b/gl/getloadavg.c
@@ -1,6 +1,6 @@
1/* Get the system load averages. 1/* Get the system load averages.
2 2
3 Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2025 Free Software 3 Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2026 Free Software
4 Foundation, Inc. 4 Foundation, Inc.
5 5
6 NOTE: The canonical source of this file is maintained with gnulib. 6 NOTE: The canonical source of this file is maintained with gnulib.
@@ -140,21 +140,6 @@
140# define SUNOS_5 140# define SUNOS_5
141# endif 141# endif
142 142
143# if defined (__osf__) && defined (__alpha)
144# define OSF_ALPHA
145# include <sys/mbuf.h>
146# include <sys/socket.h>
147# include <net/route.h>
148# include <sys/table.h>
149/* Tru64 4.0D's table.h redefines sys */
150# undef sys
151# endif
152
153# if defined (__osf__) && (defined (mips) || defined (__mips__))
154# define OSF_MIPS
155# include <sys/table.h>
156# endif
157
158 143
159/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */ 144/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */
160# ifndef LOAD_AVE_TYPE 145# ifndef LOAD_AVE_TYPE
@@ -167,31 +152,16 @@
167# define LOAD_AVE_TYPE long 152# define LOAD_AVE_TYPE long
168# endif 153# endif
169 154
170# ifdef sgi
171# define LOAD_AVE_TYPE long
172# endif
173
174# ifdef SVR4 155# ifdef SVR4
175# define LOAD_AVE_TYPE long 156# define LOAD_AVE_TYPE long
176# endif 157# endif
177 158
178# ifdef OSF_ALPHA
179# define LOAD_AVE_TYPE long
180# endif
181
182# if defined _AIX && ! defined HAVE_LIBPERFSTAT 159# if defined _AIX && ! defined HAVE_LIBPERFSTAT
183# define LOAD_AVE_TYPE long 160# define LOAD_AVE_TYPE long
184# endif 161# endif
185 162
186# endif /* No LOAD_AVE_TYPE. */ 163# endif /* No LOAD_AVE_TYPE. */
187 164
188# ifdef OSF_ALPHA
189/* <sys/param.h> defines an incorrect value for FSCALE on Alpha OSF/1,
190 according to ghazi@noc.rutgers.edu. */
191# undef FSCALE
192# define FSCALE 1024.0
193# endif
194
195 165
196# ifndef FSCALE 166# ifndef FSCALE
197 167
@@ -324,10 +294,6 @@
324# endif 294# endif
325# endif /* NeXT */ 295# endif /* NeXT */
326 296
327# ifdef sgi
328# include <sys/sysmp.h>
329# endif /* sgi */
330
331# ifdef UMAX 297# ifdef UMAX
332# include <signal.h> 298# include <signal.h>
333# include <sys/time.h> 299# include <sys/time.h>
@@ -389,7 +355,7 @@ static bool getloadavg_initialized;
389/* Offset in kmem to seek to read load average, or 0 means invalid. */ 355/* Offset in kmem to seek to read load average, or 0 means invalid. */
390static long offset; 356static long offset;
391 357
392# if ! defined __VMS && ! defined sgi && ! (defined __linux__ || defined __ANDROID__) 358# if ! defined __VMS && ! (defined __linux__ || defined __ANDROID__)
393static struct nlist name_list[2]; 359static struct nlist name_list[2];
394# endif 360# endif
395 361
@@ -418,51 +384,47 @@ getloadavg (double loadavg[], int nelem)
418# if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) /* Solaris <= 2.6 */ 384# if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) /* Solaris <= 2.6 */
419/* Use libkstat because we don't have to be root. */ 385/* Use libkstat because we don't have to be root. */
420# define LDAV_DONE 386# define LDAV_DONE
421 kstat_ctl_t *kc; 387 {
422 kstat_t *ksp; 388 kstat_ctl_t *kc = kstat_open ();
423 kstat_named_t *kn; 389 if (kc == NULL)
424 int saved_errno; 390 return -1;
425 391 kstat_t *ksp = kstat_lookup (kc, "unix", 0, "system_misc");
426 kc = kstat_open (); 392 if (ksp == NULL)
427 if (kc == NULL) 393 return -1;
428 return -1; 394 if (kstat_read (kc, ksp, 0) == -1)
429 ksp = kstat_lookup (kc, "unix", 0, "system_misc"); 395 return -1;
430 if (ksp == NULL)
431 return -1;
432 if (kstat_read (kc, ksp, 0) == -1)
433 return -1;
434
435
436 kn = kstat_data_lookup (ksp, "avenrun_1min");
437 if (kn == NULL)
438 {
439 /* Return -1 if no load average information is available. */
440 nelem = 0;
441 elem = -1;
442 }
443
444 if (nelem >= 1)
445 loadavg[elem++] = (double) kn->value.ul / FSCALE;
446
447 if (nelem >= 2)
448 {
449 kn = kstat_data_lookup (ksp, "avenrun_5min");
450 if (kn != NULL)
451 {
452 loadavg[elem++] = (double) kn->value.ul / FSCALE;
453 396
454 if (nelem >= 3) 397 kstat_named_t *kn = kstat_data_lookup (ksp, "avenrun_1min");
455 { 398 if (kn == NULL)
456 kn = kstat_data_lookup (ksp, "avenrun_15min"); 399 {
457 if (kn != NULL) 400 /* Return -1 if no load average information is available. */
458 loadavg[elem++] = (double) kn->value.ul / FSCALE; 401 nelem = 0;
459 } 402 elem = -1;
460 } 403 }
461 } 404
405 if (nelem >= 1)
406 loadavg[elem++] = (double) kn->value.ul / FSCALE;
407
408 if (nelem >= 2)
409 {
410 kn = kstat_data_lookup (ksp, "avenrun_5min");
411 if (kn != NULL)
412 {
413 loadavg[elem++] = (double) kn->value.ul / FSCALE;
414
415 if (nelem >= 3)
416 {
417 kn = kstat_data_lookup (ksp, "avenrun_15min");
418 if (kn != NULL)
419 loadavg[elem++] = (double) kn->value.ul / FSCALE;
420 }
421 }
422 }
462 423
463 saved_errno = errno; 424 int saved_errno = errno;
464 kstat_close (kc); 425 kstat_close (kc);
465 errno = saved_errno; 426 errno = saved_errno;
427 }
466# endif /* HAVE_LIBKSTAT */ 428# endif /* HAVE_LIBKSTAT */
467 429
468# if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) 430# if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
@@ -523,13 +485,12 @@ getloadavg (double loadavg[], int nelem)
523 485
524 char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")]; 486 char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")];
525 char const *ptr = ldavgbuf; 487 char const *ptr = ldavgbuf;
526 int fd, count, saved_errno;
527 488
528 fd = open ("/proc/loadavg", O_RDONLY | O_CLOEXEC); 489 int fd = open ("/proc/loadavg", O_RDONLY | O_CLOEXEC);
529 if (fd == -1) 490 if (fd == -1)
530 return -1; 491 return -1;
531 count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); 492 int count = read (fd, ldavgbuf, sizeof ldavgbuf - 1);
532 saved_errno = errno; 493 int saved_errno = errno;
533 (void) close (fd); 494 (void) close (fd);
534 errno = saved_errno; 495 errno = saved_errno;
535 if (count <= 0) 496 if (count <= 0)
@@ -538,9 +499,6 @@ getloadavg (double loadavg[], int nelem)
538 499
539 for (elem = 0; elem < nelem; elem++) 500 for (elem = 0; elem < nelem; elem++)
540 { 501 {
541 double numerator = 0;
542 double denominator = 1;
543
544 while (*ptr == ' ') 502 while (*ptr == ' ')
545 ptr++; 503 ptr++;
546 504
@@ -556,6 +514,9 @@ getloadavg (double loadavg[], int nelem)
556 break; 514 break;
557 } 515 }
558 516
517 double numerator = 0;
518 double denominator = 1;
519
559 while ('0' <= *ptr && *ptr <= '9') 520 while ('0' <= *ptr && *ptr <= '9')
560 numerator = 10 * numerator + (*ptr++ - '0'); 521 numerator = 10 * numerator + (*ptr++ - '0');
561 522
@@ -578,24 +539,25 @@ getloadavg (double loadavg[], int nelem)
578# define NETBSD_LDAV_FILE "/kern/loadavg" 539# define NETBSD_LDAV_FILE "/kern/loadavg"
579# endif 540# endif
580 541
581 unsigned long int load_ave[3], scale;
582 int count;
583 char readbuf[4 * INT_BUFSIZE_BOUND (unsigned long int) + 1];
584 int fd = open (NETBSD_LDAV_FILE, O_RDONLY | O_CLOEXEC); 542 int fd = open (NETBSD_LDAV_FILE, O_RDONLY | O_CLOEXEC);
585 if (fd < 0) 543 if (fd < 0)
586 return fd; 544 return fd;
545
546 char readbuf[4 * INT_BUFSIZE_BOUND (unsigned long int) + 1];
587 int nread = read (fd, readbuf, sizeof readbuf - 1); 547 int nread = read (fd, readbuf, sizeof readbuf - 1);
588 int err = errno; 548 int saved_errno = errno;
589 close (fd); 549 close (fd);
590 if (nread < 0) 550 if (nread < 0)
591 { 551 {
592 errno = err; 552 errno = saved_errno;
593 return -1; 553 return -1;
594 } 554 }
595 readbuf[nread] = '\0'; 555 readbuf[nread] = '\0';
596 count = sscanf (readbuf, "%lu %lu %lu %lu\n", 556
597 &load_ave[0], &load_ave[1], &load_ave[2], 557 unsigned long int load_ave[3], scale;
598 &scale); 558 int count = sscanf (readbuf, "%lu %lu %lu %lu\n",
559 &load_ave[0], &load_ave[1], &load_ave[2],
560 &scale);
599 if (count != 4) 561 if (count != 4)
600 { 562 {
601 errno = ENOTSUP; 563 errno = ENOTSUP;
@@ -613,10 +575,6 @@ getloadavg (double loadavg[], int nelem)
613# define LDAV_DONE 575# define LDAV_DONE
614 /* The NeXT code was adapted from iscreen 3.2. */ 576 /* The NeXT code was adapted from iscreen 3.2. */
615 577
616 host_t host;
617 struct processor_set_basic_info info;
618 unsigned int info_count;
619
620 /* We only know how to get the 1-minute average for this system, 578 /* We only know how to get the 1-minute average for this system,
621 so even if the caller asks for more than 1, we only return 1. */ 579 so even if the caller asks for more than 1, we only return 1. */
622 580
@@ -628,7 +586,9 @@ getloadavg (double loadavg[], int nelem)
628 586
629 if (getloadavg_initialized) 587 if (getloadavg_initialized)
630 { 588 {
631 info_count = PROCESSOR_SET_BASIC_INFO_COUNT; 589 host_t host;
590 struct processor_set_basic_info info;
591 unsigned int info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
632 if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, 592 if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
633 (processor_set_info_t) &info, &info_count) 593 (processor_set_info_t) &info, &info_count)
634 != KERN_SUCCESS) 594 != KERN_SUCCESS)
@@ -654,14 +614,9 @@ getloadavg (double loadavg[], int nelem)
654 can be gathered with inq_stats system calls. 614 can be gathered with inq_stats system calls.
655 We only know how to get the 1-minute average for this system. */ 615 We only know how to get the 1-minute average for this system. */
656 616
657 struct proc_summary proc_sum_data;
658 struct stat_descr proc_info;
659 double load;
660 register unsigned int i, j;
661
662 if (cpus == 0) 617 if (cpus == 0)
663 { 618 {
664 register unsigned int c, i; 619 register unsigned int c;
665 struct cpu_config conf; 620 struct cpu_config conf;
666 struct stat_descr desc; 621 struct stat_descr desc;
667 622
@@ -675,7 +630,7 @@ getloadavg (double loadavg[], int nelem)
675 return -1; 630 return -1;
676 631
677 c = 0; 632 c = 0;
678 for (i = 0; i < conf.config_maxclass; ++i) 633 for (unsigned int i = 0; i < conf.config_maxclass; ++i)
679 { 634 {
680 struct class_stats stats; 635 struct class_stats stats;
681 memset (&stats, 0, sizeof stats); 636 memset (&stats, 0, sizeof stats);
@@ -694,6 +649,9 @@ getloadavg (double loadavg[], int nelem)
694 samples = cpus < 2 ? 3 : (2 * cpus / 3); 649 samples = cpus < 2 ? 3 : (2 * cpus / 3);
695 } 650 }
696 651
652 struct proc_summary proc_sum_data;
653
654 struct stat_descr proc_info;
697 proc_info.sd_next = 0; 655 proc_info.sd_next = 0;
698 proc_info.sd_subsys = SUBSYS_PROC; 656 proc_info.sd_subsys = SUBSYS_PROC;
699 proc_info.sd_type = PROCTYPE_SUMMARY; 657 proc_info.sd_type = PROCTYPE_SUMMARY;
@@ -704,9 +662,9 @@ getloadavg (double loadavg[], int nelem)
704 if (inq_stats (1, &proc_info) != 0) 662 if (inq_stats (1, &proc_info) != 0)
705 return -1; 663 return -1;
706 664
707 load = proc_sum_data.ps_nrunnable; 665 double load = proc_sum_data.ps_nrunnable;
708 j = 0; 666 register unsigned int j = 0;
709 for (i = samples - 1; i > 0; --i) 667 for (unsigned int i = samples - 1; i > 0; --i)
710 { 668 {
711 load += proc_sum_data.ps_nrun[j]; 669 load += proc_sum_data.ps_nrun[j];
712 if (j++ == PS_NRUNSIZE) 670 if (j++ == PS_NRUNSIZE)
@@ -781,18 +739,6 @@ getloadavg (double loadavg[], int nelem)
781 } 739 }
782# endif /* __MSDOS__ || WINDOWS32 */ 740# endif /* __MSDOS__ || WINDOWS32 */
783 741
784# if !defined (LDAV_DONE) && defined (OSF_ALPHA) /* OSF/1 */
785# define LDAV_DONE
786
787 struct tbl_loadavg load_ave;
788 table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
789 for (elem = 0; elem < nelem; elem++)
790 loadavg[elem]
791 = (load_ave.tl_lscale == 0
792 ? load_ave.tl_avenrun.d[elem]
793 : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
794# endif /* OSF_ALPHA */
795
796# if ! defined LDAV_DONE && defined __VMS /* VMS */ 742# if ! defined LDAV_DONE && defined __VMS /* VMS */
797 /* VMS specific code -- read from the Load Ave driver. */ 743 /* VMS specific code -- read from the Load Ave driver. */
798 744
@@ -837,52 +783,44 @@ getloadavg (double loadavg[], int nelem)
837# endif /* ! defined LDAV_DONE && defined __VMS */ 783# endif /* ! defined LDAV_DONE && defined __VMS */
838 784
839# if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS 785# if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS
840 /* IRIX, other old systems */ 786 /* other old systems */
841 787
842 /* UNIX-specific code -- read the average from /dev/kmem. */ 788 /* UNIX-specific code -- read the average from /dev/kmem. */
843 789
844# define LDAV_PRIVILEGED /* This code requires special installation. */ 790# define LDAV_PRIVILEGED /* This code requires special installation. */
845 791
846 LOAD_AVE_TYPE load_ave[3];
847
848 /* Get the address of LDAV_SYMBOL. */ 792 /* Get the address of LDAV_SYMBOL. */
849 if (offset == 0) 793 if (offset == 0)
850 { 794 {
851# ifndef sgi 795# if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER
852# if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER
853 strcpy (name_list[0].n_name, LDAV_SYMBOL); 796 strcpy (name_list[0].n_name, LDAV_SYMBOL);
854 strcpy (name_list[1].n_name, ""); 797 strcpy (name_list[1].n_name, "");
855# else /* NLIST_STRUCT */ 798# else /* NLIST_STRUCT */
856# ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME 799# ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
857 name_list[0].n_un.n_name = LDAV_SYMBOL; 800 name_list[0].n_un.n_name = LDAV_SYMBOL;
858 name_list[1].n_un.n_name = 0; 801 name_list[1].n_un.n_name = 0;
859# else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ 802# else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
860 name_list[0].n_name = LDAV_SYMBOL; 803 name_list[0].n_name = LDAV_SYMBOL;
861 name_list[1].n_name = 0; 804 name_list[1].n_name = 0;
862# endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ 805# endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
863# endif /* NLIST_STRUCT */ 806# endif /* NLIST_STRUCT */
864 807
865# ifndef SUNOS_5 808# ifndef SUNOS_5
866 if ( 809 if (
867# if !defined (_AIX) 810# if !defined (_AIX)
868 nlist (KERNEL_FILE, name_list) 811 nlist (KERNEL_FILE, name_list)
869# else /* _AIX */ 812# else /* _AIX */
870 knlist (name_list, 1, sizeof (name_list[0])) 813 knlist (name_list, 1, sizeof (name_list[0]))
871# endif 814# endif
872 >= 0) 815 >= 0)
873 /* Omit "&& name_list[0].n_type != 0 " -- it breaks on Sun386i. */ 816 /* Omit "&& name_list[0].n_type != 0 " -- it breaks on Sun386i. */
874 { 817 {
875# ifdef FIXUP_KERNEL_SYMBOL_ADDR 818# ifdef FIXUP_KERNEL_SYMBOL_ADDR
876 FIXUP_KERNEL_SYMBOL_ADDR (name_list); 819 FIXUP_KERNEL_SYMBOL_ADDR (name_list);
877# endif 820# endif
878 offset = name_list[0].n_value; 821 offset = name_list[0].n_value;
879 } 822 }
880# endif /* !SUNOS_5 */ 823# endif /* !SUNOS_5 */
881# else /* sgi */
882 ptrdiff_t ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
883 if (ldav_off != -1)
884 offset = (long int) ldav_off & 0x7fffffff;
885# endif /* sgi */
886 } 824 }
887 825
888 /* Make sure we have /dev/kmem open. */ 826 /* Make sure we have /dev/kmem open. */
@@ -909,6 +847,8 @@ getloadavg (double loadavg[], int nelem)
909# endif /* SUNOS_5 */ 847# endif /* SUNOS_5 */
910 } 848 }
911 849
850 LOAD_AVE_TYPE load_ave[3];
851
912 /* If we can, get the load average values. */ 852 /* If we can, get the load average values. */
913 if (offset && getloadavg_initialized) 853 if (offset && getloadavg_initialized)
914 { 854 {