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 "iphlp_interface.hpp"
  27 #include "logging/log.hpp"
  28 #include "memory/allocation.inline.hpp"
  29 #include "memory/resourceArea.hpp"
  30 #include "pdh_interface.hpp"
  31 #include "runtime/os_perf.hpp"
  32 #include "runtime/os.hpp"
  33 #include "utilities/globalDefinitions.hpp"
  34 #include "utilities/macros.hpp"
  35 #include CPU_HEADER(vm_version_ext)
  36 #include <math.h>
  37 #include <psapi.h>
  38 #include <TlHelp32.h>
  39 
  40 /*
  41  * Windows provides a vast plethora of performance objects and counters,
  42  * consumption of which is assisted using the Performance Data Helper (PDH) interface.
  43  * We import a selected few api entry points from PDH, see pdh_interface.hpp.
  44  *
  45  * The code located in this file is to a large extent an abstraction over much of the
  46  * plumbing needed to start consuming an object and/or counter of choice.
  47  *
  48  */
  49 
  50  /*
  51  * How to use:
  52  * 1. Create query
  53  * 2. Add counters to the query
  54  * 3. Collect the performance data using the query
  55  * 4. Display the performance data using the counters associated with the query
  56  * 5. Destroy query (counter destruction implied)
  57  */
  58 
  59 /*
  60  * Every PDH artifact, like processor, process, thread, memory, and so forth are
  61  * identified with an index that is always the same irrespective
  62  * of the localized version of the operating system or service pack installed.
  63  * INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
  64  *   http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
  65  *
  66  * To find the correct index for an object or counter, inspect the registry key / value:
  67  * [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Counter]
  68  *
  69  * some common PDH indexes
  70  */
  71 static const DWORD PDH_PROCESSOR_IDX = 238;
  72 static const DWORD PDH_PROCESSOR_TIME_IDX = 6;
  73 static const DWORD PDH_PRIV_PROCESSOR_TIME_IDX = 144;
  74 static const DWORD PDH_PROCESS_IDX = 230;
  75 static const DWORD PDH_ID_PROCESS_IDX = 784;
  76 static const DWORD PDH_CONTEXT_SWITCH_RATE_IDX = 146;
  77 static const DWORD PDH_SYSTEM_IDX = 2;
  78 
  79 /* useful pdh fmt's */
  80 static const char* const OBJECT_COUNTER_FMT = "\\%s\\%s";
  81 static const size_t OBJECT_COUNTER_FMT_LEN = 2;
  82 static const char* const OBJECT_WITH_INSTANCES_COUNTER_FMT = "\\%s(%s)\\%s";
  83 static const size_t OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN = 4;
  84 static const char* const PROCESS_OBJECT_INSTANCE_COUNTER_FMT = "\\%s(%s#%s)\\%s";
  85 static const size_t PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN = 5;
  86 
  87 static const char* process_image_name = NULL; // for example, "java" but could have another image name
  88 static char* pdh_IDProcess_counter_fmt = NULL;   // "\Process(java#%d)\ID Process" */
  89 
  90 // Need to limit how often we update a query to minimize the heisenberg effect.
  91 // (PDH behaves erratically if the counters are queried too often, especially counters that
  92 // store and use values from two consecutive updates, like cpu load.)
  93 static const int min_update_interval_millis = 500;
  94 
  95 /*
  96 * Structs for PDH queries.
  97 */
  98 typedef struct {
  99   HQUERY query;
 100   s8     lastUpdate; // Last time query was updated (current millis).
 101 } UpdateQueryS, *UpdateQueryP;
 102 
 103 
 104 typedef struct {
 105   UpdateQueryS query;
 106   HCOUNTER     counter;
 107   bool         initialized;
 108 } CounterQueryS, *CounterQueryP;
 109 
 110 typedef struct {
 111   UpdateQueryS query;
 112   HCOUNTER*    counters;
 113   int          noOfCounters;
 114   bool         initialized;
 115 } MultiCounterQueryS, *MultiCounterQueryP;
 116 
 117 typedef struct {
 118   MultiCounterQueryP queries;
 119   int                size;
 120   bool               initialized;
 121 } MultiCounterQuerySetS, *MultiCounterQuerySetP;
 122 
 123 typedef struct {
 124   MultiCounterQuerySetS set;
 125   int                   process_index;
 126 } ProcessQueryS, *ProcessQueryP;
 127 
 128 static void pdh_cleanup(HQUERY* const query, HCOUNTER* const counter) {
 129   if (counter != NULL && *counter != NULL) {
 130     PdhDll::PdhRemoveCounter(*counter);
 131     *counter = NULL;
 132   }
 133   if (query != NULL && *query != NULL) {
 134     PdhDll::PdhCloseQuery(*query);
 135     *query = NULL;
 136   }
 137 }
 138 
 139 static CounterQueryP create_counter_query() {
 140   CounterQueryP const query = NEW_C_HEAP_ARRAY(CounterQueryS, 1, mtInternal);
 141   memset(query, 0, sizeof(CounterQueryS));
 142   return query;
 143 }
 144 
 145 static void destroy_counter_query(CounterQueryP query) {
 146   assert(query != NULL, "invariant");
 147   pdh_cleanup(&query->query.query, &query->counter);
 148   FREE_C_HEAP_ARRAY(CounterQueryS, query);
 149 }
 150 
 151 static MultiCounterQueryP create_multi_counter_query() {
 152   MultiCounterQueryP const query = NEW_C_HEAP_ARRAY(MultiCounterQueryS, 1, mtInternal);
 153   memset(query, 0, sizeof(MultiCounterQueryS));
 154   return query;
 155 }
 156 
 157 static void destroy_counter_query(MultiCounterQueryP counter_query) {
 158   if (counter_query != NULL) {
 159     for (int i = 0; i < counter_query->noOfCounters; ++i) {
 160       pdh_cleanup(NULL, &counter_query->counters[i]);
 161     }
 162     FREE_C_HEAP_ARRAY(char, counter_query->counters);
 163     pdh_cleanup(&counter_query->query.query, NULL);
 164     FREE_C_HEAP_ARRAY(MultiCounterQueryS, counter_query);
 165   }
 166 }
 167 
 168 static void destroy_multi_counter_query(MultiCounterQuerySetP counter_query_set) {
 169   for (int i = 0; i < counter_query_set->size; i++) {
 170     for (int j = 0; j < counter_query_set->queries[i].noOfCounters; ++j) {
 171       pdh_cleanup(NULL, &counter_query_set->queries[i].counters[j]);
 172     }
 173     FREE_C_HEAP_ARRAY(char, counter_query_set->queries[i].counters);
 174     pdh_cleanup(&counter_query_set->queries[i].query.query, NULL);
 175   }
 176   FREE_C_HEAP_ARRAY(MultiCounterQueryS, counter_query_set->queries);
 177 }
 178 
 179 static void destroy_counter_query(MultiCounterQuerySetP counter_query_set) {
 180   destroy_multi_counter_query(counter_query_set);
 181   FREE_C_HEAP_ARRAY(MultiCounterQuerySetS, counter_query_set);
 182 }
 183 
 184 static void destroy_counter_query(ProcessQueryP process_query) {
 185   destroy_multi_counter_query(&process_query->set);
 186   FREE_C_HEAP_ARRAY(ProcessQueryS, process_query);
 187 }
 188 
 189 static int open_query(HQUERY* query) {
 190   return PdhDll::PdhOpenQuery(NULL, 0, query);
 191 }
 192 
 193 template <typename QueryP>
 194 static int open_query(QueryP query) {
 195   return open_query(&query->query);
 196 }
 197 
 198 static int allocate_counters(MultiCounterQueryP query, size_t nofCounters) {
 199   assert(query != NULL, "invariant");
 200   assert(!query->initialized, "invariant");
 201   assert(0 == query->noOfCounters, "invariant");
 202   assert(query->counters == NULL, "invariant");
 203   query->counters = (HCOUNTER*)NEW_C_HEAP_ARRAY(char, nofCounters * sizeof(HCOUNTER), mtInternal);
 204   if (query->counters == NULL) {
 205     return OS_ERR;
 206   }
 207   memset(query->counters, 0, nofCounters * sizeof(HCOUNTER));
 208   query->noOfCounters = (int)nofCounters;
 209   return OS_OK;
 210 }
 211 
 212 static int allocate_counters(MultiCounterQuerySetP query_set, size_t nofCounters) {
 213   assert(query_set != NULL, "invariant");
 214   assert(!query_set->initialized, "invariant");
 215   for (int i = 0; i < query_set->size; ++i) {
 216     if (allocate_counters(&query_set->queries[i], nofCounters) != OS_OK) {
 217       return OS_ERR;
 218     }
 219   }
 220   return OS_OK;
 221 }
 222 
 223 static int allocate_counters(ProcessQueryP process_query, size_t nofCounters) {
 224   assert(process_query != NULL, "invariant");
 225   return allocate_counters(&process_query->set, nofCounters);
 226 }
 227 
 228 static void deallocate_counters(MultiCounterQueryP query) {
 229   if (query->counters != NULL) {
 230     FREE_C_HEAP_ARRAY(char, query->counters);
 231     query->counters = NULL;
 232     query->noOfCounters = 0;
 233   }
 234 }
 235 
 236 static OSReturn add_counter(UpdateQueryP query, HCOUNTER* counter, const char* path, bool first_sample_on_init) {
 237   assert(query != NULL, "invariant");
 238   assert(counter != NULL, "invariant");
 239   assert(path != NULL, "invariant");
 240   if (query->query == NULL) {
 241     if (open_query(query) != ERROR_SUCCESS) {
 242       return OS_ERR;
 243     }
 244   }
 245   assert(query->query != NULL, "invariant");
 246   PDH_STATUS status = PdhDll::PdhAddCounter(query->query, path, 0, counter);
 247   if (PDH_CSTATUS_NO_OBJECT == status || PDH_CSTATUS_NO_COUNTER == status) {
 248     return OS_ERR;
 249   }
 250   /*
 251   * According to the MSDN documentation, rate counters must be read twice:
 252   *
 253   * "Obtaining the value of rate counters such as Page faults/sec requires that
 254   *  PdhCollectQueryData be called twice, with a specific time interval between
 255   *  the two calls, before calling PdhGetFormattedCounterValue. Call Sleep to
 256   *  implement the waiting period between the two calls to PdhCollectQueryData."
 257   *
 258   *  Take the first sample here already to allow for the next "real" sample
 259   *  to succeed.
 260   */
 261   if (first_sample_on_init) {
 262     PdhDll::PdhCollectQueryData(query->query);
 263   }
 264   return OS_OK;
 265 }
 266 
 267 template <typename QueryP>
 268 static OSReturn add_counter(QueryP counter_query, HCOUNTER* counter, const char* path, bool first_sample_on_init) {
 269   assert(counter_query != NULL, "invariant");
 270   assert(counter != NULL, "invariant");
 271   assert(path != NULL, "invariant");
 272   return add_counter(&counter_query->query, counter, path, first_sample_on_init);
 273 }
 274 
 275 static OSReturn add_counter(CounterQueryP counter_query, const char* path, bool first_sample_on_init) {
 276   if (add_counter(counter_query, &counter_query->counter, path, first_sample_on_init) != OS_OK) {
 277     // performance counter might be disabled in the registry
 278     return OS_ERR;
 279   }
 280   counter_query->initialized = true;
 281   return OS_OK;
 282 }
 283 
 284 static OSReturn add_process_counter(MultiCounterQueryP query, int slot_index, const char* path, bool first_sample_on_init) {
 285   assert(query != NULL, "invariant");
 286   assert(slot_index < query->noOfCounters, "invariant");
 287   assert(query->counters[slot_index] == NULL, "invariant");
 288   const OSReturn ret = add_counter(query, &query->counters[slot_index], path, first_sample_on_init);
 289   if (OS_OK == ret) {
 290     if (slot_index + 1 == query->noOfCounters) {
 291       query->initialized = true;
 292     }
 293   }
 294   return ret;
 295 }
 296 
 297 static int collect_query_data(UpdateQueryP update_query) {
 298   assert(update_query != NULL, "invariant");
 299   const s8 now = os::javaTimeMillis();
 300   if (now - update_query->lastUpdate > min_update_interval_millis) {
 301     if (PdhDll::PdhCollectQueryData(update_query->query) != ERROR_SUCCESS) {
 302       return OS_ERR;
 303     }
 304     update_query->lastUpdate = now;
 305   }
 306   return OS_OK;
 307 }
 308 
 309 template <typename Query>
 310 static int collect_query_data(Query* counter_query) {
 311   assert(counter_query != NULL, "invariant");
 312   return collect_query_data(&counter_query->query);
 313 }
 314 
 315 static int formatted_counter_value(HCOUNTER counter, DWORD format, PDH_FMT_COUNTERVALUE* const value) {
 316   assert(value != NULL, "invariant");
 317   if (PdhDll::PdhGetFormattedCounterValue(counter, format, NULL, value) != ERROR_SUCCESS) {
 318     return OS_ERR;
 319   }
 320   return OS_OK;
 321 }
 322 
 323 /*
 324 * Working against the Process object and it's related counters is inherently problematic
 325 * when using the PDH API:
 326 *
 327 * Using PDH, a process is not primarily identified by the process id,
 328 * but with a sequential number, for example \Process(java#0), \Process(java#1), ...
 329 * The really bad part is that this list is reset as soon as a process exits:
 330 * If \Process(java#1) exits, \Process(java#3) now becomes \Process(java#2) etc.
 331 *
 332 * The PDH api requires a process identifier to be submitted when registering
 333 * a query, but as soon as the list resets, the query is invalidated (since the name changed).
 334 *
 335 * Solution:
 336 * The #number identifier for a Process query can only decrease after process creation.
 337 *
 338 * We therefore create an array of counter queries for all process object instances
 339 * up to and including ourselves:
 340 *
 341 * Ex. we come in as third process instance (java#2), we then create and register
 342 * queries for the following Process object instances:
 343 * java#0, java#1, java#2
 344 *
 345 * current_query_index_for_process() keeps track of the current "correct" query
 346 * (in order to keep this index valid when the list resets from underneath,
 347 * ensure to call current_query_index_for_process() before every query involving
 348 * Process object instance data).
 349 *
 350 * if unable to query, returns OS_ERR(-1)
 351 */
 352 static int current_query_index_for_process() {
 353   assert(process_image_name != NULL, "invariant");
 354   assert(pdh_IDProcess_counter_fmt != NULL, "invariant");
 355   HQUERY tmpQuery = NULL;
 356   if (open_query(&tmpQuery) != ERROR_SUCCESS) {
 357     return OS_ERR;
 358   }
 359   char counter[512];
 360   HCOUNTER handle_counter = NULL;
 361   // iterate over all instance indexes and try to find our own pid
 362   for (int index = 0; index < max_intx; index++) {
 363     jio_snprintf(counter, sizeof(counter) - 1, pdh_IDProcess_counter_fmt, index);
 364     assert(strlen(counter) < sizeof(counter), "invariant");
 365     if (PdhDll::PdhAddCounter(tmpQuery, counter, 0, &handle_counter) != ERROR_SUCCESS) {
 366       pdh_cleanup(&tmpQuery, &handle_counter);
 367       return OS_ERR;
 368     }
 369     const PDH_STATUS res = PdhDll::PdhCollectQueryData(tmpQuery);
 370     if (res == PDH_INVALID_HANDLE || res == PDH_NO_DATA) {
 371       pdh_cleanup(&tmpQuery, &handle_counter);
 372       return OS_ERR;
 373     } else {
 374       PDH_FMT_COUNTERVALUE counter_value;
 375       formatted_counter_value(handle_counter, PDH_FMT_LONG, &counter_value);
 376       pdh_cleanup(NULL, &handle_counter);
 377       if ((LONG)os::current_process_id() == counter_value.longValue) {
 378         pdh_cleanup(&tmpQuery, NULL);
 379         return index;
 380       }
 381     }
 382   }
 383   pdh_cleanup(&tmpQuery, NULL);
 384   return OS_ERR;
 385 }
 386 
 387 static ProcessQueryP create_process_query() {
 388   const int current_process_idx = current_query_index_for_process();
 389   if (OS_ERR == current_process_idx) {
 390     return NULL;
 391   }
 392   ProcessQueryP const process_query = NEW_C_HEAP_ARRAY(ProcessQueryS, 1, mtInternal);
 393   memset(process_query, 0, sizeof(ProcessQueryS));
 394   process_query->set.queries = NEW_C_HEAP_ARRAY(MultiCounterQueryS, current_process_idx + 1, mtInternal);
 395   memset(process_query->set.queries, 0, sizeof(MultiCounterQueryS) * (current_process_idx + 1));
 396   process_query->process_index = current_process_idx;
 397   process_query->set.size = current_process_idx + 1;
 398   assert(process_query->set.size > process_query->process_index, "invariant");
 399   return process_query;
 400 }
 401 
 402 static MultiCounterQueryP current_process_counter_query(ProcessQueryP process_query) {
 403   assert(process_query != NULL, "invariant");
 404   assert(process_query->process_index < process_query->set.size, "invariant");
 405   return &process_query->set.queries[process_query->process_index];
 406 }
 407 
 408 static void clear_multi_counter(MultiCounterQueryP query) {
 409   for (int i = 0; i < query->noOfCounters; ++i) {
 410     pdh_cleanup(NULL, &query->counters[i]);
 411   }
 412   pdh_cleanup(&query->query.query, NULL);
 413   query->initialized = false;
 414 }
 415 
 416 static int ensure_valid_process_query_index(ProcessQueryP process_query) {
 417   assert(process_query != NULL, "invariant");
 418   const int previous_process_idx = process_query->process_index;
 419   if (previous_process_idx == 0) {
 420     return previous_process_idx;
 421   }
 422   const int current_process_idx = current_query_index_for_process();
 423   if (current_process_idx == previous_process_idx || OS_ERR == current_process_idx ||
 424     current_process_idx >= process_query->set.size) {
 425     return previous_process_idx;
 426   }
 427 
 428   assert(current_process_idx >= 0 && current_process_idx < process_query->set.size, "out of bounds!");
 429   while (current_process_idx < process_query->set.size - 1) {
 430     const int new_size = --process_query->set.size;
 431     clear_multi_counter(&process_query->set.queries[new_size]);
 432   }
 433   assert(current_process_idx < process_query->set.size, "invariant");
 434   process_query->process_index = current_process_idx;
 435   return current_process_idx;
 436 }
 437 
 438 static MultiCounterQueryP current_process_query(ProcessQueryP process_query) {
 439   assert(process_query != NULL, "invariant");
 440   const int current_process_idx = ensure_valid_process_query_index(process_query);
 441   assert(current_process_idx == process_query->process_index, "invariant");
 442   assert(current_process_idx < process_query->set.size, "invariant");
 443   return &process_query->set.queries[current_process_idx];
 444 }
 445 
 446 static int collect_process_query_data(ProcessQueryP process_query) {
 447   assert(process_query != NULL, "invariant");
 448   return collect_query_data(current_process_query(process_query));
 449 }
 450 
 451 static int query_process_counter(ProcessQueryP process_query, int slot_index, DWORD format, PDH_FMT_COUNTERVALUE* const value) {
 452   MultiCounterQueryP const current_query = current_process_counter_query(process_query);
 453   assert(current_query != NULL, "invariant");
 454   assert(slot_index < current_query->noOfCounters, "invariant");
 455   assert(current_query->counters[slot_index] != NULL, "invariant");
 456   return formatted_counter_value(current_query->counters[slot_index], format, value);
 457 }
 458 
 459 /*
 460  * Construct a fully qualified PDH path
 461  *
 462  * @param objectName   a PDH Object string representation(required)
 463  * @param counterName  a PDH Counter string representation(required)
 464  * @param imageName    a process image name string, ex. "java" (opt)
 465  * @param instance     an instance string, ex. "0", "1", ... (opt)
 466  * @return             the fully qualified PDH path.
 467  *
 468  * Caller will need a ResourceMark.
 469  *
 470  * (PdhMakeCounterPath() seems buggy on concatenating instances, hence this function instead)
 471  */
 472 static const char* make_fully_qualified_counter_path(const char* object_name,
 473                                                      const char* counter_name,
 474                                                      const char* image_name = NULL,
 475                                                      const char* instance = NULL) {
 476   assert(object_name != NULL, "invariant");
 477   assert(counter_name != NULL, "invariant");
 478   size_t full_counter_path_len = strlen(object_name) + strlen(counter_name);
 479 
 480   char* full_counter_path;
 481   size_t jio_snprintf_result = 0;
 482   if (image_name) {
 483     /*
 484     * For paths using the "Process" Object.
 485     *
 486     * Examples:
 487     * form:   "\object_name(image_name#instance)\counter_name"
 488     * actual: "\Process(java#2)\ID Process"
 489     */
 490     full_counter_path_len += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
 491     full_counter_path_len += strlen(image_name);
 492     /*
 493     * image_name must be passed together with an associated
 494     * instance "number" ("0", "1", "2", ...).
 495     * This is required in order to create valid "Process" Object paths.
 496     *
 497     * Examples: "\Process(java#0)", \Process(java#1"), ...
 498     */
 499     assert(instance != NULL, "invariant");
 500     full_counter_path_len += strlen(instance);
 501     full_counter_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, full_counter_path_len + 1);
 502     if (full_counter_path == NULL) {
 503       return NULL;
 504     }
 505     jio_snprintf_result = jio_snprintf(full_counter_path,
 506                                        full_counter_path_len + 1,
 507                                        PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
 508                                        object_name,
 509                                        image_name,
 510                                        instance,
 511                                        counter_name);
 512   } else {
 513     if (instance) {
 514       /*
 515       * For paths where the Object has multiple instances.
 516       *
 517       * Examples:
 518       * form:   "\object_name(instance)\counter_name"
 519       * actual: "\Processor(0)\% Privileged Time"
 520       */
 521       full_counter_path_len += strlen(instance);
 522       full_counter_path_len += OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN;
 523     } else {
 524       /*
 525       * For "normal" paths.
 526       *
 527       * Examples:
 528       * form:   "\object_name\counter_name"
 529       * actual: "\Memory\Available Mbytes"
 530       */
 531       full_counter_path_len += OBJECT_COUNTER_FMT_LEN;
 532     }
 533     full_counter_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, full_counter_path_len + 1);
 534     if (full_counter_path == NULL) {
 535       return NULL;
 536     }
 537     if (instance) {
 538       jio_snprintf_result = jio_snprintf(full_counter_path,
 539                                          full_counter_path_len + 1,
 540                                          OBJECT_WITH_INSTANCES_COUNTER_FMT,
 541                                          object_name,
 542                                          instance,
 543                                          counter_name);
 544     } else {
 545       jio_snprintf_result = jio_snprintf(full_counter_path,
 546                                          full_counter_path_len + 1,
 547                                          OBJECT_COUNTER_FMT,
 548                                          object_name,
 549                                          counter_name);
 550     }
 551   }
 552   assert(full_counter_path_len == jio_snprintf_result, "invariant");
 553   return full_counter_path;
 554 }
 555 
 556 static void log_invalid_pdh_index(DWORD index) {
 557   log_warning(os)("Unable to resolve PDH index: (%ld)", index);
 558   log_warning(os)("Please check the registry if this performance object/counter is disabled");
 559 }
 560 
 561 static bool is_valid_pdh_index(DWORD index) {
 562   DWORD dummy = 0;
 563   if (PdhDll::PdhLookupPerfNameByIndex(NULL, index, NULL, &dummy) != PDH_MORE_DATA) {
 564     log_invalid_pdh_index(index);
 565     return false;
 566   }
 567   return true;
 568 }
 569 
 570 /*
 571  * Maps an index to a resource area allocated string for the localized PDH artifact.
 572  *
 573  * Caller will need a ResourceMark.
 574  *
 575  * @param index    the counter index as specified in the registry
 576  * @param ppBuffer pointer to a char*
 577  * @return         OS_OK if successful, OS_ERR on failure.
 578  */
 579 static OSReturn lookup_name_by_index(DWORD index, char** p_string) {
 580   assert(p_string != NULL, "invariant");
 581   if (!is_valid_pdh_index(index)) {
 582     return OS_ERR;
 583   }
 584   // determine size needed
 585   DWORD size = 0;
 586   PDH_STATUS status = PdhDll::PdhLookupPerfNameByIndex(NULL, index, NULL, &size);
 587   assert(status == PDH_MORE_DATA, "invariant");
 588   *p_string = NEW_RESOURCE_ARRAY_RETURN_NULL(char, size);
 589   if (*p_string== NULL) {
 590     return OS_ERR;
 591   }
 592   if (PdhDll::PdhLookupPerfNameByIndex(NULL, index, *p_string, &size) != ERROR_SUCCESS) {
 593     return OS_ERR;
 594   }
 595   if (0 == size || *p_string == NULL) {
 596     return OS_ERR;
 597   }
 598   // windows vista does not null-terminate the string (although the docs says it will)
 599   (*p_string)[size - 1] = '\0';
 600   return OS_OK;
 601 }
 602 
 603 static const char* copy_string_to_c_heap(const char* string) {
 604   assert(string != NULL, "invariant");
 605   const size_t len = strlen(string);
 606   char* const cheap_allocated_string = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
 607   if (NULL == cheap_allocated_string) {
 608     return NULL;
 609   }
 610   strncpy(cheap_allocated_string, string, len + 1);
 611   return cheap_allocated_string;
 612 }
 613 
 614 /*
 615 * Maps an index to a resource area allocated string for the localized PDH artifact.
 616 *
 617 * Caller will need a ResourceMark.
 618 *
 619 * @param index    the counter index as specified in the registry
 620 * @return         localized pdh artifact string if successful, NULL on failure.
 621 */
 622 static const char* pdh_localized_artifact(DWORD pdh_artifact_index) {
 623   char* pdh_localized_artifact_string = NULL;
 624   // get localized name from pdh artifact index
 625   if (lookup_name_by_index(pdh_artifact_index, &pdh_localized_artifact_string) != OS_OK) {
 626     return NULL;
 627   }
 628   return pdh_localized_artifact_string;
 629 }
 630 
 631 /*
 632  * Returns the PDH string identifying the current process image name.
 633  * Use this prefix when getting counters from the PDH process object
 634  * representing your process.
 635  * Ex. "Process(java#0)\Virtual Bytes" - where "java" is the PDH process
 636  * image description.
 637  *
 638  * Caller needs ResourceMark.
 639  *
 640  * @return the process image description. NULL if the call failed.
 641 */
 642 static const char* pdh_process_image_name() {
 643   char* module_name = NEW_RESOURCE_ARRAY_RETURN_NULL(char, MAX_PATH);
 644   if (NULL == module_name) {
 645     return NULL;
 646   }
 647   // Find our module name and use it to extract the image name used by PDH
 648   DWORD getmfn_return = GetModuleFileName(NULL, module_name, MAX_PATH);
 649   if (getmfn_return >= MAX_PATH || 0 == getmfn_return) {
 650     return NULL;
 651   }
 652   if (os::get_last_error() == ERROR_INSUFFICIENT_BUFFER) {
 653     return NULL;
 654   }
 655   char* process_image_name = strrchr(module_name, '\\'); //drop path
 656   process_image_name++;                                  //skip slash
 657   char* dot_pos = strrchr(process_image_name, '.');      //drop .exe
 658   dot_pos[0] = '\0';
 659   return process_image_name;
 660 }
 661 
 662 static void deallocate_pdh_constants() {
 663   if (process_image_name != NULL) {
 664     FREE_C_HEAP_ARRAY(char, process_image_name);
 665     process_image_name = NULL;
 666   }
 667   if (pdh_IDProcess_counter_fmt != NULL) {
 668     FREE_C_HEAP_ARRAY(char, pdh_IDProcess_counter_fmt);
 669     pdh_IDProcess_counter_fmt = NULL;
 670   }
 671 }
 672 
 673 static int allocate_pdh_constants() {
 674   assert(process_image_name == NULL, "invariant");
 675   const char* pdh_image_name = pdh_process_image_name();
 676   if (pdh_image_name == NULL) {
 677     return OS_ERR;
 678   }
 679   process_image_name = copy_string_to_c_heap(pdh_image_name);
 680 
 681   const char* pdh_localized_process_object = pdh_localized_artifact(PDH_PROCESS_IDX);
 682   if (pdh_localized_process_object == NULL) {
 683     return OS_ERR;
 684   }
 685 
 686   const char* pdh_localized_IDProcess_counter = pdh_localized_artifact(PDH_ID_PROCESS_IDX);
 687   if (pdh_localized_IDProcess_counter == NULL) {
 688     return OS_ERR;
 689   }
 690 
 691   size_t pdh_IDProcess_counter_fmt_len = strlen(process_image_name);
 692   pdh_IDProcess_counter_fmt_len += strlen(pdh_localized_process_object);
 693   pdh_IDProcess_counter_fmt_len += strlen(pdh_localized_IDProcess_counter);
 694   pdh_IDProcess_counter_fmt_len += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
 695   pdh_IDProcess_counter_fmt_len += 2; // "%d"
 696 
 697   assert(pdh_IDProcess_counter_fmt == NULL, "invariant");
 698   pdh_IDProcess_counter_fmt = NEW_C_HEAP_ARRAY_RETURN_NULL(char, pdh_IDProcess_counter_fmt_len + 1, mtInternal);
 699   if (pdh_IDProcess_counter_fmt == NULL) {
 700     return OS_ERR;
 701   }
 702 
 703   /* "\Process(java#%d)\ID Process" */
 704   const size_t len = jio_snprintf(pdh_IDProcess_counter_fmt,
 705                                   pdh_IDProcess_counter_fmt_len + 1,
 706                                   PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
 707                                   pdh_localized_process_object,
 708                                   process_image_name,
 709                                   "%d",
 710                                   pdh_localized_IDProcess_counter);
 711 
 712   assert(pdh_IDProcess_counter_fmt != NULL, "invariant");
 713   assert(len == pdh_IDProcess_counter_fmt_len, "invariant");
 714   return OS_OK;
 715 }
 716 
 717 /*
 718  * Enuerate the Processor PDH object and returns a buffer containing the enumerated instances.
 719  * Caller needs ResourceMark;
 720  *
 721  * @return  buffer if successful, NULL on failure.
 722 */
 723 static const char* enumerate_cpu_instances() {
 724   char* processor; //'Processor' == PDH_PROCESSOR_IDX
 725   if (lookup_name_by_index(PDH_PROCESSOR_IDX, &processor) != OS_OK) {
 726     return NULL;
 727   }
 728   DWORD c_size = 0;
 729   DWORD i_size = 0;
 730   // enumerate all processors.
 731   PDH_STATUS pdhStat = PdhDll::PdhEnumObjectItems(NULL, // reserved
 732                                                   NULL, // local machine
 733                                                   processor, // object to enumerate
 734                                                   NULL,
 735                                                   &c_size,
 736                                                   NULL, // instance buffer is NULL and
 737                                                   &i_size,  // pass 0 length in order to get the required size
 738                                                   PERF_DETAIL_WIZARD, // counter detail level
 739                                                   0);
 740   if (PdhDll::PdhStatusFail((pdhStat))) {
 741     return NULL;
 742   }
 743   char* const instances = NEW_RESOURCE_ARRAY_RETURN_NULL(char, i_size);
 744   if (instances == NULL) {
 745     return NULL;
 746   }
 747   c_size = 0;
 748   pdhStat = PdhDll::PdhEnumObjectItems(NULL, // reserved
 749                                        NULL, // local machine
 750                                        processor, // object to enumerate
 751                                        NULL,
 752                                        &c_size,
 753                                        instances, // now instance buffer is allocated to be filled in
 754                                        &i_size, // and the required size is known
 755                                        PERF_DETAIL_WIZARD, // counter detail level
 756                                        0);
 757   if (PdhDll::PdhStatusFail((pdhStat))) {
 758     return NULL;
 759   }
 760   return instances;
 761 }
 762 
 763 static int count_logical_cpus(const char* instances) {
 764   assert(instances != NULL, "invariant");
 765   // count logical instances.
 766   DWORD count;
 767   char* tmp;
 768   for (count = 0, tmp = const_cast<char*>(instances); *tmp != '\0'; tmp = &tmp[strlen(tmp) + 1], count++);
 769   // PDH reports an instance for each logical processor plus an instance for the total (_Total)
 770   assert(count == os::processor_count() + 1, "invalid enumeration!");
 771   return count - 1;
 772 }
 773 
 774 static int number_of_logical_cpus() {
 775   static int numberOfCPUS = 0;
 776   if (numberOfCPUS == 0) {
 777     const char* instances = enumerate_cpu_instances();
 778     if (instances == NULL) {
 779       return OS_ERR;
 780     }
 781     numberOfCPUS = count_logical_cpus(instances);
 782   }
 783   return numberOfCPUS;
 784 }
 785 
 786 static double cpu_factor() {
 787   static DWORD  numCpus = 0;
 788   static double cpuFactor = .0;
 789   if (numCpus == 0) {
 790     numCpus = number_of_logical_cpus();
 791     assert(os::processor_count() <= (int)numCpus, "invariant");
 792     cpuFactor = numCpus * 100;
 793   }
 794   return cpuFactor;
 795 }
 796 
 797 static void log_error_message_on_no_PDH_artifact(const char* full_counter_name) {
 798   log_warning(os)("Unable to register PDH query for \"%s\"", full_counter_name);
 799   log_warning(os)("Please check the registry if this performance object/counter is disabled");
 800 }
 801 
 802 static int initialize_cpu_query_counters(MultiCounterQueryP cpu_query, DWORD pdh_counter_idx) {
 803   assert(cpu_query != NULL, "invariant");
 804   assert(cpu_query->counters != NULL, "invariant");
 805   char* processor; //'Processor' == PDH_PROCESSOR_IDX
 806   if (lookup_name_by_index(PDH_PROCESSOR_IDX, &processor) != OS_OK) {
 807     return OS_ERR;
 808   }
 809   char* counter_name = NULL;
 810   if (lookup_name_by_index(pdh_counter_idx, &counter_name) != OS_OK) {
 811     return OS_ERR;
 812   }
 813   if (cpu_query->query.query == NULL) {
 814     if (open_query(cpu_query)) {
 815       return OS_ERR;
 816     }
 817   }
 818   assert(cpu_query->query.query != NULL, "invariant");
 819   size_t counter_len = strlen(processor);
 820   counter_len += strlen(counter_name);
 821   counter_len += OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN; // "\\%s(%s)\\%s"
 822 
 823   DWORD index;
 824   char* tmp;
 825   const char* instances = enumerate_cpu_instances();
 826   for (index = 0, tmp = const_cast<char*>(instances); *tmp != '\0'; tmp = &tmp[strlen(tmp) + 1], index++) {
 827     const size_t tmp_len = strlen(tmp);
 828     char* counter_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, counter_len + tmp_len + 1);
 829     if (counter_path == NULL) {
 830       return OS_ERR;
 831     }
 832     const size_t jio_snprintf_result = jio_snprintf(counter_path,
 833                                                     counter_len + tmp_len + 1,
 834                                                     OBJECT_WITH_INSTANCES_COUNTER_FMT,
 835                                                     processor,
 836                                                     tmp, // instance "0", "1", .."_Total"
 837                                                     counter_name);
 838     assert(counter_len + tmp_len == jio_snprintf_result, "invariant");
 839     if (add_counter(cpu_query, &cpu_query->counters[index], counter_path, false) != OS_OK) {
 840       // performance counter is disabled in registry and not accessible via PerfLib
 841       log_error_message_on_no_PDH_artifact(counter_path);
 842       // return OS_OK to have the system continue to run without the missing counter
 843       return OS_OK;
 844     }
 845   }
 846   cpu_query->initialized = true;
 847   // Query once to initialize the counters which require at least two samples
 848   // (like the % CPU usage) to calculate correctly.
 849   collect_query_data(cpu_query);
 850   return OS_OK;
 851 }
 852 
 853 static int initialize_cpu_query(MultiCounterQueryP cpu_query, DWORD pdh_counter_idx) {
 854   assert(cpu_query != NULL, "invariant");
 855   assert(!cpu_query->initialized, "invariant");
 856   const int logical_cpu_count = number_of_logical_cpus();
 857   assert(logical_cpu_count >= os::processor_count(), "invariant");
 858   // we also add another counter for instance "_Total"
 859   if (allocate_counters(cpu_query, logical_cpu_count + 1) != OS_OK) {
 860     return OS_ERR;
 861   }
 862   assert(cpu_query->noOfCounters == logical_cpu_count + 1, "invariant");
 863   return initialize_cpu_query_counters(cpu_query, pdh_counter_idx);
 864 }
 865 
 866 static int initialize_process_counter(ProcessQueryP process_query, int slot_index, DWORD pdh_counter_index) {
 867   char* localized_process_object;
 868   if (lookup_name_by_index(PDH_PROCESS_IDX, &localized_process_object) != OS_OK) {
 869     return OS_ERR;
 870   }
 871   assert(localized_process_object != NULL, "invariant");
 872   char* localized_counter_name;
 873   if (lookup_name_by_index(pdh_counter_index, &localized_counter_name) != OS_OK) {
 874     return OS_ERR;
 875   }
 876   assert(localized_counter_name != NULL, "invariant");
 877   for (int i = 0; i < process_query->set.size; ++i) {
 878     char instanceIndexBuffer[32];
 879     const char* counter_path = make_fully_qualified_counter_path(localized_process_object,
 880                                                                  localized_counter_name,
 881                                                                  process_image_name,
 882                                                                  itoa(i, instanceIndexBuffer, 10));
 883     if (counter_path == NULL) {
 884       return OS_ERR;
 885     }
 886     MultiCounterQueryP const query = &process_query->set.queries[i];
 887     if (add_process_counter(query, slot_index, counter_path, true)) {
 888       return OS_ERR;
 889     }
 890   }
 891   return OS_OK;
 892 }
 893 
 894 static CounterQueryP create_counter_query(DWORD pdh_object_idx, DWORD pdh_counter_idx) {
 895   if (!((is_valid_pdh_index(pdh_object_idx) && is_valid_pdh_index(pdh_counter_idx)))) {
 896     return NULL;
 897   }
 898   CounterQueryP const query = create_counter_query();
 899   const char* object = pdh_localized_artifact(pdh_object_idx);
 900   assert(object != NULL, "invariant");
 901   const char* counter = pdh_localized_artifact(pdh_counter_idx);
 902   assert(counter != NULL, "invariant");
 903   const char* full_counter_path = make_fully_qualified_counter_path(object, counter);
 904   assert(full_counter_path != NULL, "invariant");
 905   add_counter(query, full_counter_path, true);
 906   return query;
 907 }
 908 
 909 static void deallocate() {
 910   deallocate_pdh_constants();
 911   PdhDll::PdhDetach();
 912 }
 913 
 914 static LONG critical_section = 0;
 915 static LONG reference_count = 0;
 916 static bool pdh_initialized = false;
 917 
 918 static void on_initialization_failure() {
 919   // still holder of critical section
 920   deallocate();
 921   InterlockedExchangeAdd(&reference_count, -1);
 922 }
 923 
 924 static OSReturn initialize() {
 925   ResourceMark rm;
 926   if (!PdhDll::PdhAttach()) {
 927     return OS_ERR;
 928   }
 929   if (allocate_pdh_constants() != OS_OK) {
 930     on_initialization_failure();
 931     return OS_ERR;
 932   }
 933   return OS_OK;
 934 }
 935 
 936 /*
 937 * Helper to initialize the PDH library, function pointers, constants and counters.
 938 *
 939 * Reference counting allows for unloading of pdh.dll granted all sessions use the pair:
 940 *
 941 *   pdh_acquire();
 942 *   pdh_release();
 943 *
 944 * @return  OS_OK if successful, OS_ERR on failure.
 945 */
 946 static bool pdh_acquire() {
 947   while (InterlockedCompareExchange(&critical_section, 1, 0) == 1);
 948   InterlockedExchangeAdd(&reference_count, 1);
 949   if (pdh_initialized) {
 950     return true;
 951   }
 952   const OSReturn ret = initialize();
 953   if (OS_OK == ret) {
 954     pdh_initialized = true;
 955   }
 956   while (InterlockedCompareExchange(&critical_section, 0, 1) == 0);
 957   return ret == OS_OK;
 958 }
 959 
 960 static void pdh_release() {
 961   while (InterlockedCompareExchange(&critical_section, 1, 0) == 1);
 962   const LONG prev_ref_count = InterlockedExchangeAdd(&reference_count, -1);
 963   if (1 == prev_ref_count) {
 964     deallocate();
 965     pdh_initialized = false;
 966   }
 967   while (InterlockedCompareExchange(&critical_section, 0, 1) == 0);
 968 }
 969 
 970 class CPUPerformanceInterface::CPUPerformance : public CHeapObj<mtInternal> {
 971   friend class CPUPerformanceInterface;
 972  private:
 973   CounterQueryP _context_switches;
 974   ProcessQueryP _process_cpu_load;
 975   MultiCounterQueryP _machine_cpu_load;
 976 
 977   int cpu_load(int which_logical_cpu, double* cpu_load);
 978   int context_switch_rate(double* rate);
 979   int cpu_load_total_process(double* cpu_load);
 980   int cpu_loads_process(double* jvm_user_load, double* jvm_kernel_load, double* psystemTotalLoad);
 981   CPUPerformance();
 982   ~CPUPerformance();
 983   bool initialize();
 984 };
 985 
 986 class SystemProcessInterface::SystemProcesses : public CHeapObj<mtInternal> {
 987   friend class SystemProcessInterface;
 988  private:
 989   class ProcessIterator : public CHeapObj<mtInternal> {
 990     friend class SystemProcessInterface::SystemProcesses;
 991    private:
 992     HANDLE         _hProcessSnap;
 993     PROCESSENTRY32 _pe32;
 994     BOOL           _valid;
 995     char           _exePath[MAX_PATH];
 996     ProcessIterator();
 997     ~ProcessIterator();
 998     bool initialize();
 999 
1000     int current(SystemProcess* const process_info);
1001     int next_process();
1002     bool is_valid() const { return _valid != FALSE; }
1003     char* allocate_string(const char* str) const;
1004     int snapshot();
1005   };
1006 
1007   ProcessIterator* _iterator;
1008   SystemProcesses();
1009   ~SystemProcesses();
1010   bool initialize();
1011 
1012   // information about system processes
1013   int system_processes(SystemProcess** system_processes, int* no_of_sys_processes) const;
1014 };
1015 
1016 CPUPerformanceInterface::CPUPerformance::CPUPerformance() : _context_switches(NULL), _process_cpu_load(NULL), _machine_cpu_load(NULL) {}
1017 
1018 bool CPUPerformanceInterface::CPUPerformance::initialize() {
1019   if (!pdh_acquire()) {
1020     return true;
1021   }
1022   _context_switches = create_counter_query(PDH_SYSTEM_IDX, PDH_CONTEXT_SWITCH_RATE_IDX);
1023   _process_cpu_load = create_process_query();
1024   if (_process_cpu_load == NULL) {
1025     return true;
1026   }
1027   if (allocate_counters(_process_cpu_load, 2) != OS_OK) {
1028     return true;
1029   }
1030   if (initialize_process_counter(_process_cpu_load, 0, PDH_PROCESSOR_TIME_IDX) != OS_OK) {
1031     return true;
1032   }
1033   if (initialize_process_counter(_process_cpu_load, 1, PDH_PRIV_PROCESSOR_TIME_IDX) != OS_OK) {
1034     return true;
1035   }
1036   _process_cpu_load->set.initialized = true;
1037   _machine_cpu_load = create_multi_counter_query();
1038   if (_machine_cpu_load == NULL) {
1039     return true;
1040   }
1041   initialize_cpu_query(_machine_cpu_load, PDH_PROCESSOR_TIME_IDX);
1042   return true;
1043 }
1044 
1045 CPUPerformanceInterface::CPUPerformance::~CPUPerformance() {
1046   if (_context_switches != NULL) {
1047     destroy_counter_query(_context_switches);
1048     _context_switches = NULL;
1049   }
1050   if (_process_cpu_load != NULL) {
1051     destroy_counter_query(_process_cpu_load);
1052     _process_cpu_load = NULL;
1053   }
1054   if (_machine_cpu_load != NULL) {
1055     destroy_counter_query(_machine_cpu_load);
1056     _machine_cpu_load = NULL;
1057   }
1058   pdh_release();
1059 }
1060 
1061 CPUPerformanceInterface::CPUPerformanceInterface() {
1062   _impl = NULL;
1063 }
1064 
1065 bool CPUPerformanceInterface::initialize() {
1066   _impl = new CPUPerformanceInterface::CPUPerformance();
1067   return _impl != NULL && _impl->initialize();
1068 }
1069 
1070 CPUPerformanceInterface::~CPUPerformanceInterface() {
1071   if (_impl != NULL) {
1072     delete _impl;
1073   }
1074 }
1075 
1076 int CPUPerformanceInterface::cpu_load(int which_logical_cpu, double* cpu_load) const {
1077   return _impl->cpu_load(which_logical_cpu, cpu_load);
1078 }
1079 
1080 int CPUPerformanceInterface::context_switch_rate(double* rate) const {
1081   return _impl->context_switch_rate(rate);
1082 }
1083 
1084 int CPUPerformanceInterface::cpu_load_total_process(double* cpu_load) const {
1085   return _impl->cpu_load_total_process(cpu_load);
1086 }
1087 
1088 int CPUPerformanceInterface::cpu_loads_process(double* pjvmUserLoad,
1089                                                double* pjvmKernelLoad,
1090                                                double* psystemTotalLoad) const {
1091   return _impl->cpu_loads_process(pjvmUserLoad, pjvmKernelLoad, psystemTotalLoad);
1092 }
1093 
1094 int CPUPerformanceInterface::CPUPerformance::cpu_load(int which_logical_cpu, double* cpu_load) {
1095   *cpu_load = .0;
1096   if (_machine_cpu_load == NULL || !_machine_cpu_load->initialized) {
1097     return OS_ERR;
1098   }
1099   assert(_machine_cpu_load != NULL, "invariant");
1100   assert(which_logical_cpu < _machine_cpu_load->noOfCounters, "invariant");
1101 
1102   if (collect_query_data(_machine_cpu_load)) {
1103     return OS_ERR;
1104   }
1105   // -1 is total (all cpus)
1106   const int counter_idx = -1 == which_logical_cpu ? _machine_cpu_load->noOfCounters - 1 : which_logical_cpu;
1107   PDH_FMT_COUNTERVALUE counter_value;
1108   formatted_counter_value(_machine_cpu_load->counters[counter_idx], PDH_FMT_DOUBLE, &counter_value);
1109   *cpu_load = counter_value.doubleValue / 100;
1110   return OS_OK;
1111 }
1112 
1113 int CPUPerformanceInterface::CPUPerformance::cpu_load_total_process(double* cpu_load) {
1114   *cpu_load = .0;
1115   if (_process_cpu_load == NULL || !_process_cpu_load->set.initialized) {
1116     return OS_ERR;
1117   }
1118   assert(_process_cpu_load != NULL, "invariant");
1119   if (collect_process_query_data(_process_cpu_load)) {
1120     return OS_ERR;
1121   }
1122   PDH_FMT_COUNTERVALUE counter_value;
1123   if (query_process_counter(_process_cpu_load, 0, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100, &counter_value) != OS_OK) {
1124     return OS_ERR;
1125   }
1126   double process_load = counter_value.doubleValue / cpu_factor();
1127   process_load = MIN2<double>(1, process_load);
1128   process_load = MAX2<double>(0, process_load);
1129   *cpu_load = process_load;
1130   return OS_OK;
1131 }
1132 
1133 int CPUPerformanceInterface::CPUPerformance::cpu_loads_process(double* pjvmUserLoad,
1134                                                                double* pjvmKernelLoad,
1135                                                                double* psystemTotalLoad) {
1136   assert(pjvmUserLoad != NULL, "pjvmUserLoad is NULL!");
1137   assert(pjvmKernelLoad != NULL, "pjvmKernelLoad is NULL!");
1138   assert(psystemTotalLoad != NULL, "psystemTotalLoad is NULL!");
1139   *pjvmUserLoad = .0;
1140   *pjvmKernelLoad = .0;
1141   *psystemTotalLoad = .0;
1142 
1143   if (_process_cpu_load == NULL || !_process_cpu_load->set.initialized) {
1144     return OS_ERR;
1145   }
1146   assert(_process_cpu_load != NULL, "invariant");
1147   if (collect_process_query_data(_process_cpu_load)) {
1148     return OS_ERR;
1149   }
1150   double process_load = .0;
1151   PDH_FMT_COUNTERVALUE counter_value;
1152   // Read  PDH_PROCESSOR_TIME_IDX
1153   if (query_process_counter(_process_cpu_load, 0, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100, &counter_value) != OS_OK) {
1154     return OS_ERR;
1155   }
1156   process_load = counter_value.doubleValue / cpu_factor();
1157   process_load = MIN2<double>(1, process_load);
1158   process_load = MAX2<double>(0, process_load);
1159   // Read PDH_PRIV_PROCESSOR_TIME_IDX
1160   if (query_process_counter(_process_cpu_load, 1, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100, &counter_value) != OS_OK) {
1161     return OS_ERR;
1162   }
1163   double kernel_load = counter_value.doubleValue / cpu_factor();
1164   kernel_load = MIN2<double>(1, kernel_load);
1165   kernel_load = MAX2<double>(0, kernel_load);
1166   *pjvmKernelLoad = kernel_load;
1167 
1168   double user_load = process_load - kernel_load;
1169   user_load = MIN2<double>(1, user_load);
1170   user_load = MAX2<double>(0, user_load);
1171   *pjvmUserLoad = user_load;
1172 
1173   if (collect_query_data(_machine_cpu_load)) {
1174     return OS_ERR;
1175   }
1176   if (formatted_counter_value(_machine_cpu_load->counters[_machine_cpu_load->noOfCounters - 1], PDH_FMT_DOUBLE, &counter_value) != OS_OK) {
1177     return OS_ERR;
1178   }
1179   double machine_load = counter_value.doubleValue / 100;
1180   assert(machine_load >= 0, "machine_load is negative!");
1181   // clamp at user+system and 1.0
1182   if (*pjvmKernelLoad + *pjvmUserLoad > machine_load) {
1183     machine_load = MIN2(*pjvmKernelLoad + *pjvmUserLoad, 1.0);
1184   }
1185   *psystemTotalLoad = machine_load;
1186   return OS_OK;
1187 }
1188 
1189 int CPUPerformanceInterface::CPUPerformance::context_switch_rate(double* rate) {
1190   assert(rate != NULL, "invariant");
1191   *rate = .0;
1192   if (_context_switches == NULL || !_context_switches->initialized) {
1193     return OS_ERR;
1194   }
1195   assert(_context_switches != NULL, "invariant");
1196   if (collect_query_data(_context_switches) != OS_OK) {
1197     return OS_ERR;
1198   }
1199   PDH_FMT_COUNTERVALUE counter_value;
1200   if (formatted_counter_value(_context_switches->counter, PDH_FMT_DOUBLE, &counter_value) != OS_OK) {
1201     return OS_ERR;
1202   }
1203   *rate = counter_value.doubleValue;
1204   return OS_OK;
1205 }
1206 
1207 SystemProcessInterface::SystemProcesses::ProcessIterator::ProcessIterator() {
1208   _hProcessSnap = INVALID_HANDLE_VALUE;
1209   _valid = FALSE;
1210   _pe32.dwSize = sizeof(PROCESSENTRY32);
1211 }
1212 
1213 bool SystemProcessInterface::SystemProcesses::ProcessIterator::initialize() {
1214   return true;
1215 }
1216 
1217 int SystemProcessInterface::SystemProcesses::ProcessIterator::snapshot() {
1218   // take snapshot of all process in the system
1219   _hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
1220   if (_hProcessSnap == INVALID_HANDLE_VALUE) {
1221     return OS_ERR;
1222   }
1223   // step to first process
1224   _valid = Process32First(_hProcessSnap, &_pe32);
1225   return is_valid() ? OS_OK : OS_ERR;
1226 }
1227 
1228 SystemProcessInterface::SystemProcesses::ProcessIterator::~ProcessIterator() {
1229   if (_hProcessSnap != INVALID_HANDLE_VALUE) {
1230     CloseHandle(_hProcessSnap);
1231   }
1232 }
1233 
1234 int SystemProcessInterface::SystemProcesses::ProcessIterator::current(SystemProcess* process_info) {
1235   assert(is_valid(), "no current process to be fetched!");
1236   assert(process_info != NULL, "process_info is NULL!");
1237   char* exePath = NULL;
1238   HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, _pe32.th32ProcessID);
1239   if (hProcess != NULL) {
1240     HMODULE hMod;
1241     DWORD cbNeeded;
1242     if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded) != 0) {
1243       if (GetModuleFileNameExA(hProcess, hMod, _exePath, sizeof(_exePath)) != 0) {
1244         exePath = _exePath;
1245       }
1246     }
1247     CloseHandle (hProcess);
1248   }
1249   process_info->set_pid((int)_pe32.th32ProcessID);
1250   process_info->set_name(allocate_string(_pe32.szExeFile));
1251   process_info->set_path(allocate_string(exePath));
1252   return OS_OK;
1253 }
1254 
1255 char* SystemProcessInterface::SystemProcesses::ProcessIterator::allocate_string(const char* str) const {
1256   if (str != NULL) {
1257     return os::strdup_check_oom(str, mtInternal);
1258   }
1259   return NULL;
1260 }
1261 
1262 int SystemProcessInterface::SystemProcesses::ProcessIterator::next_process() {
1263   _valid = Process32Next(_hProcessSnap, &_pe32);
1264   return OS_OK;
1265 }
1266 
1267 SystemProcessInterface::SystemProcesses::SystemProcesses() {
1268   _iterator = NULL;
1269 }
1270 
1271 bool SystemProcessInterface::SystemProcesses::initialize() {
1272   _iterator = new SystemProcessInterface::SystemProcesses::ProcessIterator();
1273   return _iterator != NULL && _iterator->initialize();
1274 }
1275 
1276 SystemProcessInterface::SystemProcesses::~SystemProcesses() {
1277   if (_iterator != NULL) {
1278     delete _iterator;
1279     _iterator = NULL;
1280   }
1281 }
1282 
1283 int SystemProcessInterface::SystemProcesses::system_processes(SystemProcess** system_processes,
1284                                                               int* no_of_sys_processes) const {
1285   assert(system_processes != NULL, "system_processes pointer is NULL!");
1286   assert(no_of_sys_processes != NULL, "system_processes counter pointers is NULL!");
1287   assert(_iterator != NULL, "iterator is NULL!");
1288 
1289   // initialize pointers
1290   *no_of_sys_processes = 0;
1291   *system_processes = NULL;
1292 
1293   // take process snapshot
1294   if (_iterator->snapshot() != OS_OK) {
1295     return OS_ERR;
1296   }
1297 
1298   while (_iterator->is_valid()) {
1299     SystemProcess* tmp = new SystemProcess();
1300     _iterator->current(tmp);
1301 
1302     //if already existing head
1303     if (*system_processes != NULL) {
1304       //move "first to second"
1305       tmp->set_next(*system_processes);
1306     }
1307     // new head
1308     *system_processes = tmp;
1309     // increment
1310     (*no_of_sys_processes)++;
1311     // step forward
1312     _iterator->next_process();
1313   }
1314   return OS_OK;
1315 }
1316 
1317 int SystemProcessInterface::system_processes(SystemProcess** system_procs,
1318                                              int* no_of_sys_processes) const {
1319   return _impl->system_processes(system_procs, no_of_sys_processes);
1320 }
1321 
1322 SystemProcessInterface::SystemProcessInterface() {
1323   _impl = NULL;
1324 }
1325 
1326 bool SystemProcessInterface::initialize() {
1327   _impl = new SystemProcessInterface::SystemProcesses();
1328   return _impl != NULL && _impl->initialize();
1329 }
1330 
1331 SystemProcessInterface::~SystemProcessInterface() {
1332   if (_impl != NULL) {
1333     delete _impl;
1334   }
1335 }
1336 
1337 CPUInformationInterface::CPUInformationInterface() {
1338   _cpu_info = NULL;
1339 }
1340 
1341 bool CPUInformationInterface::initialize() {
1342   _cpu_info = new CPUInformation();
1343   if (NULL == _cpu_info) {
1344     return false;
1345   }
1346   _cpu_info->set_number_of_hardware_threads(VM_Version_Ext::number_of_threads());
1347   _cpu_info->set_number_of_cores(VM_Version_Ext::number_of_cores());
1348   _cpu_info->set_number_of_sockets(VM_Version_Ext::number_of_sockets());
1349   _cpu_info->set_cpu_name(VM_Version_Ext::cpu_name());
1350   _cpu_info->set_cpu_description(VM_Version_Ext::cpu_description());
1351   return true;
1352 }
1353 
1354 CPUInformationInterface::~CPUInformationInterface() {
1355   if (_cpu_info != NULL) {
1356     const char* cpu_name = _cpu_info->cpu_name();
1357     if (cpu_name != NULL) {
1358       FREE_C_HEAP_ARRAY(char, cpu_name);
1359       _cpu_info->set_cpu_name(NULL);
1360     }
1361     const char* cpu_desc = _cpu_info->cpu_description();
1362     if (cpu_desc != NULL) {
1363       FREE_C_HEAP_ARRAY(char, cpu_desc);
1364       _cpu_info->set_cpu_description(NULL);
1365     }
1366     delete _cpu_info;
1367     _cpu_info = NULL;
1368   }
1369 }
1370 
1371 int CPUInformationInterface::cpu_information(CPUInformation& cpu_info) {
1372   if (NULL == _cpu_info) {
1373     return OS_ERR;
1374   }
1375   cpu_info = *_cpu_info; // shallow copy assignment
1376   return OS_OK;
1377 }
1378 
1379 class NetworkPerformanceInterface::NetworkPerformance : public CHeapObj<mtInternal> {
1380   friend class NetworkPerformanceInterface;
1381  private:
1382   bool _iphlp_attached;
1383 
1384   NetworkPerformance();
1385   NONCOPYABLE(NetworkPerformance);
1386   bool initialize();
1387   ~NetworkPerformance();
1388   int network_utilization(NetworkInterface** network_interfaces) const;
1389 };
1390 
1391 NetworkPerformanceInterface::NetworkPerformance::NetworkPerformance()
1392 : _iphlp_attached(false) {
1393 }
1394 
1395 bool NetworkPerformanceInterface::NetworkPerformance::initialize() {
1396   _iphlp_attached = IphlpDll::IphlpAttach();
1397   return _iphlp_attached;
1398 }
1399 
1400 NetworkPerformanceInterface::NetworkPerformance::~NetworkPerformance() {
1401   if (_iphlp_attached) {
1402     IphlpDll::IphlpDetach();
1403   }
1404 }
1405 
1406 int NetworkPerformanceInterface::NetworkPerformance::network_utilization(NetworkInterface** network_interfaces) const {
1407   MIB_IF_TABLE2* table;
1408 
1409   if (IphlpDll::GetIfTable2(&table) != NO_ERROR) {
1410     return OS_ERR;
1411   }
1412 
1413   NetworkInterface* ret = NULL;
1414   for (ULONG i = 0; i < table->NumEntries; ++i) {
1415     if (table->Table[i].InterfaceAndOperStatusFlags.FilterInterface) {
1416       continue;
1417     }
1418 
1419     char buf[256];
1420     if (WideCharToMultiByte(CP_UTF8, 0, table->Table[i].Description, -1, buf, sizeof(buf), NULL, NULL) == 0) {
1421       continue;
1422     }
1423 
1424     NetworkInterface* cur = new NetworkInterface(buf, table->Table[i].InOctets, table->Table[i].OutOctets, ret);
1425     ret = cur;
1426   }
1427 
1428   IphlpDll::FreeMibTable(table);
1429   *network_interfaces = ret;
1430 
1431   return OS_OK;
1432 }
1433 
1434 NetworkPerformanceInterface::NetworkPerformanceInterface() {
1435   _impl = NULL;
1436 }
1437 
1438 NetworkPerformanceInterface::~NetworkPerformanceInterface() {
1439   if (_impl != NULL) {
1440     delete _impl;
1441   }
1442 }
1443 
1444 bool NetworkPerformanceInterface::initialize() {
1445   _impl = new NetworkPerformanceInterface::NetworkPerformance();
1446   return _impl != NULL && _impl->initialize();
1447 }
1448 
1449 int NetworkPerformanceInterface::network_utilization(NetworkInterface** network_interfaces) const {
1450   return _impl->network_utilization(network_interfaces);
1451 }