I seem to have lost Jim's reply, but here is a patch. Works on
aix-4.3.3 and aix-5.3.
The SBITS thing is the way the libperstat.h header recommends
calculating the loadavg:
/* To calculate the load average, divide the numbers by (1<<SBITS). SBITS is
defined in <sys/proc.h>. */
Of course, it is not defined on aix4.3.3 ...
Peter
diff --git a/lib/getloadavg.c b/lib/getloadavg.c
index eac8483..ec09919 100644
--- a/lib/getloadavg.c
+++ b/lib/getloadavg.c
@@ -30,6 +30,8 @@
If that isn't an option, then just put
AC_CHECK_FUNCS(pstat_getdynamic) in your
configure.in file.
+ HAVE_LIBPERFSTAT Define this if your system has the
+ perfstat_cpu_total function in libperfstat
(AIX).
FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist.
KERNEL_FILE Name of the kernel file to nlist.
LDAV_CVT() Scale the load average from the kernel.
@@ -254,7 +256,7 @@
# define LOAD_AVE_TYPE long
# endif
-# ifdef _AIX
+# if defined (_AIX) && ! defined(HAVE_LIBPERFSTAT)
# define LOAD_AVE_TYPE long
# endif
@@ -309,7 +311,7 @@
# define FSCALE 100.0
# endif
-# ifdef _AIX
+# if defined (_AIX) && !defined(HAVE_LIBPERFSTAT)
# define FSCALE 65536.0
# endif
@@ -347,7 +349,7 @@
# define LDAV_SYMBOL "_Loadavg"
# endif
-# if !defined (LDAV_SYMBOL) && ((defined (hpux) && !defined (hp9000s300)) ||
defined (_SEQUENT_) || defined (SVR4) || defined (ISC) || defined (sgi) ||
(defined (ardent) && defined (titan)) || defined (_AIX))
+# 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)))
# define LDAV_SYMBOL "avenrun"
# endif
@@ -404,6 +406,14 @@
# endif /* LOAD_AVE_TYPE */
+# if defined (HAVE_LIBPERFSTAT)
+# include <libperfstat.h>
+# include <sys/proc.h>
+# ifndef SBITS
+# define SBITS 16
+# endif
+# endif
+
# if defined (__GNU__) && !defined (NeXT)
/* Note that NeXT Openstep defines __GNU__ even though it should not. */
/* GNU system acts much like NeXT, for load average purposes,
@@ -485,6 +495,10 @@ static kvm_t *kd;
# endif /* SUNOS_5 */
# endif /* LOAD_AVE_TYPE && !HAVE_LIBKSTAT */
+
+# if defined(HAVE_LIBPERFSTAT)
+static perfstat_cpu_total_t cpu_stats;
+# endif
/* Put the 1 minute, 5 minute and 15 minute load averages
into the first NELEM elements of LOADAVG.
@@ -568,6 +582,18 @@ getloadavg (double loadavg[], int nelem)
# endif /* hpux && HAVE_PSTAT_GETDYNAMIC */
+# if ! defined (LDAV_DONE) && defined(HAVE_LIBPERFSTAT)
+# define LDAV_DONE
+# undef LOAD_AVE_TYPE
+/* Use perfstat_cpu_total because we don't have to be root. */
+ int result = perfstat_cpu_total( NULL, &cpu_stats, sizeof(cpu_stats), 1);
+ if (result == -1) return result;
+ loadavg[0] = (double) cpu_stats.loadavg[0] / (double)(1 << SBITS);
+ loadavg[1] = (double) cpu_stats.loadavg[1] / (double)(1 << SBITS);
+ loadavg[2] = (double) cpu_stats.loadavg[2] / (double)(1 << SBITS);
+ elem = 3;
+# endif
+
# if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__))
# define LDAV_DONE
# undef LOAD_AVE_TYPE
diff --git a/m4/getloadavg.m4 b/m4/getloadavg.m4
index 8243729..c1547c7 100644
--- a/m4/getloadavg.m4
+++ b/m4/getloadavg.m4
@@ -31,6 +31,10 @@ AC_CHECK_FUNCS(pstat_getdynamic)
AC_CHECK_LIB(kstat, kstat_open)
test $ac_cv_lib_kstat_kstat_open = yes && gl_have_func=yes
+# AIX has libperfstat which does not require root
+AC_CHECK_LIB(perfstat, perfstat_cpu_total)
+test $ac_cv_lib_perfstat_perfstat_cpu_total = yes && gl_have_func=yes
+
# Some systems with -lutil have (and need) -lkvm as well, some do not.
# On Solaris, -lkvm requires nlist from -lelf, so check that first
# to get the right answer into the cache.