diff --git a/src/os/aix/aix_sigar.c b/src/os/aix/aix_sigar.c index 33cc0bb2..0af9eedd 100644 --- a/src/os/aix/aix_sigar.c +++ b/src/os/aix/aix_sigar.c @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -39,6 +40,12 @@ #define SBITS 16 #endif +#ifndef PTHRDSINFO_RUSAGE_START +#define PTHRDSINFO_RUSAGE_START 0x00000001 +#define PTHRDSINFO_RUSAGE_STOP 0x00000002 +#define PTHRDSINFO_RUSAGE_COLLECT 0x00000004 +#endif + /* * from libperfstat.h: * "To calculate the load average, divide the numbers by (1<aix_version = atoi(name.version); + (*sigar)->thrusage = PTHRDSINFO_RUSAGE_STOP; + (*sigar)->diskmap = NULL; return SIGAR_OK; @@ -169,6 +178,11 @@ int sigar_os_close(sigar_t *sigar) if (sigar->diskmap) { sigar_cache_destroy(sigar->diskmap); } + if (sigar->thrusage == PTHRDSINFO_RUSAGE_START) { + struct rusage usage; + sigar->perfstat.thread_rusage(&usage, + PTHRDSINFO_RUSAGE_STOP); + } free(sigar); return SIGAR_OK; } @@ -268,6 +282,18 @@ static int sigar_perfstat_init(sigar_t *sigar) return errno; } + sigar->perfstat.thread_rusage = + (thread_rusage_func_t)dlsym(handle, + "sigar_thread_rusage"); + + if (!sigar->perfstat.thread_rusage) { + if (SIGAR_LOG_IS_DEBUG(sigar)) { + sigar_log_printf(sigar, SIGAR_LOG_DEBUG, + "dlsym(sigar_thread_rusage) failed: %s", + dlerror()); + } + } + sigar->perfstat.cpu_total = (perfstat_cpu_total_func_t)dlsym(handle, "sigar_perfstat_cpu_total"); @@ -1237,11 +1263,46 @@ int sigar_proc_modules_get(sigar_t *sigar, sigar_pid_t pid, } } +#define SIGAR_MICROSEC2NANO(s) \ + ((sigar_uint64_t)(s) * (sigar_uint64_t)1000) + +#define TIME_NSEC(t) \ + (SIGAR_SEC2NANO((t).tv_sec) + SIGAR_MICROSEC2NANO((t).tv_usec)) + int sigar_thread_cpu_get(sigar_t *sigar, sigar_uint64_t id, sigar_thread_cpu_t *cpu) { - return SIGAR_ENOTIMPL; + struct rusage usage; + int retval; + + sigar_perfstat_init(sigar); + if (!sigar->perfstat.thread_rusage) { + return SIGAR_ENOTIMPL; + } + + if (sigar->thrusage != PTHRDSINFO_RUSAGE_START) { + sigar->thrusage = PTHRDSINFO_RUSAGE_START; + retval = + sigar->perfstat.thread_rusage(&usage, + PTHRDSINFO_RUSAGE_START); + if (retval != 0) { + return retval; + } + } + + retval = + sigar->perfstat.thread_rusage(&usage, + PTHRDSINFO_RUSAGE_COLLECT); + if (retval != 0) { + return retval; + } + + cpu->user = TIME_NSEC(usage.ru_utime); + cpu->sys = TIME_NSEC(usage.ru_stime); + cpu->total = TIME_NSEC(usage.ru_utime) + TIME_NSEC(usage.ru_stime); + + return SIGAR_OK; } int sigar_os_fs_type_get(sigar_file_system_t *fsp) diff --git a/src/os/aix/sigar_os.h b/src/os/aix/sigar_os.h index af560a11..cb2316fd 100644 --- a/src/os/aix/sigar_os.h +++ b/src/os/aix/sigar_os.h @@ -5,6 +5,8 @@ #include #include #include +#include + #include "libperfstat.h" enum { @@ -37,6 +39,8 @@ typedef int (*perfstat_swap_func_t)(perfstat_id_t *, perfstat_pagingspace_t *, size_t, int); +typedef int (*thread_rusage_func_t)(struct rusage *, int); + struct sigar_t { SIGAR_T_BASE; int kmem; @@ -49,6 +53,7 @@ struct sigar_t { perfstat_cpu_func_t cpu; perfstat_cpu_total_func_t cpu_total; perfstat_swap_func_t swap; + thread_rusage_func_t thread_rusage; void *handle; } perfstat; int pagesize; @@ -62,6 +67,7 @@ struct sigar_t { char model[128]; char self_path[SIGAR_PATH_MAX]; /* path to where libsigar.so lives */ int aix_version; + int thrusage; sigar_cache_t *diskmap; };