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