/* * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, IBM Corp. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
len = fread(&psinfo, 1, sizeof(psinfo_t), fp); return len == sizeof(psinfo_t);
}
/** * Get and set ticks for the specified lcpu
*/ static OSReturn get_lcpu_ticks(perfstat_id_t* lcpu_name, cpu_tick_store_t* pticks) {
perfstat_cpu_t lcpu_stats;
/** * Calculate the current system load from current ticks using previous ticks as a starting point.
*/ staticvoid calculate_updated_load(cpu_tick_store_t* update, cpu_tick_store_t* prev, double* load) {
cpu_tick_store_t diff;
// If perfstat_cpu does not return the expected number of names, signal error to caller if (ncpus != libperfstat::perfstat_cpu(&name_holder, all_lcpu_stats, sizeof(perfstat_cpu_t), ncpus)) { returnfalse;
}
for (int n = 0; n < ncpus; n++) {
strncpy(lcpu_names[n].name, all_lcpu_stats[n].name, IDENTIFIER_LENGTH);
}
class CPUPerformanceInterface::CPUPerformance : public CHeapObj<mtInternal> { private: int _ncpus;
perfstat_id_t* _lcpu_names;
cpu_tick_store_t* _prev_ticks;
int cpu_load(int which_logical_cpu, double* cpu_load); int context_switch_rate(double* rate); int cpu_load_total_process(double* cpu_load); int cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad);
};
_prev_ticks = NEW_C_HEAP_ARRAY(cpu_tick_store_t, _ncpus, mtInternal); // Set all prev-tick values to 0
memset(_prev_ticks, 0, _ncpus*sizeof(cpu_tick_store_t));
if (!populate_lcpu_names(_ncpus, _lcpu_names)) { returnfalse;
}
returntrue;
}
CPUPerformanceInterface::CPUPerformance::~CPUPerformance() { if (_lcpu_names) {
FREE_C_HEAP_ARRAY(perfstat_id_t, _lcpu_names);
} if (_prev_ticks) {
FREE_C_HEAP_ARRAY(cpu_tick_store_t, _prev_ticks);
}
}
/** * Get CPU load for all processes on specified logical CPU.
*/ int CPUPerformanceInterface::CPUPerformance::cpu_load(int lcpu_number, double* lcpu_load) {
cpu_tick_store_t ticks;
assert(lcpu_load != NULL, "NULL pointer passed to cpu_load");
assert(lcpu_number < _ncpus, "Invalid lcpu passed to cpu_load");
/** * Get CPU load for all processes on all CPUs.
*/ int CPUPerformanceInterface::CPUPerformance::cpu_load_total_process(double* total_load) {
cpu_tick_store_t total_ticks;
cpu_tick_store_t prev_total_ticks;
assert(total_load != NULL, "NULL pointer passed to cpu_load_total_process");
/** * Get CPU load for all CPUs. * * Set values for: * - pjvmUserLoad: CPU load due to jvm process in user mode. Jvm process assumed to be self process * - pjvmKernelLoad: CPU load due to jvm process in kernel mode. Jvm process assumed to be self process * - psystemTotalLoad: Total CPU load from all process on all logical CPUs * * Note: If any of the above loads cannot be calculated, this procedure returns OS_ERR and any load that could not be calculated is set to -1 *
*/ int CPUPerformanceInterface::CPUPerformance::cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad) { double u, k, t;
int retval = OS_OK; if (get_jvm_load(&u, &k) == OS_ERR || cpu_load_total_process(&t) == OS_ERR) {
retval = OS_ERR;
}
if (pjvmUserLoad) {
*pjvmUserLoad = u;
} if (pjvmKernelLoad) {
*pjvmKernelLoad = k;
} if (psystemTotalLoad) {
*psystemTotalLoad = t;
}
return retval;
}
int CPUPerformanceInterface::CPUPerformance::context_switch_rate(double* rate) { return perf_context_switch_rate(rate);
}
int SystemProcessInterface::SystemProcesses::system_processes(SystemProcess** system_processes, int* nprocs) const {
ResourceMark rm;
perfstat_process_t* proc_stats;
SystemProcess* head;
perfstat_id_t name_holder; int records_allocated = 0;
assert(nprocs != NULL, "system_processes counter pointers is NULL!");
head = NULL;
*nprocs = 0;
strncpy(name_holder.name, "", IDENTIFIER_LENGTH);
// calling perfstat_<subsystem>(NULL, NULL, _, 0) returns number of available records
*nprocs = libperfstat::perfstat_process(NULL, NULL, sizeof(perfstat_process_t), 0); if(*nprocs < 1) { // expect at least 1 process return OS_ERR;
}
// populate stats && set the actual number of procs that have been populated // should never be higher than requested, but may be lower due to process death
*nprocs = libperfstat::perfstat_process(&name_holder, proc_stats, sizeof(perfstat_process_t), records_allocated);
for (int n = 0; n < *nprocs; n++) {
psinfo_t psinfo; // Note: SystemProcess with free these in its dtor. char* name = NEW_C_HEAP_ARRAY(char, IDENTIFIER_LENGTH, mtInternal); char* exe_name = NEW_C_HEAP_ARRAY(char, PRFNSZ, mtInternal); char* cmd_line = NEW_C_HEAP_ARRAY(char, PRARGSZ, mtInternal);
// create a new SystemProcess with next pointing to current head.
SystemProcess* sp = new SystemProcess(proc_stats[n].pid,
name,
exe_name,
cmd_line,
head); // update head.
head = sp;
}
// calling perfstat_<subsystem>(NULL, NULL, _, 0) returns number of available records if ((n_records = libperfstat::perfstat_netinterface(NULL, NULL, sizeof(perfstat_netinterface_t), 0)) < 0) { return OS_ERR;
}
// check for error if (n_records < 0) {
FREE_C_HEAP_ARRAY(perfstat_netinterface_t, net_stats); return OS_ERR;
}
for (int i = 0; i < n_records; i++) { // Create new Network interface *with current head as next node* // Note: NetworkInterface makes copies of these string values into RA memory // this means: // (1) we are free to clean our values upon exiting this proc // (2) we avoid using RA-alloced memory here (ie. do not use NEW_RESOURCE_ARRAY)
NetworkInterface* new_interface = new NetworkInterface(net_stats[i].name,
net_stats[i].ibytes,
net_stats[i].obytes,
*network_interfaces);
*network_interfaces = new_interface;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.