< prev index next >

src/hotspot/os/linux/os_perf_linux.cpp

Print this page

        

@@ -204,10 +204,17 @@
 
 #ifndef _SCANFMT_
 #  define _SCANFMT_
 #endif
 
+
+struct CPUPerfTicks {
+  uint64_t  used;
+  uint64_t  usedKernel;
+  uint64_t  total;
+};
+
 typedef enum {
   CPU_LOAD_VM_ONLY,
   CPU_LOAD_GLOBAL,
 } CpuLoadTarget;
 

@@ -218,12 +225,12 @@
   BAREMETAL
 };
 
 struct CPUPerfCounters {
   int   nProcs;
-  os::Linux::CPUPerfTicks jvmTicks;
-  os::Linux::CPUPerfTicks* cpus;
+  CPUPerfTicks jvmTicks;
+  CPUPerfTicks* cpus;
 };
 
 static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target);
 
 /** reads /proc/<pid>/stat data, with some checks and some skips.

@@ -278,10 +285,84 @@
     }
   }
   return f;
 }
 
+static void
+next_line(FILE *f) {
+  int c;
+  do {
+    c = fgetc(f);
+  } while (c != '\n' && c != EOF);
+}
+
+/**
+ * Return the total number of ticks since the system was booted.
+ * If the usedTicks parameter is not NULL, it will be filled with
+ * the number of ticks spent on actual processes (user, system or
+ * nice processes) since system boot. Note that this is the total number
+ * of "executed" ticks on _all_ CPU:s, that is on a n-way system it is
+ * n times the number of ticks that has passed in clock time.
+ *
+ * Returns a negative value if the reading of the ticks failed.
+ */
+static OSReturn get_total_ticks(int which_logical_cpu, CPUPerfTicks* pticks) {
+  FILE*         fh;
+  uint64_t      userTicks, niceTicks, systemTicks, idleTicks;
+  uint64_t      iowTicks = 0, irqTicks = 0, sirqTicks= 0;
+  int           logical_cpu = -1;
+  const int     expected_assign_count = (-1 == which_logical_cpu) ? 4 : 5;
+  int           n;
+
+  if ((fh = open_statfile()) == NULL) {
+    return OS_ERR;
+  }
+  if (-1 == which_logical_cpu) {
+    n = fscanf(fh, "cpu " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " "
+            UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT,
+            &userTicks, &niceTicks, &systemTicks, &idleTicks,
+            &iowTicks, &irqTicks, &sirqTicks);
+  } else {
+    // Move to next line
+    next_line(fh);
+
+    // find the line for requested cpu faster to just iterate linefeeds?
+    for (int i = 0; i < which_logical_cpu; i++) {
+      next_line(fh);
+    }
+
+    n = fscanf(fh, "cpu%u " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " "
+               UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT,
+               &logical_cpu, &userTicks, &niceTicks,
+               &systemTicks, &idleTicks, &iowTicks, &irqTicks, &sirqTicks);
+  }
+
+  fclose(fh);
+  if (n < expected_assign_count || logical_cpu != which_logical_cpu) {
+#ifdef DEBUG_LINUX_PROC_STAT
+    vm_fprintf(stderr, "[stat] read failed");
+#endif
+    return OS_ERR;
+  }
+
+#ifdef DEBUG_LINUX_PROC_STAT
+  vm_fprintf(stderr, "[stat] read "
+          UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " "
+          UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " \n",
+          userTicks, niceTicks, systemTicks, idleTicks,
+          iowTicks, irqTicks, sirqTicks);
+#endif
+
+  pticks->used       = userTicks + niceTicks;
+  pticks->usedKernel = systemTicks + irqTicks + sirqTicks;
+  pticks->total      = userTicks + niceTicks + systemTicks + idleTicks +
+                       iowTicks + irqTicks + sirqTicks;
+
+  return OS_OK;
+}
+
+
 static int get_systemtype(void) {
   static int procEntriesType = UNDETECTED;
   DIR *taskDir;
 
   if (procEntriesType != UNDETECTED) {

@@ -308,11 +389,11 @@
 
 /**
  * Return the number of ticks spent in any of the processes belonging
  * to the JVM on any CPU.
  */
-static OSReturn get_jvm_ticks(os::Linux::CPUPerfTicks* pticks) {
+static OSReturn get_jvm_ticks(CPUPerfTicks* pticks) {
   uint64_t userTicks;
   uint64_t systemTicks;
 
   if (get_systemtype() != LINUX26_NPTL) {
     return OS_ERR;

@@ -321,11 +402,11 @@
   if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) != 2) {
     return OS_ERR;
   }
 
   // get the total
-  if (! os::Linux::get_tick_information(pticks, -1)) {
+  if (get_total_ticks(-1, pticks) != OS_OK) {
     return OS_ERR;
   }
 
   pticks->used       = userTicks;
   pticks->usedKernel = systemTicks;

@@ -340,12 +421,12 @@
  *
  * Returns a negative value if there is a problem in determining the CPU load.
  */
 static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target) {
   uint64_t udiff, kdiff, tdiff;
-  os::Linux::CPUPerfTicks* pticks;
-  os::Linux::CPUPerfTicks  tmp;
+  CPUPerfTicks* pticks;
+  CPUPerfTicks  tmp;
   double user_load;
 
   *pkernelLoad = 0.0;
 
   if (target == CPU_LOAD_VM_ONLY) {

@@ -360,11 +441,11 @@
 
   if (target == CPU_LOAD_VM_ONLY) {
     if (get_jvm_ticks(pticks) != OS_OK) {
       return -1.0;
     }
-  } else if (! os::Linux::get_tick_information(pticks, which_logical_cpu)) {
+  } else if (get_total_ticks(which_logical_cpu, pticks) != OS_OK) {
     return -1.0;
   }
 
   // seems like we sometimes end up with less kernel ticks when
   // reading /proc/self/stat a second time, timing issue between cpus?

@@ -501,23 +582,23 @@
   _counters.nProcs = os::active_processor_count();
   _counters.cpus = NULL;
 }
 
 bool CPUPerformanceInterface::CPUPerformance::initialize() {
-  size_t tick_array_size = (_counters.nProcs +1) * sizeof(os::Linux::CPUPerfTicks);
-  _counters.cpus = (os::Linux::CPUPerfTicks*)NEW_C_HEAP_ARRAY(char, tick_array_size, mtInternal);
+  size_t tick_array_size = (_counters.nProcs +1) * sizeof(CPUPerfTicks);
+  _counters.cpus = (CPUPerfTicks*)NEW_C_HEAP_ARRAY(char, tick_array_size, mtInternal);
   if (NULL == _counters.cpus) {
     return false;
   }
   memset(_counters.cpus, 0, tick_array_size);
 
   // For the CPU load total
-  os::Linux::get_tick_information(&_counters.cpus[_counters.nProcs], -1);
+  get_total_ticks(-1, &_counters.cpus[_counters.nProcs]);
 
   // For each CPU
   for (int i = 0; i < _counters.nProcs; i++) {
-    os::Linux::get_tick_information(&_counters.cpus[i], i);
+    get_total_ticks(i, &_counters.cpus[i]);
   }
   // For JVM load
   get_jvm_ticks(&_counters.jvmTicks);
 
   // initialize context switch system
< prev index next >