1 /* 2 * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "jvm.h" 27 #include "memory/allocation.inline.hpp" 28 #include "os_linux.inline.hpp" 29 #include "runtime/os.hpp" 30 #include "runtime/os_perf.hpp" 31 32 #ifdef TARGET_ARCH_x86 33 # include "vm_version_ext_x86.hpp" 34 #endif 35 #ifdef TARGET_ARCH_sparc 36 # include "vm_version_ext_sparc.hpp" 37 #endif 38 #ifdef TARGET_ARCH_zero 39 # include "vm_version_ext_zero.hpp" 40 #endif 41 #ifdef TARGET_ARCH_arm 42 # include "vm_version_ext_arm.hpp" 43 #endif 44 #ifdef TARGET_ARCH_ppc 45 # include "vm_version_ext_ppc.hpp" 46 #endif 47 #ifdef TARGET_ARCH_aarch64 48 # include "vm_version_ext_aarch64.hpp" 49 #endif 50 51 #include <stdio.h> 52 #include <stdarg.h> 53 #include <unistd.h> 54 #include <errno.h> 55 #include <string.h> 56 #include <sys/resource.h> 57 #include <sys/types.h> 58 #include <sys/stat.h> 59 #include <dirent.h> 60 #include <stdlib.h> 61 #include <dlfcn.h> 62 #include <pthread.h> 63 #include <limits.h> 64 #include <ifaddrs.h> 65 #include <fcntl.h> 66 67 /** 68 /proc/[number]/stat 69 Status information about the process. This is used by ps(1). It is defined in /usr/src/linux/fs/proc/array.c. 70 71 The fields, in order, with their proper scanf(3) format specifiers, are: 72 73 1. pid %d The process id. 74 75 2. comm %s 76 The filename of the executable, in parentheses. This is visible whether or not the executable is swapped out. 77 78 3. state %c 79 One character from the string "RSDZTW" where R is running, S is sleeping in an interruptible wait, D is waiting in uninterruptible disk 80 sleep, Z is zombie, T is traced or stopped (on a signal), and W is paging. 81 82 4. ppid %d 83 The PID of the parent. 84 85 5. pgrp %d 86 The process group ID of the process. 87 88 6. session %d 89 The session ID of the process. 90 91 7. tty_nr %d 92 The tty the process uses. 93 94 8. tpgid %d 95 The process group ID of the process which currently owns the tty that the process is connected to. 96 97 9. flags %lu 98 The flags of the process. The math bit is decimal 4, and the traced bit is decimal 10. 99 100 10. minflt %lu 101 The number of minor faults the process has made which have not required loading a memory page from disk. 102 103 11. cminflt %lu 104 The number of minor faults that the process's waited-for children have made. 105 106 12. majflt %lu 107 The number of major faults the process has made which have required loading a memory page from disk. 108 109 13. cmajflt %lu 110 The number of major faults that the process's waited-for children have made. 111 112 14. utime %lu 113 The number of jiffies that this process has been scheduled in user mode. 114 115 15. stime %lu 116 The number of jiffies that this process has been scheduled in kernel mode. 117 118 16. cutime %ld 119 The number of jiffies that this process's waited-for children have been scheduled in user mode. (See also times(2).) 120 121 17. cstime %ld 122 The number of jiffies that this process' waited-for children have been scheduled in kernel mode. 123 124 18. priority %ld 125 The standard nice value, plus fifteen. The value is never negative in the kernel. 126 127 19. nice %ld 128 The nice value ranges from 19 (nicest) to -19 (not nice to others). 129 130 20. 0 %ld This value is hard coded to 0 as a placeholder for a removed field. 131 132 21. itrealvalue %ld 133 The time in jiffies before the next SIGALRM is sent to the process due to an interval timer. 134 135 22. starttime %lu 136 The time in jiffies the process started after system boot. 137 138 23. vsize %lu 139 Virtual memory size in bytes. 140 141 24. rss %ld 142 Resident Set Size: number of pages the process has in real memory, minus 3 for administrative purposes. This is just the pages which count 143 towards text, data, or stack space. This does not include pages which have not been demand-loaded in, or which are swapped out. 144 145 25. rlim %lu 146 Current limit in bytes on the rss of the process (usually 4294967295 on i386). 147 148 26. startcode %lu 149 The address above which program text can run. 150 151 27. endcode %lu 152 The address below which program text can run. 153 154 28. startstack %lu 155 The address of the start of the stack. 156 157 29. kstkesp %lu 158 The current value of esp (stack pointer), as found in the kernel stack page for the process. 159 160 30. kstkeip %lu 161 The current EIP (instruction pointer). 162 163 31. signal %lu 164 The bitmap of pending signals (usually 0). 165 166 32. blocked %lu 167 The bitmap of blocked signals (usually 0, 2 for shells). 168 169 33. sigignore %lu 170 The bitmap of ignored signals. 171 172 34. sigcatch %lu 173 The bitmap of catched signals. 174 175 35. wchan %lu 176 This is the "channel" in which the process is waiting. It is the address of a system call, and can be looked up in a namelist if you need 177 a textual name. (If you have an up-to-date /etc/psdatabase, then try ps -l to see the WCHAN field in action.) 178 179 36. nswap %lu 180 Number of pages swapped - not maintained. 181 182 37. cnswap %lu 183 Cumulative nswap for child processes. 184 185 38. exit_signal %d 186 Signal to be sent to parent when we die. 187 188 39. processor %d 189 CPU number last executed on. 190 191 192 193 ///// SSCANF FORMAT STRING. Copy and use. 194 195 field: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 196 format: %d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d 197 198 199 */ 200 201 /** 202 * For platforms that have them, when declaring 203 * a printf-style function, 204 * formatSpec is the parameter number (starting at 1) 205 * that is the format argument ("%d pid %s") 206 * params is the parameter number where the actual args to 207 * the format starts. If the args are in a va_list, this 208 * should be 0. 209 */ 210 #ifndef PRINTF_ARGS 211 # define PRINTF_ARGS(formatSpec, params) ATTRIBUTE_PRINTF(formatSpec, params) 212 #endif 213 214 #ifndef SCANF_ARGS 215 # define SCANF_ARGS(formatSpec, params) ATTRIBUTE_SCANF(formatSpec, params) 216 #endif 217 218 #ifndef _PRINTFMT_ 219 # define _PRINTFMT_ 220 #endif 221 222 #ifndef _SCANFMT_ 223 # define _SCANFMT_ 224 #endif 225 226 227 struct CPUPerfTicks { 228 uint64_t used; 229 uint64_t usedKernel; 230 uint64_t total; 231 }; 232 233 typedef enum { 234 CPU_LOAD_VM_ONLY, 235 CPU_LOAD_GLOBAL, 236 } CpuLoadTarget; 237 238 enum { 239 UNDETECTED, 240 UNDETECTABLE, 241 LINUX26_NPTL, 242 BAREMETAL 243 }; 244 245 struct CPUPerfCounters { 246 int nProcs; 247 CPUPerfTicks jvmTicks; 248 CPUPerfTicks* cpus; 249 }; 250 251 static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target); 252 253 /** reads /proc/<pid>/stat data, with some checks and some skips. 254 * Ensure that 'fmt' does _NOT_ contain the first two "%d %s" 255 */ 256 static int SCANF_ARGS(2, 0) vread_statdata(const char* procfile, _SCANFMT_ const char* fmt, va_list args) { 257 FILE*f; 258 int n; 259 char buf[2048]; 260 261 if ((f = fopen(procfile, "r")) == NULL) { 262 return -1; 263 } 264 265 if ((n = fread(buf, 1, sizeof(buf), f)) != -1) { 266 char *tmp; 267 268 buf[n-1] = '\0'; 269 /** skip through pid and exec name. */ 270 if ((tmp = strrchr(buf, ')')) != NULL) { 271 // skip the ')' and the following space 272 // but check that buffer is long enough 273 tmp += 2; 274 if (tmp < buf + n) { 275 n = vsscanf(tmp, fmt, args); 276 } 277 } 278 } 279 280 fclose(f); 281 282 return n; 283 } 284 285 static int SCANF_ARGS(2, 3) read_statdata(const char* procfile, _SCANFMT_ const char* fmt, ...) { 286 int n; 287 va_list args; 288 289 va_start(args, fmt); 290 n = vread_statdata(procfile, fmt, args); 291 va_end(args); 292 return n; 293 } 294 295 static FILE* open_statfile(void) { 296 FILE *f; 297 298 if ((f = fopen("/proc/stat", "r")) == NULL) { 299 static int haveWarned = 0; 300 if (!haveWarned) { 301 haveWarned = 1; 302 } 303 } 304 return f; 305 } 306 307 static void 308 next_line(FILE *f) { 309 int c; 310 do { 311 c = fgetc(f); 312 } while (c != '\n' && c != EOF); 313 } 314 315 /** 316 * Return the total number of ticks since the system was booted. 317 * If the usedTicks parameter is not NULL, it will be filled with 318 * the number of ticks spent on actual processes (user, system or 319 * nice processes) since system boot. Note that this is the total number 320 * of "executed" ticks on _all_ CPU:s, that is on a n-way system it is 321 * n times the number of ticks that has passed in clock time. 322 * 323 * Returns a negative value if the reading of the ticks failed. 324 */ 325 static OSReturn get_total_ticks(int which_logical_cpu, CPUPerfTicks* pticks) { 326 FILE* fh; 327 uint64_t userTicks, niceTicks, systemTicks, idleTicks; 328 uint64_t iowTicks = 0, irqTicks = 0, sirqTicks= 0; 329 int logical_cpu = -1; 330 const int expected_assign_count = (-1 == which_logical_cpu) ? 4 : 5; 331 int n; 332 333 if ((fh = open_statfile()) == NULL) { 334 return OS_ERR; 335 } 336 if (-1 == which_logical_cpu) { 337 n = fscanf(fh, "cpu " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " 338 UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT, 339 &userTicks, &niceTicks, &systemTicks, &idleTicks, 340 &iowTicks, &irqTicks, &sirqTicks); 341 } else { 342 // Move to next line 343 next_line(fh); 344 345 // find the line for requested cpu faster to just iterate linefeeds? 346 for (int i = 0; i < which_logical_cpu; i++) { 347 next_line(fh); 348 } 349 350 n = fscanf(fh, "cpu%u " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " 351 UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT, 352 &logical_cpu, &userTicks, &niceTicks, 353 &systemTicks, &idleTicks, &iowTicks, &irqTicks, &sirqTicks); 354 } 355 356 fclose(fh); 357 if (n < expected_assign_count || logical_cpu != which_logical_cpu) { 358 #ifdef DEBUG_LINUX_PROC_STAT 359 vm_fprintf(stderr, "[stat] read failed"); 360 #endif 361 return OS_ERR; 362 } 363 364 #ifdef DEBUG_LINUX_PROC_STAT 365 vm_fprintf(stderr, "[stat] read " 366 UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " 367 UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " \n", 368 userTicks, niceTicks, systemTicks, idleTicks, 369 iowTicks, irqTicks, sirqTicks); 370 #endif 371 372 pticks->used = userTicks + niceTicks; 373 pticks->usedKernel = systemTicks + irqTicks + sirqTicks; 374 pticks->total = userTicks + niceTicks + systemTicks + idleTicks + 375 iowTicks + irqTicks + sirqTicks; 376 377 return OS_OK; 378 } 379 380 381 static int get_systemtype(void) { 382 static int procEntriesType = UNDETECTED; 383 DIR *taskDir; 384 385 if (procEntriesType != UNDETECTED) { 386 return procEntriesType; 387 } 388 389 // Check whether we have a task subdirectory 390 if ((taskDir = opendir("/proc/self/task")) == NULL) { 391 procEntriesType = UNDETECTABLE; 392 } else { 393 // The task subdirectory exists; we're on a Linux >= 2.6 system 394 closedir(taskDir); 395 procEntriesType = LINUX26_NPTL; 396 } 397 398 return procEntriesType; 399 } 400 401 /** read user and system ticks from a named procfile, assumed to be in 'stat' format then. */ 402 static int read_ticks(const char* procfile, uint64_t* userTicks, uint64_t* systemTicks) { 403 return read_statdata(procfile, "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " UINT64_FORMAT " " UINT64_FORMAT, 404 userTicks, systemTicks); 405 } 406 407 /** 408 * Return the number of ticks spent in any of the processes belonging 409 * to the JVM on any CPU. 410 */ 411 static OSReturn get_jvm_ticks(CPUPerfTicks* pticks) { 412 uint64_t userTicks; 413 uint64_t systemTicks; 414 415 if (get_systemtype() != LINUX26_NPTL) { 416 return OS_ERR; 417 } 418 419 if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) != 2) { 420 return OS_ERR; 421 } 422 423 // get the total 424 if (get_total_ticks(-1, pticks) != OS_OK) { 425 return OS_ERR; 426 } 427 428 pticks->used = userTicks; 429 pticks->usedKernel = systemTicks; 430 431 return OS_OK; 432 } 433 434 /** 435 * Return the load of the CPU as a double. 1.0 means the CPU process uses all 436 * available time for user or system processes, 0.0 means the CPU uses all time 437 * being idle. 438 * 439 * Returns a negative value if there is a problem in determining the CPU load. 440 */ 441 static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target) { 442 uint64_t udiff, kdiff, tdiff; 443 CPUPerfTicks* pticks; 444 CPUPerfTicks tmp; 445 double user_load; 446 447 *pkernelLoad = 0.0; 448 449 if (target == CPU_LOAD_VM_ONLY) { 450 pticks = &counters->jvmTicks; 451 } else if (-1 == which_logical_cpu) { 452 pticks = &counters->cpus[counters->nProcs]; 453 } else { 454 pticks = &counters->cpus[which_logical_cpu]; 455 } 456 457 tmp = *pticks; 458 459 if (target == CPU_LOAD_VM_ONLY) { 460 if (get_jvm_ticks(pticks) != OS_OK) { 461 return -1.0; 462 } 463 } else if (get_total_ticks(which_logical_cpu, pticks) != OS_OK) { 464 return -1.0; 465 } 466 467 // seems like we sometimes end up with less kernel ticks when 468 // reading /proc/self/stat a second time, timing issue between cpus? 469 if (pticks->usedKernel < tmp.usedKernel) { 470 kdiff = 0; 471 } else { 472 kdiff = pticks->usedKernel - tmp.usedKernel; 473 } 474 tdiff = pticks->total - tmp.total; 475 udiff = pticks->used - tmp.used; 476 477 if (tdiff == 0) { 478 return 0.0; 479 } else if (tdiff < (udiff + kdiff)) { 480 tdiff = udiff + kdiff; 481 } 482 *pkernelLoad = (kdiff / (double)tdiff); 483 // BUG9044876, normalize return values to sane values 484 *pkernelLoad = MAX2<double>(*pkernelLoad, 0.0); 485 *pkernelLoad = MIN2<double>(*pkernelLoad, 1.0); 486 487 user_load = (udiff / (double)tdiff); 488 user_load = MAX2<double>(user_load, 0.0); 489 user_load = MIN2<double>(user_load, 1.0); 490 491 return user_load; 492 } 493 494 static int SCANF_ARGS(1, 2) parse_stat(_SCANFMT_ const char* fmt, ...) { 495 FILE *f; 496 va_list args; 497 498 va_start(args, fmt); 499 500 if ((f = open_statfile()) == NULL) { 501 va_end(args); 502 return OS_ERR; 503 } 504 for (;;) { 505 char line[80]; 506 if (fgets(line, sizeof(line), f) != NULL) { 507 if (vsscanf(line, fmt, args) == 1) { 508 fclose(f); 509 va_end(args); 510 return OS_OK; 511 } 512 } else { 513 fclose(f); 514 va_end(args); 515 return OS_ERR; 516 } 517 } 518 } 519 520 static int get_noof_context_switches(uint64_t* switches) { 521 return parse_stat("ctxt " UINT64_FORMAT "\n", switches); 522 } 523 524 /** returns boot time in _seconds_ since epoch */ 525 static int get_boot_time(uint64_t* time) { 526 return parse_stat("btime " UINT64_FORMAT "\n", time); 527 } 528 529 static int perf_context_switch_rate(double* rate) { 530 static pthread_mutex_t contextSwitchLock = PTHREAD_MUTEX_INITIALIZER; 531 static uint64_t lastTime; 532 static uint64_t lastSwitches; 533 static double lastRate; 534 535 uint64_t lt = 0; 536 int res = 0; 537 538 if (lastTime == 0) { 539 uint64_t tmp; 540 if (get_boot_time(&tmp) < 0) { 541 return OS_ERR; 542 } 543 lt = tmp * 1000; 544 } 545 546 res = OS_OK; 547 548 pthread_mutex_lock(&contextSwitchLock); 549 { 550 551 uint64_t sw; 552 s8 t, d; 553 554 if (lastTime == 0) { 555 lastTime = lt; 556 } 557 558 t = os::javaTimeMillis(); 559 d = t - lastTime; 560 561 if (d == 0) { 562 *rate = lastRate; 563 } else if (!get_noof_context_switches(&sw)) { 564 *rate = ( (double)(sw - lastSwitches) / d ) * 1000; 565 lastRate = *rate; 566 lastSwitches = sw; 567 lastTime = t; 568 } else { 569 *rate = 0; 570 res = OS_ERR; 571 } 572 if (*rate <= 0) { 573 *rate = 0; 574 lastRate = 0; 575 } 576 } 577 pthread_mutex_unlock(&contextSwitchLock); 578 579 return res; 580 } 581 582 class CPUPerformanceInterface::CPUPerformance : public CHeapObj<mtInternal> { 583 friend class CPUPerformanceInterface; 584 private: 585 CPUPerfCounters _counters; 586 587 int cpu_load(int which_logical_cpu, double* cpu_load); 588 int context_switch_rate(double* rate); 589 int cpu_load_total_process(double* cpu_load); 590 int cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad); 591 592 public: 593 CPUPerformance(); 594 bool initialize(); 595 ~CPUPerformance(); 596 }; 597 598 CPUPerformanceInterface::CPUPerformance::CPUPerformance() { 599 _counters.nProcs = os::active_processor_count(); 600 _counters.cpus = NULL; 601 } 602 603 bool CPUPerformanceInterface::CPUPerformance::initialize() { 604 size_t tick_array_size = (_counters.nProcs +1) * sizeof(CPUPerfTicks); 605 _counters.cpus = (CPUPerfTicks*)NEW_C_HEAP_ARRAY(char, tick_array_size, mtInternal); 606 if (NULL == _counters.cpus) { 607 return false; 608 } 609 memset(_counters.cpus, 0, tick_array_size); 610 611 // For the CPU load total 612 get_total_ticks(-1, &_counters.cpus[_counters.nProcs]); 613 614 // For each CPU 615 for (int i = 0; i < _counters.nProcs; i++) { 616 get_total_ticks(i, &_counters.cpus[i]); 617 } 618 // For JVM load 619 get_jvm_ticks(&_counters.jvmTicks); 620 621 // initialize context switch system 622 // the double is only for init 623 double init_ctx_switch_rate; 624 perf_context_switch_rate(&init_ctx_switch_rate); 625 626 return true; 627 } 628 629 CPUPerformanceInterface::CPUPerformance::~CPUPerformance() { 630 if (_counters.cpus != NULL) { 631 FREE_C_HEAP_ARRAY(char, _counters.cpus, mtInternal); 632 } 633 } 634 635 int CPUPerformanceInterface::CPUPerformance::cpu_load(int which_logical_cpu, double* cpu_load) { 636 double u, s; 637 u = get_cpu_load(which_logical_cpu, &_counters, &s, CPU_LOAD_GLOBAL); 638 if (u < 0) { 639 *cpu_load = 0.0; 640 return OS_ERR; 641 } 642 // Cap total systemload to 1.0 643 *cpu_load = MIN2<double>((u + s), 1.0); 644 return OS_OK; 645 } 646 647 int CPUPerformanceInterface::CPUPerformance::cpu_load_total_process(double* cpu_load) { 648 double u, s; 649 u = get_cpu_load(-1, &_counters, &s, CPU_LOAD_VM_ONLY); 650 if (u < 0) { 651 *cpu_load = 0.0; 652 return OS_ERR; 653 } 654 *cpu_load = u + s; 655 return OS_OK; 656 } 657 658 int CPUPerformanceInterface::CPUPerformance::cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad) { 659 double u, s, t; 660 661 assert(pjvmUserLoad != NULL, "pjvmUserLoad not inited"); 662 assert(pjvmKernelLoad != NULL, "pjvmKernelLoad not inited"); 663 assert(psystemTotalLoad != NULL, "psystemTotalLoad not inited"); 664 665 u = get_cpu_load(-1, &_counters, &s, CPU_LOAD_VM_ONLY); 666 if (u < 0) { 667 *pjvmUserLoad = 0.0; 668 *pjvmKernelLoad = 0.0; 669 *psystemTotalLoad = 0.0; 670 return OS_ERR; 671 } 672 673 cpu_load(-1, &t); 674 // clamp at user+system and 1.0 675 if (u + s > t) { 676 t = MIN2<double>(u + s, 1.0); 677 } 678 679 *pjvmUserLoad = u; 680 *pjvmKernelLoad = s; 681 *psystemTotalLoad = t; 682 683 return OS_OK; 684 } 685 686 int CPUPerformanceInterface::CPUPerformance::context_switch_rate(double* rate) { 687 return perf_context_switch_rate(rate); 688 } 689 690 CPUPerformanceInterface::CPUPerformanceInterface() { 691 _impl = NULL; 692 } 693 694 bool CPUPerformanceInterface::initialize() { 695 _impl = new CPUPerformanceInterface::CPUPerformance(); 696 return NULL == _impl ? false : _impl->initialize(); 697 } 698 699 CPUPerformanceInterface::~CPUPerformanceInterface() { 700 if (_impl != NULL) { 701 delete _impl; 702 } 703 } 704 705 int CPUPerformanceInterface::cpu_load(int which_logical_cpu, double* cpu_load) const { 706 return _impl->cpu_load(which_logical_cpu, cpu_load); 707 } 708 709 int CPUPerformanceInterface::cpu_load_total_process(double* cpu_load) const { 710 return _impl->cpu_load_total_process(cpu_load); 711 } 712 713 int CPUPerformanceInterface::cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad) const { 714 return _impl->cpu_loads_process(pjvmUserLoad, pjvmKernelLoad, psystemTotalLoad); 715 } 716 717 int CPUPerformanceInterface::context_switch_rate(double* rate) const { 718 return _impl->context_switch_rate(rate); 719 } 720 721 class SystemProcessInterface::SystemProcesses : public CHeapObj<mtInternal> { 722 friend class SystemProcessInterface; 723 private: 724 class ProcessIterator : public CHeapObj<mtInternal> { 725 friend class SystemProcessInterface::SystemProcesses; 726 private: 727 DIR* _dir; 728 struct dirent* _entry; 729 bool _valid; 730 char _exeName[PATH_MAX]; 731 char _exePath[PATH_MAX]; 732 733 ProcessIterator(); 734 ~ProcessIterator(); 735 bool initialize(); 736 737 bool is_valid() const { return _valid; } 738 bool is_valid_entry(struct dirent* entry) const; 739 bool is_dir(const char* name) const; 740 int fsize(const char* name, uint64_t& size) const; 741 742 char* allocate_string(const char* str) const; 743 void get_exe_name(); 744 char* get_exe_path(); 745 char* get_cmdline(); 746 747 int current(SystemProcess* process_info); 748 int next_process(); 749 }; 750 751 ProcessIterator* _iterator; 752 SystemProcesses(); 753 bool initialize(); 754 ~SystemProcesses(); 755 756 //information about system processes 757 int system_processes(SystemProcess** system_processes, int* no_of_sys_processes) const; 758 }; 759 760 bool SystemProcessInterface::SystemProcesses::ProcessIterator::is_dir(const char* name) const { 761 struct stat mystat; 762 int ret_val = 0; 763 764 ret_val = stat(name, &mystat); 765 if (ret_val < 0) { 766 return false; 767 } 768 ret_val = S_ISDIR(mystat.st_mode); 769 return ret_val > 0; 770 } 771 772 int SystemProcessInterface::SystemProcesses::ProcessIterator::fsize(const char* name, uint64_t& size) const { 773 assert(name != NULL, "name pointer is NULL!"); 774 size = 0; 775 struct stat fbuf; 776 777 if (stat(name, &fbuf) < 0) { 778 return OS_ERR; 779 } 780 size = fbuf.st_size; 781 return OS_OK; 782 } 783 784 // if it has a numeric name, is a directory and has a 'stat' file in it 785 bool SystemProcessInterface::SystemProcesses::ProcessIterator::is_valid_entry(struct dirent* entry) const { 786 char buffer[PATH_MAX]; 787 uint64_t size = 0; 788 789 if (atoi(entry->d_name) != 0) { 790 jio_snprintf(buffer, PATH_MAX, "/proc/%s", entry->d_name); 791 buffer[PATH_MAX - 1] = '\0'; 792 793 if (is_dir(buffer)) { 794 jio_snprintf(buffer, PATH_MAX, "/proc/%s/stat", entry->d_name); 795 buffer[PATH_MAX - 1] = '\0'; 796 if (fsize(buffer, size) != OS_ERR) { 797 return true; 798 } 799 } 800 } 801 return false; 802 } 803 804 // get exe-name from /proc/<pid>/stat 805 void SystemProcessInterface::SystemProcesses::ProcessIterator::get_exe_name() { 806 FILE* fp; 807 char buffer[PATH_MAX]; 808 809 jio_snprintf(buffer, PATH_MAX, "/proc/%s/stat", _entry->d_name); 810 buffer[PATH_MAX - 1] = '\0'; 811 if ((fp = fopen(buffer, "r")) != NULL) { 812 if (fgets(buffer, PATH_MAX, fp) != NULL) { 813 char* start, *end; 814 // exe-name is between the first pair of ( and ) 815 start = strchr(buffer, '('); 816 if (start != NULL && start[1] != '\0') { 817 start++; 818 end = strrchr(start, ')'); 819 if (end != NULL) { 820 size_t len; 821 len = MIN2<size_t>(end - start, sizeof(_exeName) - 1); 822 memcpy(_exeName, start, len); 823 _exeName[len] = '\0'; 824 } 825 } 826 } 827 fclose(fp); 828 } 829 } 830 831 // get command line from /proc/<pid>/cmdline 832 char* SystemProcessInterface::SystemProcesses::ProcessIterator::get_cmdline() { 833 FILE* fp; 834 char buffer[PATH_MAX]; 835 char* cmdline = NULL; 836 837 jio_snprintf(buffer, PATH_MAX, "/proc/%s/cmdline", _entry->d_name); 838 buffer[PATH_MAX - 1] = '\0'; 839 if ((fp = fopen(buffer, "r")) != NULL) { 840 size_t size = 0; 841 char dummy; 842 843 // find out how long the file is (stat always returns 0) 844 while (fread(&dummy, 1, 1, fp) == 1) { 845 size++; 846 } 847 if (size > 0) { 848 cmdline = NEW_C_HEAP_ARRAY(char, size + 1, mtInternal); 849 if (cmdline != NULL) { 850 cmdline[0] = '\0'; 851 if (fseek(fp, 0, SEEK_SET) == 0) { 852 if (fread(cmdline, 1, size, fp) == size) { 853 // the file has the arguments separated by '\0', 854 // so we translate '\0' to ' ' 855 for (size_t i = 0; i < size; i++) { 856 if (cmdline[i] == '\0') { 857 cmdline[i] = ' '; 858 } 859 } 860 cmdline[size] = '\0'; 861 } 862 } 863 } 864 } 865 fclose(fp); 866 } 867 return cmdline; 868 } 869 870 // get full path to exe from /proc/<pid>/exe symlink 871 char* SystemProcessInterface::SystemProcesses::ProcessIterator::get_exe_path() { 872 char buffer[PATH_MAX]; 873 874 jio_snprintf(buffer, PATH_MAX, "/proc/%s/exe", _entry->d_name); 875 buffer[PATH_MAX - 1] = '\0'; 876 return realpath(buffer, _exePath); 877 } 878 879 char* SystemProcessInterface::SystemProcesses::ProcessIterator::allocate_string(const char* str) const { 880 if (str != NULL) { 881 size_t len = strlen(str); 882 char* tmp = NEW_C_HEAP_ARRAY(char, len+1, mtInternal); 883 strncpy(tmp, str, len); 884 tmp[len] = '\0'; 885 return tmp; 886 } 887 return NULL; 888 } 889 890 int SystemProcessInterface::SystemProcesses::ProcessIterator::current(SystemProcess* process_info) { 891 if (!is_valid()) { 892 return OS_ERR; 893 } 894 895 process_info->set_pid(atoi(_entry->d_name)); 896 897 get_exe_name(); 898 process_info->set_name(allocate_string(_exeName)); 899 900 if (get_exe_path() != NULL) { 901 process_info->set_path(allocate_string(_exePath)); 902 } 903 904 char* cmdline = NULL; 905 cmdline = get_cmdline(); 906 if (cmdline != NULL) { 907 process_info->set_command_line(allocate_string(cmdline)); 908 FREE_C_HEAP_ARRAY(char, cmdline, mtInternal); 909 } 910 911 return OS_OK; 912 } 913 914 int SystemProcessInterface::SystemProcesses::ProcessIterator::next_process() { 915 if (!is_valid()) { 916 return OS_ERR; 917 } 918 919 do { 920 _entry = os::readdir(_dir); 921 if (_entry == NULL) { 922 // Error or reached end. Could use errno to distinguish those cases. 923 _valid = false; 924 return OS_ERR; 925 } 926 } while(!is_valid_entry(_entry)); 927 928 _valid = true; 929 return OS_OK; 930 } 931 932 SystemProcessInterface::SystemProcesses::ProcessIterator::ProcessIterator() { 933 _dir = NULL; 934 _entry = NULL; 935 _valid = false; 936 } 937 938 bool SystemProcessInterface::SystemProcesses::ProcessIterator::initialize() { 939 _dir = os::opendir("/proc"); 940 _entry = NULL; 941 _valid = true; 942 next_process(); 943 944 return true; 945 } 946 947 SystemProcessInterface::SystemProcesses::ProcessIterator::~ProcessIterator() { 948 if (_dir != NULL) { 949 os::closedir(_dir); 950 } 951 } 952 953 SystemProcessInterface::SystemProcesses::SystemProcesses() { 954 _iterator = NULL; 955 } 956 957 bool SystemProcessInterface::SystemProcesses::initialize() { 958 _iterator = new SystemProcessInterface::SystemProcesses::ProcessIterator(); 959 return NULL == _iterator ? false : _iterator->initialize(); 960 } 961 962 SystemProcessInterface::SystemProcesses::~SystemProcesses() { 963 if (_iterator != NULL) { 964 delete _iterator; 965 } 966 } 967 968 int SystemProcessInterface::SystemProcesses::system_processes(SystemProcess** system_processes, int* no_of_sys_processes) const { 969 assert(system_processes != NULL, "system_processes pointer is NULL!"); 970 assert(no_of_sys_processes != NULL, "system_processes counter pointers is NULL!"); 971 assert(_iterator != NULL, "iterator is NULL!"); 972 973 // initialize pointers 974 *no_of_sys_processes = 0; 975 *system_processes = NULL; 976 977 while (_iterator->is_valid()) { 978 SystemProcess* tmp = new SystemProcess(); 979 _iterator->current(tmp); 980 981 //if already existing head 982 if (*system_processes != NULL) { 983 //move "first to second" 984 tmp->set_next(*system_processes); 985 } 986 // new head 987 *system_processes = tmp; 988 // increment 989 (*no_of_sys_processes)++; 990 // step forward 991 _iterator->next_process(); 992 } 993 return OS_OK; 994 } 995 996 int SystemProcessInterface::system_processes(SystemProcess** system_procs, int* no_of_sys_processes) const { 997 return _impl->system_processes(system_procs, no_of_sys_processes); 998 } 999 1000 SystemProcessInterface::SystemProcessInterface() { 1001 _impl = NULL; 1002 } 1003 1004 bool SystemProcessInterface::initialize() { 1005 _impl = new SystemProcessInterface::SystemProcesses(); 1006 return NULL == _impl ? false : _impl->initialize(); 1007 } 1008 1009 SystemProcessInterface::~SystemProcessInterface() { 1010 if (_impl != NULL) { 1011 delete _impl; 1012 } 1013 } 1014 1015 CPUInformationInterface::CPUInformationInterface() { 1016 _cpu_info = NULL; 1017 } 1018 1019 bool CPUInformationInterface::initialize() { 1020 _cpu_info = new CPUInformation(); 1021 if (NULL == _cpu_info) { 1022 return false; 1023 } 1024 _cpu_info->set_number_of_hardware_threads(VM_Version_Ext::number_of_threads()); 1025 _cpu_info->set_number_of_cores(VM_Version_Ext::number_of_cores()); 1026 _cpu_info->set_number_of_sockets(VM_Version_Ext::number_of_sockets()); 1027 _cpu_info->set_cpu_name(VM_Version_Ext::cpu_name()); 1028 _cpu_info->set_cpu_description(VM_Version_Ext::cpu_description()); 1029 1030 return true; 1031 } 1032 1033 CPUInformationInterface::~CPUInformationInterface() { 1034 if (_cpu_info != NULL) { 1035 if (_cpu_info->cpu_name() != NULL) { 1036 const char* cpu_name = _cpu_info->cpu_name(); 1037 FREE_C_HEAP_ARRAY(char, cpu_name, mtInternal); 1038 _cpu_info->set_cpu_name(NULL); 1039 } 1040 if (_cpu_info->cpu_description() != NULL) { 1041 const char* cpu_desc = _cpu_info->cpu_description(); 1042 FREE_C_HEAP_ARRAY(char, cpu_desc, mtInternal); 1043 _cpu_info->set_cpu_description(NULL); 1044 } 1045 delete _cpu_info; 1046 } 1047 } 1048 1049 int CPUInformationInterface::cpu_information(CPUInformation& cpu_info) { 1050 if (_cpu_info == NULL) { 1051 return OS_ERR; 1052 } 1053 1054 cpu_info = *_cpu_info; // shallow copy assignment 1055 return OS_OK; 1056 } 1057 1058 class NetworkPerformanceInterface::NetworkPerformance : public CHeapObj<mtInternal> { 1059 friend class NetworkPerformanceInterface; 1060 private: 1061 NetworkPerformance(); 1062 NetworkPerformance(const NetworkPerformance& rhs); // no impl 1063 NetworkPerformance& operator=(const NetworkPerformance& rhs); // no impl 1064 bool initialize(); 1065 ~NetworkPerformance(); 1066 int64_t read_counter(const char* iface, const char* counter) const; 1067 int network_utilization(NetworkInterface** network_interfaces) const; 1068 }; 1069 1070 NetworkPerformanceInterface::NetworkPerformance::NetworkPerformance() { 1071 1072 } 1073 1074 bool NetworkPerformanceInterface::NetworkPerformance::initialize() { 1075 return true; 1076 } 1077 1078 NetworkPerformanceInterface::NetworkPerformance::~NetworkPerformance() { 1079 } 1080 1081 int64_t NetworkPerformanceInterface::NetworkPerformance::read_counter(const char* iface, const char* counter) const { 1082 char buf[128]; 1083 1084 snprintf(buf, sizeof(buf), "/sys/class/net/%s/statistics/%s", iface, counter); 1085 1086 int fd = open(buf, O_RDONLY); 1087 if (fd == -1) { 1088 return -1; 1089 } 1090 1091 ssize_t num_bytes = read(fd, buf, sizeof(buf)); 1092 close(fd); 1093 if ((num_bytes == -1) || (num_bytes >= static_cast<ssize_t>(sizeof(buf))) || (num_bytes < 1)) { 1094 return -1; 1095 } 1096 1097 buf[num_bytes] = '\0'; 1098 int64_t value = strtoll(buf, NULL, 10); 1099 1100 return value; 1101 } 1102 1103 int NetworkPerformanceInterface::NetworkPerformance::network_utilization(NetworkInterface** network_interfaces) const 1104 { 1105 ifaddrs* addresses; 1106 ifaddrs* cur_address; 1107 1108 if (getifaddrs(&addresses) != 0) { 1109 return OS_ERR; 1110 } 1111 1112 NetworkInterface* ret = NULL; 1113 for (cur_address = addresses; cur_address != NULL; cur_address = cur_address->ifa_next) { 1114 if ((cur_address->ifa_addr == NULL) || (cur_address->ifa_addr->sa_family != AF_PACKET)) { 1115 continue; 1116 } 1117 1118 int64_t bytes_in = read_counter(cur_address->ifa_name, "rx_bytes"); 1119 int64_t bytes_out = read_counter(cur_address->ifa_name, "tx_bytes"); 1120 1121 NetworkInterface* cur = new NetworkInterface(cur_address->ifa_name, bytes_in, bytes_out, ret); 1122 ret = cur; 1123 } 1124 1125 freeifaddrs(addresses); 1126 *network_interfaces = ret; 1127 1128 return OS_OK; 1129 } 1130 1131 NetworkPerformanceInterface::NetworkPerformanceInterface() { 1132 _impl = NULL; 1133 } 1134 1135 NetworkPerformanceInterface::~NetworkPerformanceInterface() { 1136 if (_impl != NULL) { 1137 delete _impl; 1138 } 1139 } 1140 1141 bool NetworkPerformanceInterface::initialize() { 1142 _impl = new NetworkPerformanceInterface::NetworkPerformance(); 1143 return _impl != NULL && _impl->initialize(); 1144 } 1145 1146 int NetworkPerformanceInterface::network_utilization(NetworkInterface** network_interfaces) const { 1147 return _impl->network_utilization(network_interfaces); 1148 }