< prev index next >

src/hotspot/os/aix/os_perf_aix.cpp

Print this page




 256         n = vsscanf(tmp, fmt, args);
 257       }
 258     }
 259   }
 260 
 261   fclose(f);
 262 
 263   return n;
 264 }
 265 
 266 static int SCANF_ARGS(2, 3) read_statdata(const char* procfile, _SCANFMT_ const char* fmt, ...) {
 267   int   n;
 268   va_list args;
 269 
 270   va_start(args, fmt);
 271   n = vread_statdata(procfile, fmt, args);
 272   va_end(args);
 273   return n;
 274 }
 275 




















 276 /**
 277  * on Linux we got the ticks related information from /proc/stat
 278  * this does not work on AIX, libperfstat might be an alternative






 279  */
 280 static OSReturn get_total_ticks(int which_logical_cpu, CPUPerfTicks* pticks) {
 281   return OS_ERR;








































































 282 }
 283 
 284 /** read user and system ticks from a named procfile, assumed to be in 'stat' format then. */
 285 static int read_ticks(const char* procfile, uint64_t* userTicks, uint64_t* systemTicks) {
 286   return read_statdata(procfile, "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " UINT64_FORMAT " " UINT64_FORMAT,
 287     userTicks, systemTicks);
 288 }
 289 
 290 /**
 291  * Return the number of ticks spent in any of the processes belonging
 292  * to the JVM on any CPU.
 293  */
 294 static OSReturn get_jvm_ticks(CPUPerfTicks* pticks) {
 295   return OS_ERR;



















 296 }
 297 
 298 /**
 299  * Return the load of the CPU as a double. 1.0 means the CPU process uses all
 300  * available time for user or system processes, 0.0 means the CPU uses all time
 301  * being idle.
 302  *
 303  * Returns a negative value if there is a problem in determining the CPU load.
 304  */
 305 static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target) {
 306   uint64_t udiff, kdiff, tdiff;
 307   CPUPerfTicks* pticks;
 308   CPUPerfTicks  tmp;
 309   double user_load;
 310 
 311   *pkernelLoad = 0.0;
 312 
 313   if (target == CPU_LOAD_VM_ONLY) {
 314     pticks = &counters->jvmTicks;
 315   } else if (-1 == which_logical_cpu) {


 339   udiff = pticks->used - tmp.used;
 340 
 341   if (tdiff == 0) {
 342     return 0.0;
 343   } else if (tdiff < (udiff + kdiff)) {
 344     tdiff = udiff + kdiff;
 345   }
 346   *pkernelLoad = (kdiff / (double)tdiff);
 347   // BUG9044876, normalize return values to sane values
 348   *pkernelLoad = MAX2<double>(*pkernelLoad, 0.0);
 349   *pkernelLoad = MIN2<double>(*pkernelLoad, 1.0);
 350 
 351   user_load = (udiff / (double)tdiff);
 352   user_load = MAX2<double>(user_load, 0.0);
 353   user_load = MIN2<double>(user_load, 1.0);
 354 
 355   return user_load;
 356 }
 357 
 358 static int SCANF_ARGS(1, 2) parse_stat(_SCANFMT_ const char* fmt, ...) {
 359   return OS_ERR;






















 360 }
 361 
 362 static int get_noof_context_switches(uint64_t* switches) {
 363   return parse_stat("ctxt " UINT64_FORMAT "\n", switches);
 364 }
 365 
 366 /** returns boot time in _seconds_ since epoch */
 367 static int get_boot_time(uint64_t* time) {
 368   return parse_stat("btime " UINT64_FORMAT "\n", time);
 369 }
 370 
 371 static int perf_context_switch_rate(double* rate) {
 372   static pthread_mutex_t contextSwitchLock = PTHREAD_MUTEX_INITIALIZER;
 373   static uint64_t      lastTime;
 374   static uint64_t      lastSwitches;
 375   static double        lastRate;
 376 
 377   uint64_t lt = 0;
 378   int res = 0;
 379 




 256         n = vsscanf(tmp, fmt, args);
 257       }
 258     }
 259   }
 260 
 261   fclose(f);
 262 
 263   return n;
 264 }
 265 
 266 static int SCANF_ARGS(2, 3) read_statdata(const char* procfile, _SCANFMT_ const char* fmt, ...) {
 267   int   n;
 268   va_list args;
 269 
 270   va_start(args, fmt);
 271   n = vread_statdata(procfile, fmt, args);
 272   va_end(args);
 273   return n;
 274 }
 275 
 276 static FILE* open_statfile(void) {
 277   FILE *f;
 278 
 279   if ((f = fopen("/proc/stat", "r")) == NULL) {
 280     static int haveWarned = 0;
 281     if (!haveWarned) {
 282       haveWarned = 1;
 283     }
 284   }
 285   return f;
 286 }
 287 
 288 static void
 289 next_line(FILE *f) {
 290   int c;
 291   do {
 292     c = fgetc(f);
 293   } while (c != '\n' && c != EOF);
 294 }
 295 
 296 /**
 297  * Return the total number of ticks since the system was booted.
 298  * If the usedTicks parameter is not NULL, it will be filled with
 299  * the number of ticks spent on actual processes (user, system or
 300  * nice processes) since system boot. Note that this is the total number
 301  * of "executed" ticks on _all_ CPU:s, that is on a n-way system it is
 302  * n times the number of ticks that has passed in clock time.
 303  *
 304  * Returns a negative value if the reading of the ticks failed.
 305  */
 306 static OSReturn get_total_ticks(int which_logical_cpu, CPUPerfTicks* pticks) {
 307   FILE*         fh;
 308   uint64_t      userTicks, niceTicks, systemTicks, idleTicks;
 309   uint64_t      iowTicks = 0, irqTicks = 0, sirqTicks= 0;
 310   int           logical_cpu = -1;
 311   const int     expected_assign_count = (-1 == which_logical_cpu) ? 4 : 5;
 312   int           n;
 313 
 314   if ((fh = open_statfile()) == NULL) {
 315     return OS_ERR;
 316   }
 317   if (-1 == which_logical_cpu) {
 318     n = fscanf(fh, "cpu " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " "
 319             UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT,
 320             &userTicks, &niceTicks, &systemTicks, &idleTicks,
 321             &iowTicks, &irqTicks, &sirqTicks);
 322   } else {
 323     // Move to next line
 324     next_line(fh);
 325 
 326     // find the line for requested cpu faster to just iterate linefeeds?
 327     for (int i = 0; i < which_logical_cpu; i++) {
 328       next_line(fh);
 329     }
 330 
 331     n = fscanf(fh, "cpu%u " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " "
 332                UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT,
 333                &logical_cpu, &userTicks, &niceTicks,
 334                &systemTicks, &idleTicks, &iowTicks, &irqTicks, &sirqTicks);
 335   }
 336 
 337   fclose(fh);
 338   if (n < expected_assign_count || logical_cpu != which_logical_cpu) {
 339 #ifdef DEBUG_LINUX_PROC_STAT
 340     vm_fprintf(stderr, "[stat] read failed");
 341 #endif
 342     return OS_ERR;
 343   }
 344 
 345 #ifdef DEBUG_LINUX_PROC_STAT
 346   vm_fprintf(stderr, "[stat] read "
 347           UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " "
 348           UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " \n",
 349           userTicks, niceTicks, systemTicks, idleTicks,
 350           iowTicks, irqTicks, sirqTicks);
 351 #endif
 352 
 353   pticks->used       = userTicks + niceTicks;
 354   pticks->usedKernel = systemTicks + irqTicks + sirqTicks;
 355   pticks->total      = userTicks + niceTicks + systemTicks + idleTicks +
 356                        iowTicks + irqTicks + sirqTicks;
 357 
 358   return OS_OK;
 359 }
 360 
 361 
 362 static int get_systemtype(void) {
 363   static int procEntriesType = UNDETECTED;
 364   DIR *taskDir;
 365 
 366   if (procEntriesType != UNDETECTED) {
 367     return procEntriesType;
 368   }
 369 
 370   // Check whether we have a task subdirectory
 371   if ((taskDir = opendir("/proc/self/task")) == NULL) {
 372     procEntriesType = UNDETECTABLE;
 373   } else {
 374     // The task subdirectory exists; we're on a Linux >= 2.6 system
 375     closedir(taskDir);
 376     procEntriesType = LINUX26_NPTL;
 377   }
 378 
 379   return procEntriesType;
 380 }
 381 
 382 /** read user and system ticks from a named procfile, assumed to be in 'stat' format then. */
 383 static int read_ticks(const char* procfile, uint64_t* userTicks, uint64_t* systemTicks) {
 384   return read_statdata(procfile, "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " UINT64_FORMAT " " UINT64_FORMAT,
 385     userTicks, systemTicks);
 386 }
 387 
 388 /**
 389  * Return the number of ticks spent in any of the processes belonging
 390  * to the JVM on any CPU.
 391  */
 392 static OSReturn get_jvm_ticks(CPUPerfTicks* pticks) {
 393   uint64_t userTicks;
 394   uint64_t systemTicks;
 395 
 396   if (get_systemtype() != LINUX26_NPTL) {
 397     return OS_ERR;
 398   }
 399 
 400   if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) != 2) {
 401     return OS_ERR;
 402   }
 403 
 404   // get the total
 405   if (get_total_ticks(-1, pticks) != OS_OK) {
 406     return OS_ERR;
 407   }
 408 
 409   pticks->used       = userTicks;
 410   pticks->usedKernel = systemTicks;
 411 
 412   return OS_OK;
 413 }
 414 
 415 /**
 416  * Return the load of the CPU as a double. 1.0 means the CPU process uses all
 417  * available time for user or system processes, 0.0 means the CPU uses all time
 418  * being idle.
 419  *
 420  * Returns a negative value if there is a problem in determining the CPU load.
 421  */
 422 static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target) {
 423   uint64_t udiff, kdiff, tdiff;
 424   CPUPerfTicks* pticks;
 425   CPUPerfTicks  tmp;
 426   double user_load;
 427 
 428   *pkernelLoad = 0.0;
 429 
 430   if (target == CPU_LOAD_VM_ONLY) {
 431     pticks = &counters->jvmTicks;
 432   } else if (-1 == which_logical_cpu) {


 456   udiff = pticks->used - tmp.used;
 457 
 458   if (tdiff == 0) {
 459     return 0.0;
 460   } else if (tdiff < (udiff + kdiff)) {
 461     tdiff = udiff + kdiff;
 462   }
 463   *pkernelLoad = (kdiff / (double)tdiff);
 464   // BUG9044876, normalize return values to sane values
 465   *pkernelLoad = MAX2<double>(*pkernelLoad, 0.0);
 466   *pkernelLoad = MIN2<double>(*pkernelLoad, 1.0);
 467 
 468   user_load = (udiff / (double)tdiff);
 469   user_load = MAX2<double>(user_load, 0.0);
 470   user_load = MIN2<double>(user_load, 1.0);
 471 
 472   return user_load;
 473 }
 474 
 475 static int SCANF_ARGS(1, 2) parse_stat(_SCANFMT_ const char* fmt, ...) {
 476   FILE *f;
 477   va_list args;
 478 
 479   va_start(args, fmt);
 480 
 481   if ((f = open_statfile()) == NULL) {
 482     va_end(args);
 483     return OS_ERR;
 484   }
 485   for (;;) {
 486     char line[80];
 487     if (fgets(line, sizeof(line), f) != NULL) {
 488       if (vsscanf(line, fmt, args) == 1) {
 489         fclose(f);
 490         va_end(args);
 491         return OS_OK;
 492       }
 493     } else {
 494         fclose(f);
 495         va_end(args);
 496         return OS_ERR;
 497     }
 498   }
 499 }
 500 
 501 static int get_noof_context_switches(uint64_t* switches) {
 502   return parse_stat("ctxt " UINT64_FORMAT "\n", switches);
 503 }
 504 
 505 /** returns boot time in _seconds_ since epoch */
 506 static int get_boot_time(uint64_t* time) {
 507   return parse_stat("btime " UINT64_FORMAT "\n", time);
 508 }
 509 
 510 static int perf_context_switch_rate(double* rate) {
 511   static pthread_mutex_t contextSwitchLock = PTHREAD_MUTEX_INITIALIZER;
 512   static uint64_t      lastTime;
 513   static uint64_t      lastSwitches;
 514   static double        lastRate;
 515 
 516   uint64_t lt = 0;
 517   int res = 0;
 518 


< prev index next >