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