< prev index next >

src/hotspot/os/linux/os_perf_linux.cpp

Print this page

        

*** 204,213 **** --- 204,220 ---- #ifndef _SCANFMT_ # define _SCANFMT_ #endif + + struct CPUPerfTicks { + uint64_t used; + uint64_t usedKernel; + uint64_t total; + }; + typedef enum { CPU_LOAD_VM_ONLY, CPU_LOAD_GLOBAL, } CpuLoadTarget;
*** 218,229 **** BAREMETAL }; struct CPUPerfCounters { int nProcs; ! os::Linux::CPUPerfTicks jvmTicks; ! os::Linux::CPUPerfTicks* cpus; }; static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target); /** reads /proc/<pid>/stat data, with some checks and some skips. --- 225,236 ---- BAREMETAL }; struct CPUPerfCounters { int nProcs; ! CPUPerfTicks jvmTicks; ! CPUPerfTicks* cpus; }; static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target); /** reads /proc/<pid>/stat data, with some checks and some skips.
*** 278,287 **** --- 285,368 ---- } } return f; } + static void + next_line(FILE *f) { + int c; + do { + c = fgetc(f); + } while (c != '\n' && c != EOF); + } + + /** + * Return the total number of ticks since the system was booted. + * If the usedTicks parameter is not NULL, it will be filled with + * the number of ticks spent on actual processes (user, system or + * nice processes) since system boot. Note that this is the total number + * of "executed" ticks on _all_ CPU:s, that is on a n-way system it is + * n times the number of ticks that has passed in clock time. + * + * Returns a negative value if the reading of the ticks failed. + */ + static OSReturn get_total_ticks(int which_logical_cpu, CPUPerfTicks* pticks) { + FILE* fh; + uint64_t userTicks, niceTicks, systemTicks, idleTicks; + uint64_t iowTicks = 0, irqTicks = 0, sirqTicks= 0; + int logical_cpu = -1; + const int expected_assign_count = (-1 == which_logical_cpu) ? 4 : 5; + int n; + + if ((fh = open_statfile()) == NULL) { + return OS_ERR; + } + if (-1 == which_logical_cpu) { + n = fscanf(fh, "cpu " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " + UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT, + &userTicks, &niceTicks, &systemTicks, &idleTicks, + &iowTicks, &irqTicks, &sirqTicks); + } else { + // Move to next line + next_line(fh); + + // find the line for requested cpu faster to just iterate linefeeds? + for (int i = 0; i < which_logical_cpu; i++) { + next_line(fh); + } + + n = fscanf(fh, "cpu%u " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " + UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT, + &logical_cpu, &userTicks, &niceTicks, + &systemTicks, &idleTicks, &iowTicks, &irqTicks, &sirqTicks); + } + + fclose(fh); + if (n < expected_assign_count || logical_cpu != which_logical_cpu) { + #ifdef DEBUG_LINUX_PROC_STAT + vm_fprintf(stderr, "[stat] read failed"); + #endif + return OS_ERR; + } + + #ifdef DEBUG_LINUX_PROC_STAT + vm_fprintf(stderr, "[stat] read " + UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " + UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " \n", + userTicks, niceTicks, systemTicks, idleTicks, + iowTicks, irqTicks, sirqTicks); + #endif + + pticks->used = userTicks + niceTicks; + pticks->usedKernel = systemTicks + irqTicks + sirqTicks; + pticks->total = userTicks + niceTicks + systemTicks + idleTicks + + iowTicks + irqTicks + sirqTicks; + + return OS_OK; + } + + static int get_systemtype(void) { static int procEntriesType = UNDETECTED; DIR *taskDir; if (procEntriesType != UNDETECTED) {
*** 308,318 **** /** * Return the number of ticks spent in any of the processes belonging * to the JVM on any CPU. */ ! static OSReturn get_jvm_ticks(os::Linux::CPUPerfTicks* pticks) { uint64_t userTicks; uint64_t systemTicks; if (get_systemtype() != LINUX26_NPTL) { return OS_ERR; --- 389,399 ---- /** * Return the number of ticks spent in any of the processes belonging * to the JVM on any CPU. */ ! static OSReturn get_jvm_ticks(CPUPerfTicks* pticks) { uint64_t userTicks; uint64_t systemTicks; if (get_systemtype() != LINUX26_NPTL) { return OS_ERR;
*** 321,331 **** if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) != 2) { return OS_ERR; } // get the total ! if (! os::Linux::get_tick_information(pticks, -1)) { return OS_ERR; } pticks->used = userTicks; pticks->usedKernel = systemTicks; --- 402,412 ---- if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) != 2) { return OS_ERR; } // get the total ! if (get_total_ticks(-1, pticks) != OS_OK) { return OS_ERR; } pticks->used = userTicks; pticks->usedKernel = systemTicks;
*** 340,351 **** * * Returns a negative value if there is a problem in determining the CPU load. */ static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target) { uint64_t udiff, kdiff, tdiff; ! os::Linux::CPUPerfTicks* pticks; ! os::Linux::CPUPerfTicks tmp; double user_load; *pkernelLoad = 0.0; if (target == CPU_LOAD_VM_ONLY) { --- 421,432 ---- * * Returns a negative value if there is a problem in determining the CPU load. */ static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target) { uint64_t udiff, kdiff, tdiff; ! CPUPerfTicks* pticks; ! CPUPerfTicks tmp; double user_load; *pkernelLoad = 0.0; if (target == CPU_LOAD_VM_ONLY) {
*** 360,370 **** if (target == CPU_LOAD_VM_ONLY) { if (get_jvm_ticks(pticks) != OS_OK) { return -1.0; } ! } else if (! os::Linux::get_tick_information(pticks, which_logical_cpu)) { return -1.0; } // seems like we sometimes end up with less kernel ticks when // reading /proc/self/stat a second time, timing issue between cpus? --- 441,451 ---- if (target == CPU_LOAD_VM_ONLY) { if (get_jvm_ticks(pticks) != OS_OK) { return -1.0; } ! } else if (get_total_ticks(which_logical_cpu, pticks) != OS_OK) { return -1.0; } // seems like we sometimes end up with less kernel ticks when // reading /proc/self/stat a second time, timing issue between cpus?
*** 501,523 **** _counters.nProcs = os::active_processor_count(); _counters.cpus = NULL; } bool CPUPerformanceInterface::CPUPerformance::initialize() { ! size_t tick_array_size = (_counters.nProcs +1) * sizeof(os::Linux::CPUPerfTicks); ! _counters.cpus = (os::Linux::CPUPerfTicks*)NEW_C_HEAP_ARRAY(char, tick_array_size, mtInternal); if (NULL == _counters.cpus) { return false; } memset(_counters.cpus, 0, tick_array_size); // For the CPU load total ! os::Linux::get_tick_information(&_counters.cpus[_counters.nProcs], -1); // For each CPU for (int i = 0; i < _counters.nProcs; i++) { ! os::Linux::get_tick_information(&_counters.cpus[i], i); } // For JVM load get_jvm_ticks(&_counters.jvmTicks); // initialize context switch system --- 582,604 ---- _counters.nProcs = os::active_processor_count(); _counters.cpus = NULL; } bool CPUPerformanceInterface::CPUPerformance::initialize() { ! size_t tick_array_size = (_counters.nProcs +1) * sizeof(CPUPerfTicks); ! _counters.cpus = (CPUPerfTicks*)NEW_C_HEAP_ARRAY(char, tick_array_size, mtInternal); if (NULL == _counters.cpus) { return false; } memset(_counters.cpus, 0, tick_array_size); // For the CPU load total ! get_total_ticks(-1, &_counters.cpus[_counters.nProcs]); // For each CPU for (int i = 0; i < _counters.nProcs; i++) { ! get_total_ticks(i, &_counters.cpus[i]); } // For JVM load get_jvm_ticks(&_counters.jvmTicks); // initialize context switch system
< prev index next >