From 7d6f84e81accb63452f8792b60a406e7e157f553 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Mon, 19 Jul 2004 18:13:56 +0000 Subject: [PATCH] refactor perfstat wrapper so it can be used in other functions --- src/os/aix/aix_sigar.c | 129 +++++++++++++++++++++++------------------ src/os/aix/sigar_os.h | 10 ++++ 2 files changed, 83 insertions(+), 56 deletions(-) diff --git a/src/os/aix/aix_sigar.c b/src/os/aix/aix_sigar.c index 4a776c4a..db3d1273 100644 --- a/src/os/aix/aix_sigar.c +++ b/src/os/aix/aix_sigar.c @@ -28,8 +28,6 @@ #include #include -#include "libperfstat.h" - #include "user_v5.h" #include "utmp_v5.h" @@ -111,6 +109,7 @@ int sigar_os_open(sigar_t **sigar) (*sigar)->cpuinfo = NULL; (*sigar)->cpuinfo_size = 0; SIGAR_ZERO(&(*sigar)->swaps); + SIGAR_ZERO(&(*sigar)->perfstat); i = getpagesize(); while ((i >>= 1) > 0) { @@ -151,6 +150,9 @@ int sigar_os_close(sigar_t *sigar) if (sigar->cpuinfo) { free(sigar->cpuinfo); } + if (sigar->perfstat.handle) { + dlclose(sigar->perfstat.handle); + } free(sigar); return SIGAR_OK; } @@ -165,6 +167,70 @@ char *sigar_os_error_string(int err) } } +/* + * the perfstat api is only supported in aix 5.2+ + * in order to be binary compatible with 4.3 and 5.1 + * we must jump through some hoops. libperfstat.a + * is a static library, we need dynamic. + * libsigar_aixperfstat.so is juat a proxy to libperfstat.a + */ +#define SIGAR_AIXPERFSTAT "/libsigar_aixperfstat.so" + +static int sigar_perfstat_init(sigar_t *sigar) +{ + perfstat_cpu_func_t pcpu; + void *handle; + char libperfstat[SIGAR_PATH_MAX], *path; + int len; + + if (sigar->perfstat.avail == 1) { + return SIGAR_OK; + } + if (sigar->perfstat.avail == -1) { + return ENOENT; + } + + path = sigar_get_self_path(sigar); + len = strlen(path); + + memcpy(&path[0], sigar->self_path, len); + memcpy(&path[len], SIGAR_AIXPERFSTAT, + sizeof(SIGAR_AIXPERFSTAT)); + + if (!(handle = dlopen(path, RTLD_LOCAL|RTLD_LAZY))) { + if (SIGAR_LOG_IS_DEBUG(sigar)) { + sigar_log_printf(sigar, SIGAR_LOG_DEBUG, + "failed to open '%s': %s", + path, sigar_strerror(sigar, errno)); + } + + sigar->perfstat.avail = -1; + return errno; + } + + pcpu = (perfstat_cpu_func_t)dlsym(handle, + "sigar_perfstat_cpu_total"); + + if (!pcpu) { + if (SIGAR_LOG_IS_DEBUG(sigar)) { + sigar_log_printf(sigar, SIGAR_LOG_DEBUG, + "dlsym(sigar_perfstat_cpu_total) failed: %s", + dlerror()); + } + + dlclose(handle); + + sigar->perfstat.avail = -1; + return ENOENT; + } + + sigar->perfstat.avail = 1; + sigar->perfstat.handle = handle; + sigar->perfstat.cpu_total = pcpu; + + return SIGAR_OK; +} + #define PAGESHIFT(v) \ ((v) << sigar->pagesize) @@ -1151,67 +1217,18 @@ static char *sigar_get_odm_model(sigar_t *sigar) #define SIGAR_CPU_CACHE_SIZE \ (_system_configuration.L2_cache_size / 1024) -/* - * the perfstat api is only supported in aix 5.2+ - * in order to be binary compatible with 4.3 and 5.1 - * we must jump through some hoops. libperfstat.a - * is a static library, we need dynamic. - * libsigar_aixperfstat.so is juat a proxy to libperfstat.a - */ -#define SIGAR_AIXPERFSTAT "/libsigar_aixperfstat.so" - -typedef int (*perfstat_cpu_func_t)(perfstat_id_t *, - perfstat_cpu_total_t *, - int, int); - static int sigar_get_cpu_mhz_perfstat(sigar_t *sigar) { - int status = 0; perfstat_cpu_total_t data; - perfstat_cpu_func_t pcpu; - void *handle; - char libperfstat[SIGAR_PATH_MAX]; - char *path = sigar_get_self_path(sigar); - int len = strlen(path); - memcpy(&path[0], sigar->self_path, len); - memcpy(&path[len], SIGAR_AIXPERFSTAT, - sizeof(SIGAR_AIXPERFSTAT)); - - if (!(handle = dlopen(path, RTLD_LOCAL|RTLD_LAZY))) { - if (SIGAR_LOG_IS_DEBUG(sigar)) { - sigar_log_printf(sigar, SIGAR_LOG_DEBUG, - "failed to open '%s': %s", - path, sigar_strerror(sigar, errno)); + if (sigar_perfstat_init(sigar) == SIGAR_OK) { + if (sigar->perfstat.cpu_total(0, &data, sizeof(data), 1)) { + sigar->cpu_mhz = data.processorHZ / 1000000; + return SIGAR_OK; } - - return errno; } - pcpu = (perfstat_cpu_func_t)dlsym(handle, - "sigar_perfstat_cpu_total"); - - if (!pcpu) { - if (SIGAR_LOG_IS_DEBUG(sigar)) { - sigar_log_printf(sigar, SIGAR_LOG_DEBUG, - "dlsym(sigar_perfstat_cpu_total) failed: %s", - dlerror()); - } - - dlclose(handle); - return ENOENT; - } - - if (pcpu(0, &data, sizeof(data), 1)) { - sigar->cpu_mhz = data.processorHZ / 1000000; - } - else { - dlclose(handle); - return errno; - } - - dlclose(handle); - return SIGAR_OK; + return ENOENT; } static int sigar_get_cpu_mhz(sigar_t *sigar) diff --git a/src/os/aix/sigar_os.h b/src/os/aix/sigar_os.h index 183f8f2c..4692b5f1 100644 --- a/src/os/aix/sigar_os.h +++ b/src/os/aix/sigar_os.h @@ -5,6 +5,7 @@ #include #include #include +#include "libperfstat.h" enum { KOFFSET_LOADAVG, @@ -26,6 +27,10 @@ typedef int (*vminfo_func_t) (void *, int, int); typedef int (*proc_fd_func_t) (sigar_t *, sigar_pid_t, sigar_proc_fd_t *); +typedef int (*perfstat_cpu_func_t)(perfstat_id_t *, + perfstat_cpu_total_t *, + int, int); + struct sigar_t { SIGAR_T_BASE; int kmem; @@ -33,6 +38,11 @@ struct sigar_t { long koffsets[KOFFSET_MAX]; vminfo_func_t getvminfo; proc_fd_func_t getprocfd; + struct { + int avail; + perfstat_cpu_func_t cpu_total; + void *handle; + } perfstat; int pagesize; swaps_t swaps; time_t last_getprocs;