Path: blob/master/src/hotspot/os/aix/libperfstat_aix.cpp
40930 views
/*1* Copyright (c) 2012, 2018 SAP SE. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "libperfstat_aix.hpp"25#include "misc_aix.hpp"2627#include <dlfcn.h>2829// Handle to the libperfstat.30static void* g_libhandle = NULL;3132typedef int (*fun_perfstat_cpu_total_t) (perfstat_id_t *name, PERFSTAT_CPU_TOTAL_T_LATEST* userbuff,33int sizeof_userbuff, int desired_number);3435typedef int (*fun_perfstat_memory_total_t) (perfstat_id_t *name, perfstat_memory_total_t* userbuff,36int sizeof_userbuff, int desired_number);3738typedef int (*fun_perfstat_partition_total_t) (perfstat_id_t *name,39PERFSTAT_PARTITON_TOTAL_T_LATEST* userbuff, int sizeof_userbuff,40int desired_number);4142typedef int (*fun_perfstat_wpar_total_t) (perfstat_id_wpar_t *name,43PERFSTAT_WPAR_TOTAL_T_LATEST* userbuff, int sizeof_userbuff,44int desired_number);4546typedef void (*fun_perfstat_reset_t) ();4748typedef cid_t (*fun_wpar_getcid_t) ();4950static fun_perfstat_cpu_total_t g_fun_perfstat_cpu_total = NULL;51static fun_perfstat_memory_total_t g_fun_perfstat_memory_total = NULL;52static fun_perfstat_partition_total_t g_fun_perfstat_partition_total = NULL;53static fun_perfstat_wpar_total_t g_fun_perfstat_wpar_total = NULL;54static fun_perfstat_reset_t g_fun_perfstat_reset = NULL;55static fun_wpar_getcid_t g_fun_wpar_getcid = NULL;5657bool libperfstat::init() {5859// Dynamically load the libperfstat porting library.60g_libhandle = dlopen("/usr/lib/libperfstat.a(shr_64.o)", RTLD_MEMBER | RTLD_NOW);61if (!g_libhandle) {62trcVerbose("Cannot load libperfstat.a (dlerror: %s)", dlerror());63return false;64}6566// Resolve function pointers6768#define RESOLVE_FUN_NO_ERROR(name) \69g_fun_##name = (fun_##name##_t) dlsym(g_libhandle, #name);7071#define RESOLVE_FUN(name) \72RESOLVE_FUN_NO_ERROR(name) \73if (!g_fun_##name) { \74trcVerbose("Cannot resolve " #name "() from libperfstat.a\n" \75" (dlerror: %s)", dlerror()); \76return false; \77}7879// These functions may or may not be there depending on the OS release.80RESOLVE_FUN_NO_ERROR(perfstat_partition_total);81RESOLVE_FUN_NO_ERROR(perfstat_wpar_total);82RESOLVE_FUN_NO_ERROR(wpar_getcid);8384// These functions are required for every release.85RESOLVE_FUN(perfstat_cpu_total);86RESOLVE_FUN(perfstat_memory_total);87RESOLVE_FUN(perfstat_reset);8889trcVerbose("libperfstat loaded.");9091return true;92}9394void libperfstat::cleanup() {9596if (g_libhandle) {97dlclose(g_libhandle);98g_libhandle = NULL;99}100101g_fun_perfstat_cpu_total = NULL;102g_fun_perfstat_memory_total = NULL;103g_fun_perfstat_partition_total = NULL;104g_fun_perfstat_wpar_total = NULL;105g_fun_perfstat_reset = NULL;106g_fun_wpar_getcid = NULL;107108}109110int libperfstat::perfstat_memory_total(perfstat_id_t *name,111perfstat_memory_total_t* userbuff,112int sizeof_userbuff, int desired_number) {113if (g_fun_perfstat_memory_total == NULL) {114return -1;115}116return g_fun_perfstat_memory_total(name, userbuff, sizeof_userbuff, desired_number);117}118119int libperfstat::perfstat_cpu_total(perfstat_id_t *name, PERFSTAT_CPU_TOTAL_T_LATEST* userbuff,120int sizeof_userbuff, int desired_number) {121if (g_fun_perfstat_cpu_total == NULL) {122return -1;123}124return g_fun_perfstat_cpu_total(name, userbuff, sizeof_userbuff, desired_number);125}126127int libperfstat::perfstat_partition_total(perfstat_id_t *name, PERFSTAT_PARTITON_TOTAL_T_LATEST* userbuff,128int sizeof_userbuff, int desired_number) {129if (g_fun_perfstat_partition_total == NULL) {130return -1;131}132return g_fun_perfstat_partition_total(name, userbuff, sizeof_userbuff, desired_number);133}134135int libperfstat::perfstat_wpar_total(perfstat_id_wpar_t *name, PERFSTAT_WPAR_TOTAL_T_LATEST* userbuff,136int sizeof_userbuff, int desired_number) {137if (g_fun_perfstat_wpar_total == NULL) {138return -1;139}140return g_fun_perfstat_wpar_total(name, userbuff, sizeof_userbuff, desired_number);141}142143void libperfstat::perfstat_reset() {144if (g_fun_perfstat_reset != NULL) {145g_fun_perfstat_reset();146}147}148149cid_t libperfstat::wpar_getcid() {150if (g_fun_wpar_getcid == NULL) {151return (cid_t) -1;152}153return g_fun_wpar_getcid();154}155156157//////////////////// convenience functions, release-independent /////////////////////////////158159160// Retrieve global cpu information.161bool libperfstat::get_cpuinfo(cpuinfo_t* pci) {162163assert(pci, "get_cpuinfo: invalid parameter");164memset(pci, 0, sizeof(cpuinfo_t));165166PERFSTAT_CPU_TOTAL_T_LATEST psct;167memset (&psct, '\0', sizeof(psct));168169if (-1 == libperfstat::perfstat_cpu_total(NULL, &psct, sizeof(PERFSTAT_CPU_TOTAL_T_LATEST), 1)) {170if (-1 == libperfstat::perfstat_cpu_total(NULL, &psct, sizeof(perfstat_cpu_total_t_71), 1)) {171if (-1 == libperfstat::perfstat_cpu_total(NULL, &psct, sizeof(perfstat_cpu_total_t_61), 1)) {172if (-1 == libperfstat::perfstat_cpu_total(NULL, &psct, sizeof(perfstat_cpu_total_t_53), 1)) {173trcVerbose("perfstat_cpu_total() failed (errno=%d)", errno);174return false;175}176}177}178}179180// Global cpu information.181strcpy(pci->description, psct.description);182pci->processorHZ = psct.processorHZ;183pci->ncpus = psct.ncpus;184for (int i = 0; i < 3; i++) {185pci->loadavg[i] = (double) psct.loadavg[i] / (1 << SBITS);186}187188pci->user_clock_ticks = psct.user;189pci->sys_clock_ticks = psct.sys;190pci->idle_clock_ticks = psct.idle;191pci->wait_clock_ticks = psct.wait;192193return true;194}195196// Retrieve partition information.197bool libperfstat::get_partitioninfo(partitioninfo_t* ppi) {198199assert(ppi, "get_partitioninfo: invalid parameter");200memset(ppi, 0, sizeof(partitioninfo_t));201202PERFSTAT_PARTITON_TOTAL_T_LATEST pspt;203memset(&pspt, '\0', sizeof(pspt));204205bool ame_details = true;206207if (-1 == libperfstat::perfstat_partition_total(NULL, &pspt, sizeof(PERFSTAT_PARTITON_TOTAL_T_LATEST), 1)) {208if (-1 == libperfstat::perfstat_partition_total(NULL, &pspt, sizeof(perfstat_partition_total_t_71), 1)) {209ame_details = false;210if (-1 == libperfstat::perfstat_partition_total(NULL, &pspt, sizeof(perfstat_partition_total_t_61), 1)) {211if (-1 == libperfstat::perfstat_partition_total(NULL, &pspt, sizeof(perfstat_partition_total_t_53), 1)) {212if (-1 == libperfstat::perfstat_partition_total(NULL, &pspt, sizeof(perfstat_partition_total_t_53_5), 1)) {213trcVerbose("perfstat_partition_total() failed (errno=%d)", errno);214return false;215}216}217}218}219}220221// partition type info222ppi->shared_enabled = pspt.type.b.shared_enabled;223ppi->smt_capable = pspt.type.b.smt_capable;224ppi->smt_enabled = pspt.type.b.smt_enabled;225ppi->lpar_capable = pspt.type.b.lpar_capable;226ppi->lpar_enabled = pspt.type.b.lpar_enabled;227ppi->dlpar_capable = pspt.type.b.dlpar_capable;228ppi->capped = pspt.type.b.capped;229ppi->kernel_is_64 = pspt.type.b.kernel_is_64;230ppi->pool_util_authority = pspt.type.b.pool_util_authority;231ppi->donate_capable = pspt.type.b.donate_capable;232ppi->donate_enabled = pspt.type.b.donate_enabled;233ppi->ams_capable = pspt.type.b.ams_capable;234ppi->ams_enabled = pspt.type.b.ams_enabled;235ppi->power_save = pspt.type.b.power_save;236ppi->ame_enabled = pspt.type.b.ame_enabled;237238// partition total info239ppi->online_cpus = pspt.online_cpus;240ppi->entitled_proc_capacity = pspt.entitled_proc_capacity;241ppi->var_proc_capacity_weight = pspt.var_proc_capacity_weight;242ppi->phys_cpus_pool = pspt.phys_cpus_pool;243ppi->pool_id = pspt.pool_id;244ppi->entitled_pool_capacity = pspt.entitled_pool_capacity;245strcpy(ppi->name, pspt.name);246247// Added values to ppi that we need for later computation of cpu utilization248// ( pool authorization needed for pool_idle_time ??? )249ppi->timebase_last = pspt.timebase_last;250ppi->pool_idle_time = pspt.pool_idle_time;251ppi->pcpu_tics_user = pspt.puser;252ppi->pcpu_tics_sys = pspt.psys;253ppi->pcpu_tics_idle = pspt.pidle;254ppi->pcpu_tics_wait = pspt.pwait;255256// Additional AME information.257if (ame_details) {258ppi->true_memory = pspt.true_memory * 4096;259ppi->expanded_memory = pspt.expanded_memory * 4096;260ppi->target_memexp_factr = pspt.target_memexp_factr;261ppi->current_memexp_factr = pspt.current_memexp_factr;262ppi->cmcs_total_time = pspt.cmcs_total_time;263}264265return true;266}267268// Retrieve wpar information.269bool libperfstat::get_wparinfo(wparinfo_t* pwi) {270271assert(pwi, "get_wparinfo: invalid parameter");272memset(pwi, 0, sizeof(wparinfo_t));273274if (libperfstat::wpar_getcid() <= 0) {275return false;276}277278PERFSTAT_WPAR_TOTAL_T_LATEST pswt;279memset (&pswt, '\0', sizeof(pswt));280281if (-1 == libperfstat::perfstat_wpar_total(NULL, &pswt, sizeof(PERFSTAT_WPAR_TOTAL_T_LATEST), 1)) {282if (-1 == libperfstat::perfstat_wpar_total(NULL, &pswt, sizeof(perfstat_wpar_total_t_61), 1)) {283trcVerbose("perfstat_wpar_total() failed (errno=%d)", errno);284return false;285}286}287288// WPAR type info.289pwi->app_wpar = pswt.type.b.app_wpar;290pwi->cpu_rset = pswt.type.b.cpu_rset;291pwi->cpu_xrset = pswt.type.b.cpu_xrset;292pwi->cpu_limits = pswt.type.b.cpu_limits;293pwi->mem_limits = pswt.type.b.mem_limits;294// WPAR total info.295strcpy(pwi->name, pswt.name);296pwi->wpar_id = pswt.wpar_id;297pwi->cpu_limit = pswt.cpu_limit;298pwi->mem_limit = pswt.mem_limit;299300return true;301}302303304