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.

Reply via email to