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