/*
 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "jni.h"
#include "jni_util.h"
#include "jlong.h"
#include "jvm.h"
#include "management.h"
#include "sun_management_OperatingSystemImpl.h"

#include <psapi.h>
#include <errno.h>
#include <stdlib.h>

#include <malloc.h>
#pragma warning (push,0)
#include <windows.h>
#pragma warning (pop)
#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <assert.h>

/* Disable warnings due to broken header files from Microsoft... */
#pragma warning(push, 3)
#include <pdh.h>
#include <pdhmsg.h>
#include <process.h>
#pragma warning(pop)

typedef unsigned __int32 juint;
typedef unsigned __int64 julong;

static void set_low(jlong* value, jint low) {
    *value &= (jlong)0xffffffff << 32;
    *value |= (jlong)(julong)(juint)low;
}

static void set_high(jlong* value, jint high) {
    *value &= (jlong)(julong)(juint)0xffffffff;
    *value |= (jlong)high       << 32;
}

static jlong jlong_from(jint h, jint l) {
    jlong result = 0; // initialization to avoid warning
    set_high(&result, h);
    set_low(&result,  l);
    return result;
}

static HANDLE main_process;

static void perfInit(void);

JNIEXPORT void JNICALL
Java_sun_management_OperatingSystemImpl_initialize
  (JNIEnv *env, jclass cls)
{
    main_process = GetCurrentProcess();
    perfInit();
}

JNIEXPORT jlong JNICALL
Java_sun_management_OperatingSystemImpl_getCommittedVirtualMemorySize0
  (JNIEnv *env, jobject mbean)
{
    PROCESS_MEMORY_COUNTERS pmc;
    if (GetProcessMemoryInfo(main_process, &pmc, sizeof(PROCESS_MEMORY_COUNTERS)) == 0) {
        return (jlong)-1L;
    } else {
        return (jlong) pmc.PagefileUsage;
    }
}

JNIEXPORT jlong JNICALL
Java_sun_management_OperatingSystemImpl_getTotalSwapSpaceSize
  (JNIEnv *env, jobject mbean)
{
    MEMORYSTATUSEX ms;
    ms.dwLength = sizeof(ms);
    GlobalMemoryStatusEx(&ms);
    return (jlong) ms.ullTotalPageFile;
}

JNIEXPORT jlong JNICALL
Java_sun_management_OperatingSystemImpl_getFreeSwapSpaceSize
  (JNIEnv *env, jobject mbean)
{
    MEMORYSTATUSEX ms;
    ms.dwLength = sizeof(ms);
    GlobalMemoryStatusEx(&ms);
    return (jlong) ms.ullAvailPageFile;
}

JNIEXPORT jlong JNICALL
Java_sun_management_OperatingSystemImpl_getProcessCpuTime
  (JNIEnv *env, jobject mbean)
{

    FILETIME process_creation_time, process_exit_time,
             process_user_time, process_kernel_time;

    // Using static variables declared above
    // Units are 100-ns intervals.  Convert to ns.
    GetProcessTimes(main_process, &process_creation_time,
                    &process_exit_time,
                    &process_kernel_time, &process_user_time);
    return (jlong_from(process_user_time.dwHighDateTime,
                        process_user_time.dwLowDateTime) +
            jlong_from(process_kernel_time.dwHighDateTime,
                        process_kernel_time.dwLowDateTime)) * 100;
}

JNIEXPORT jlong JNICALL
Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize
  (JNIEnv *env, jobject mbean)
{
    MEMORYSTATUSEX ms;
    ms.dwLength = sizeof(ms);
    GlobalMemoryStatusEx(&ms);
    return (jlong) ms.ullAvailPhys;
}

JNIEXPORT jlong JNICALL
Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize
  (JNIEnv *env, jobject mbean)
{
    MEMORYSTATUSEX ms;
    ms.dwLength = sizeof(ms);
    GlobalMemoryStatusEx(&ms);
    return (jlong) ms.ullTotalPhys;
}

/* Performance Data Helper API (PDH) support */

typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)(
                           HQUERY      hQuery,
                           LPCSTR      szFullCounterPath,
                           DWORD       dwUserData,
                           HCOUNTER    *phCounter
                           );
typedef PDH_STATUS (WINAPI *PdhOpenQueryFunc)(
                           LPCWSTR     szDataSource,
                           DWORD       dwUserData,
                           HQUERY      *phQuery
                           );
typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)(
                           HQUERY      hQuery
                           );

typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)(
                           LPCTSTR     szDataSource,
                           LPCTSTR     szMachineName,
                           LPCTSTR     szObjectName,
                           LPTSTR      mszCounterList,
                           LPDWORD     pcchCounterListLength,
                           LPTSTR      mszInstanceList,
                           LPDWORD     pcchInstanceListLength,
                           DWORD       dwDetailLevel,
                           DWORD       dwFlags
                           );
typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)(
                           HCOUNTER   hCounter
                           );
typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)(
                           LPCSTR     szMachineName,
                           DWORD      dwNameIndex,
                           LPSTR      szNameBuffer,
                           LPDWORD    pcchNameBufferSize
                           );
typedef DWORD (WINAPI *PdhCloseQueryFunc)(
                      HQUERY      hQuery
                      );

typedef DWORD (WINAPI *PdhGetFormattedCounterValueFunc)(
                      HCOUNTER                hCounter,
                      DWORD                   dwFormat,
                      LPDWORD                 lpdwType,
                      PPDH_FMT_COUNTERVALUE   pValue
                      );

static PdhAddCounterFunc PdhAddCounter_i;
static PdhOpenQueryFunc PdhOpenQuery_i;
static PdhCloseQueryFunc PdhCloseQuery_i;
static PdhCollectQueryDataFunc PdhCollectQueryData_i;
static PdhGetFormattedCounterValueFunc PdhGetFormattedCounterValue_i;
static PdhEnumObjectItemsFunc PdhEnumObjectItems_i;
static PdhRemoveCounterFunc PdhRemoveCounter_i;
static PdhLookupPerfNameByIndexFunc PdhLookupPerfNameByIndex_i;

/*
 * Struct for PDH queries.
 */
typedef struct {
    HQUERY      query;
    uint64_t    lastUpdate; // Last time query was updated (ticks)
} UpdateQueryS, *UpdateQueryP;

// Min time between query updates (ticks)
static const int MIN_UPDATE_INTERVAL = 500;

/*
 * Struct for a PDH query with multiple counters.
 */
typedef struct {
    UpdateQueryS  query;
    HCOUNTER*     counters;
    int           noOfCounters;
} MultipleCounterQueryS, *MultipleCounterQueryP;

/*
 * Struct for a PDH query with a single counter.
 */
typedef struct {
    UpdateQueryS  query;
    HCOUNTER      counter;
} SingleCounterQueryS, *SingleCounterQueryP;


typedef struct {
    CRITICAL_SECTION cs;
    DWORD owningThread;
    DWORD recursionCount;
} PdhCriticalSectionS, *PdhCriticalSectionP;

static PdhCriticalSectionS initializationLock;

static void InitializePdhCriticalSection(PdhCriticalSectionP criticalSection) {
    assert(criticalSection);

    InitializeCriticalSection(&criticalSection->cs);
    criticalSection->owningThread = 0;
    criticalSection->recursionCount = 0;
}

static void EnterPdhCriticalSection(PdhCriticalSectionP criticalSection) {
    assert(criticalSection);

    EnterCriticalSection(&criticalSection->cs);
    criticalSection->recursionCount++;
    if (!criticalSection->owningThread) {
        criticalSection->owningThread = GetCurrentThreadId();
    }
}

static void LeavePdhCriticalSection(PdhCriticalSectionP criticalSection) {
    assert(criticalSection);
    assert(GetCurrentThreadId() == criticalSection->owningThread);
    assert(criticalSection->recursionCount >= 1);

    criticalSection->recursionCount--;
    if (!criticalSection->recursionCount) {
        criticalSection->owningThread = 0;
    }
    LeaveCriticalSection(&criticalSection->cs);
}

/*
 * INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
 *   http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
 * The index value for the base system counters and objects like processor,
 * process, thread, memory, and so forth are always the same irrespective
 * of the localized version of the operating system or service pack installed.
 * To find the correct index for an object or counter, inspect the registry key/value:
 * [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Counter]
 */
static const DWORD PDH_PROCESSOR_IDX = 238;
static const DWORD PDH_PROCESSOR_TIME_IDX = 6;
static const DWORD PDH_PROCESS_IDX = 230;
static const DWORD PDH_ID_PROCESS_IDX = 784;

/* useful pdh fmt's */
static const char* const OBJECT_COUNTER_FMT = "\\%s\\%s";
static const size_t OBJECT_COUNTER_FMT_LEN = 2;
static const char* const OBJECT_WITH_INSTANCES_COUNTER_FMT = "\\%s(%s)\\%s";
static const size_t OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN = 4;
static const char* const PROCESS_OBJECT_INSTANCE_COUNTER_FMT = "\\%s(%s#%s)\\%s";
static const size_t PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN = 5;

static const char* pdhProcessImageName = NULL; /* "java" */
static char* pdhIDProcessCounterFmt = NULL;    /* "\Process(java#%d)\ID Process" */

static int numberOfJavaProcessesAtInitialization = 0;

/*
 * Currently used CPU queries/counters and variables
 */
static SingleCounterQueryP processTotalCPULoad = NULL;
static MultipleCounterQueryP multiCounterCPULoad = NULL;
static double cpuFactor = .0;
static DWORD  numCpus = 0;

/*
 * Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
 * Let's just ignore it, since we make sure we have enough buffer anyway.
 */
static int
pdhFail(PDH_STATUS pdhStat) {
    return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA;
}

static const char*
allocateAndCopy(const char* const originalString) {
    size_t len;
    char* allocatedString;

    assert(originalString);

    len = strlen(originalString);

    allocatedString = malloc(len + 1);

    if (!allocatedString) {
        return NULL;
    }

    strncpy(allocatedString, originalString, len);
    allocatedString[len] = '\0';

    return allocatedString;
}

/*
 * Allocates memory into the supplied pointer and
 * fills it with the localized PDH artifact description, if indexed correctly.
 * Caller owns the memory from the point of returning from this function.
 *
 * @param index    the PDH counter index as specified in the registry
 * @param ppBuffer pointer to a char*.
 * @return         0 if successful, negative on failure.
 */
static int
lookupNameByIndex(DWORD index, char** ppBuffer) {
    DWORD size;

    assert(ppBuffer);

    /* determine size needed */
    if (PdhLookupPerfNameByIndex_i(NULL, index, NULL, &size) != PDH_MORE_DATA) {
      /* invalid index? */
      return -1;
    }

    *ppBuffer = malloc((size_t)size);

    if (!*ppBuffer) {
        return -1;
    }

    if (PdhLookupPerfNameByIndex_i(NULL, index, *ppBuffer, &size) != ERROR_SUCCESS) {
        free(*ppBuffer);
        *ppBuffer = NULL;
        return -1;
    }

    /* windows vista does not null-terminate the string
     * (although the docs says it will) */
    (*ppBuffer)[size - 1] = '\0';

    return 0;
}

/*
* Construct a fully qualified PDH path
*
* @param objectName   a PDH Object string representation (required)
* @param counterName  a PDH Counter string representation (required)
* @param imageName    a process image name string, ex. "java" (opt)
* @param instance     an instance string, ex. "0", "1", ... (opt)
* @return             the fully qualified PDH path.
*
* Caller will own the returned malloc:ed string
*/
static const char*
makeFullCounterPath(const char* const objectName,
                    const char* const counterName,
                    const char* const imageName,
                    const char* const instance) {

    size_t fullCounterPathLen;
    char* fullCounterPath;

    assert(objectName);
    assert(counterName);

    fullCounterPathLen = strlen(objectName);
    fullCounterPathLen += strlen(counterName);

    if (imageName) {
        /*
         * For paths using the "Process" Object.
         *
         * Examples:
         * abstract: "\Process(imageName#instance)\Counter"
         * actual:   "\Process(java#2)\ID Process"
         */
        fullCounterPathLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
        fullCounterPathLen += strlen(imageName);

        /*
         * imageName must be passed together with an associated
         * instance "number" ("0", "1", "2", ...).
         * This is required in order to create valid "Process" Object paths.
         *
         * Examples: "\Process(java#0)", \Process(java#1"), ...
         */
        assert(instance);

        fullCounterPathLen += strlen(instance);

        fullCounterPath = malloc(fullCounterPathLen + 1);

        if (!fullCounterPath) {
            return NULL;
        }

        _snprintf(fullCounterPath,
                  fullCounterPathLen,
                  PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
                  objectName,
                  imageName,
                  instance,
                  counterName);
    } else {
        if (instance) {
            /*
             * For paths where the Object has multiple instances.
             *
             * Examples:
             * abstract: "\Object(instance)\Counter"
             * actual:   "\Processor(0)\% Privileged Time"
             */
            fullCounterPathLen += strlen(instance);
            fullCounterPathLen += OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN;
        } else {
            /*
             * For "normal" paths.
             *
             * Examples:
             * abstract: "\Object\Counter"
             * actual:   "\Memory\Available Mbytes"
             */
            fullCounterPathLen += OBJECT_COUNTER_FMT_LEN;
        }

        fullCounterPath = malloc(fullCounterPathLen + 1);

        if (!fullCounterPath) {
            return NULL;
        }

        if (instance) {
            _snprintf(fullCounterPath,
                      fullCounterPathLen,
                      OBJECT_WITH_INSTANCES_COUNTER_FMT,
                      objectName,
                      instance,
                      counterName);
        } else {
            _snprintf(fullCounterPath,
                      fullCounterPathLen,
                      OBJECT_COUNTER_FMT,
                      objectName,
                      counterName);
        }
    }

    fullCounterPath[fullCounterPathLen] = '\0';

    return fullCounterPath;
}

/*
 * Resolves an index for a PDH artifact to
 * a localized, malloc:ed string representation.
 * Caller will own the returned malloc:ed string.
 *
 * @param pdhArtifactIndex  PDH index
 * @return                  malloc:ed string representation
 *                          of the requested pdh artifact (localized).
 *                          NULL on failure.
 */
static const char*
getPdhLocalizedArtifact(DWORD pdhArtifactIndex) {
    char* pdhLocalizedArtifactString;

    if (lookupNameByIndex(pdhArtifactIndex,
                          &pdhLocalizedArtifactString) != 0) {
        return NULL;
    }

    return pdhLocalizedArtifactString;
}

static void
pdhCleanup(HQUERY* const query, HCOUNTER* const counter) {
    if (counter && *counter) {
        PdhRemoveCounter_i(*counter);
        *counter = NULL;
    }
    if (query && *query) {
        PdhCloseQuery_i(*query);
        *query = NULL;
    }
}

static void
destroySingleCounter(SingleCounterQueryP counterQuery) {
    if (counterQuery) {
        pdhCleanup(&counterQuery->query.query, &counterQuery->counter);
    }
}

static void
destroyMultiCounter(MultipleCounterQueryP multiCounterQuery) {
    int i;
    if (multiCounterQuery) {
        if (multiCounterQuery->counters) {
            for (i = 0; i < multiCounterQuery->noOfCounters; i++) {
                pdhCleanup(NULL, &multiCounterQuery->counters[i]);
            }
            free(multiCounterQuery->counters);
            multiCounterQuery->counters = NULL;
        }
        pdhCleanup(&multiCounterQuery->query.query, NULL);
    }
}

static int
openQuery(HQUERY* const query) {
    assert(query);

    if (PdhOpenQuery_i(NULL, 0, query) != ERROR_SUCCESS) {
        return -1;
    }

    return 0;
}

static int
addCounter(HQUERY query,
           const char* const fullCounterPath,
           HCOUNTER* const counter) {

    assert(fullCounterPath);
    assert(counter);

    if (PdhAddCounter_i(query,
                        fullCounterPath,
                        0,
                        counter) != ERROR_SUCCESS) {
        return -1;
    }

    return 0;
}

/*
 * Sets up the supplied SingleCounterQuery to listen for the specified counter.
 *
 * @param counterQuery       the counter query to set up.
 * @param fullCounterPath    the string specifying the full path to the counter.
 * @returns                  0 if successful, negative on failure.
 */
static int
initializeSingleCounterQuery(SingleCounterQueryP counterQuery,
                             const char* const fullCounterPath) {
    assert(counterQuery);
    assert(fullCounterPath);

    if (openQuery(&counterQuery->query.query) == 0) {
        if (addCounter(counterQuery->query.query,
                       fullCounterPath,
                       &counterQuery->counter) == 0) {
            return 0;
        }
    }

    return -1;
}

/*
 * Sets up a SingleCounterQuery
 *
 * param counter             the counter query to set up.
 * param localizedObject     string representing the PDH object to query
 * param localizedCounter    string representing the PDH counter to query
 * param processImageName    if the counter query needs the process image name ("java")
 * param instance            if the counter has instances, this is the instance ("\Processor(0)\")
                                 where 0 is the instance
 * param firstSampleOnInit   for counters that need two queries to yield their values,
                                 the first query can be issued just after initialization
 *
 * @returns                   0 if successful, negative on failure.
 */
static int
initializeSingleCounter(SingleCounterQueryP const counter,
                        const char* const localizedObject,
                        const char* const localizedCounter,
                        const char* const processImageName,
                        const char* const instance,
                        BOOL firstSampleOnInit) {
    int retValue = -1;

    const char* fullCounterPath = makeFullCounterPath(localizedObject,
                                                      localizedCounter,
                                                      processImageName,
                                                      instance);

    if (fullCounterPath) {

        assert(counter);

        if (initializeSingleCounterQuery(counter, fullCounterPath) == 0) {
            /*
             * According to the MSDN documentation, rate counters must be read twice:
             *
             * "Obtaining the value of rate counters such as Page faults/sec requires that
             *  PdhCollectQueryData be called twice, with a specific time interval between
             *  the two calls, before calling PdhGetFormattedCounterValue. Call Sleep to
             *  implement the waiting period between the two calls to PdhCollectQueryData."
             *
             *  Take the first sample here already to allow for the next (first) "real" sample
             *  to succeed.
             */
            if (firstSampleOnInit) {
                PdhCollectQueryData_i(counter->query.query);
            }

            retValue = 0;
        }
        free((char*)fullCounterPath);
    }

    return retValue;
}

static void
perfInit(void) {
    InitializePdhCriticalSection(&initializationLock);
}

static int
getProcessID() {
    static int myPid = 0;
    if (0 == myPid) {
        myPid = _getpid();
    }
    return myPid;
}

/*
 * Working against the Process object and it's related counters is inherently problematic
 * when using the PDH API:
 *
 * For PDH, a process is not primarily identified by it's process id,
 * but with a sequential number, for example \Process(java#0), \Process(java#1), ....
 * The really bad part is that this list is reset as soon as one process exits:
 * If \Process(java#1) exits, \Process(java#3) now becomes \Process(java#2) etc.
 *
 * The PDH query api requires a process identifier to be submitted when registering
 * a query, but as soon as the list resets, the query is invalidated (since the name
 * changed).
 *
 * Solution:
 * The #number identifier for a Process query can only decrease after process creation.
 *
 * Therefore we create an array of counter queries for all process object instances
 * up to and including ourselves:
 *
 * Ex. we come in as third process instance (java#2), we then create and register
 * queries for the following Process object instances:
 * java#0, java#1, java#2
 *
 * currentQueryIndexForProcess() keeps track of the current "correct" query
 * (in order to keep this index valid when the list resets from underneath,
 * ensure to call getCurrentQueryIndexForProcess() before every query involving
 * Process object instance data).
 */
static int
currentQueryIndexForProcess(void) {
    HQUERY tmpQuery = NULL;
    HCOUNTER handleCounter = NULL;
    int retValue = -1;

    assert(pdhProcessImageName);
    assert(pdhIDProcessCounterFmt);

    if (openQuery(&tmpQuery) == 0) {
        int index;

        /* iterate over all instance indexes and try to find our own pid */
        for (index = 0; index < INT_MAX; ++index) {
            char fullIDProcessCounterPath[MAX_PATH];
            PDH_FMT_COUNTERVALUE counterValue;
            PDH_STATUS res;

            _snprintf(fullIDProcessCounterPath,
                      MAX_PATH,
                      pdhIDProcessCounterFmt,
                      index);

            if (addCounter(tmpQuery, fullIDProcessCounterPath, &handleCounter) != 0) {
                break;
            }

            res = PdhCollectQueryData_i(tmpQuery);

            if (PDH_INVALID_HANDLE == res || PDH_NO_DATA == res) {
                break;
            }

            PdhGetFormattedCounterValue_i(handleCounter,
                                          PDH_FMT_LONG,
                                          NULL,
                                          &counterValue);
            /*
             * This check seems to be needed for Win2k SMP boxes, since
             * they for some reason don't return PDH_NO_DATA for non existing
             * counters.
             */
            if (counterValue.CStatus != PDH_CSTATUS_VALID_DATA) {
                break;
            }

            if ((LONG)getProcessID() == counterValue.longValue) {
                retValue = index;
                break;
            }
        }
    }

    pdhCleanup(&tmpQuery, &handleCounter);

    return retValue;
}

/*
 * If successful, returns the #index corresponding to our PID
 * as resolved by the pdh query:
 * "\Process(java#index)\ID Process" (or localized equivalent)
 *
 * This function should be called before attempting to read
 * from any Process related counter(s), and the return value
 * is the index to be used for indexing an array of Process object query's:
 *
 * Example:
 * processTotalCPULoad[currentQueryIndex].query
 *
 * Returns -1 on failure.
 */
static int
getCurrentQueryIndexForProcess() {
    int currentQueryIndex = currentQueryIndexForProcess();

    assert(currentQueryIndex >= 0 &&
           currentQueryIndex < numberOfJavaProcessesAtInitialization);

    return currentQueryIndex;
}

/*
 * Returns the PDH string identifying the current process image name.
 * Use this name as a qualifier when getting counters from the PDH Process Object
 * representing your process.

 * Example:
 * "\Process(java#0)\Virtual Bytes" - where "java" is the PDH process
 * image name.
 *
 * Please note that the process image name is not necessarily "java",
 * hence the use of GetModuleFileName() to detect the process image name.
 *
 * @return   the process image name to be used when retrieving
 *           PDH counters from the current process. The caller will
             own the returned malloc:ed string. NULL if failure.
 */
static const char*
getPdhProcessImageName() {
    char moduleName[MAX_PATH];
    char* processImageName;
    char* dotPos;

    // Find our module name and use it to extract the image name used by PDH
    DWORD getmfnReturn = GetModuleFileName(NULL, moduleName, sizeof(moduleName));

    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
        return NULL;
    }

    if (getmfnReturn >= MAX_PATH || 0 == getmfnReturn) {
        return NULL;
    }

    processImageName = strrchr(moduleName, '\\'); //drop path
    processImageName++;                           //skip slash
    dotPos = strrchr(processImageName, '.');      //drop .exe
    dotPos[0] = '\0';

    return allocateAndCopy(processImageName);
}

/*
 * Sets up the supplied MultipleCounterQuery to check on the processors via PDH CPU counters.
 * TODO: Refactor and prettify as with the the SingleCounter queries
 * if more MultipleCounterQueries are discovered/needed.
 *
 * @param multiCounterCPULoad  a pointer to a MultipleCounterQueryS, will be filled in with
 *                             the necessary info to check the PDH processor counters.
 * @return                     0 if successful, negative on failure.
 */
static int
initializeMultipleCounterForCPUs(MultipleCounterQueryP multiCounterCPULoad) {
    DWORD cSize = 0;
    DWORD iSize = 0;
    DWORD pCount;
    DWORD index;
    char* processor = NULL; //'Processor' == PDH_PROCESSOR_IDX
    char* time = NULL;      //'Time' == PDH_PROCESSOR_TIME_IDX
    char* instances = NULL;
    char* tmp;
    int   retValue = -1;
    PDH_STATUS pdhStat;

    if (lookupNameByIndex(PDH_PROCESSOR_IDX, &processor) != 0) {
        goto end;
    }

    if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX, &time) != 0) {
        goto end;
    }

    //ok, now we have enough to enumerate all processors.
    pdhStat = PdhEnumObjectItems_i(
                                   NULL, // reserved
                                   NULL, // local machine
                                   processor, // object to enumerate
                                   NULL, // pass in NULL buffers
                                   &cSize, // and 0 length to get
                                   NULL, // required size
                                   &iSize, // of the buffers in chars
                                   PERF_DETAIL_WIZARD, // counter detail level
                                   0);

    if (pdhFail(pdhStat)) {
        goto end;
    }

    instances = calloc(iSize, 1);

    if (!instances) {
        goto end;
    }

    cSize = 0;

    pdhStat = PdhEnumObjectItems_i(
                                   NULL, // reserved
                                   NULL, // local machine
                                   processor, // object to enumerate
                                   NULL, // pass in NULL buffers
                                   &cSize,
                                   instances, // now allocated to be filled in
                                   &iSize, // and size is known
                                   PERF_DETAIL_WIZARD, // counter detail level
                                   0);

    if (pdhFail(pdhStat)) {
        goto end;
    }

    // enumerate the Processor instances ("\Processor(0)", "\Processor(1)", ..., "\Processor(_Total)")
    for (pCount = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], pCount++);

    assert(pCount == numCpus+1);

    //ok, we now have the number of Processor instances - allocate an HCOUNTER for each
    multiCounterCPULoad->counters = (HCOUNTER*)malloc(pCount * sizeof(HCOUNTER));

    if (!multiCounterCPULoad->counters) {
        goto end;
    }

    multiCounterCPULoad->noOfCounters = pCount;

    if (openQuery(&multiCounterCPULoad->query.query) != 0) {
        goto end;
    }

    // fetch instance and register its corresponding HCOUNTER with the query
    for (index = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], ++index) {
        const char* const fullCounterPath = makeFullCounterPath(processor, time, NULL, tmp);

        if (!fullCounterPath) {
            goto end;
        }

        retValue = addCounter(multiCounterCPULoad->query.query,
                              fullCounterPath,
                              &multiCounterCPULoad->counters[index]);

        free((char*)fullCounterPath);

        if (retValue != 0) {
            goto end;
        }
    }

    // Query once to initialize the counters which require at least two samples
    // (like the % CPU usage) to calculate correctly.
    PdhCollectQueryData_i(multiCounterCPULoad->query.query);

  end:
    if (processor) {
        free(processor);
    }

    if (time) {
        free(time);
    }

    if (instances) {
        free(instances);
    }

    return retValue;
}

/*
 * Dynamically sets up function pointers to the PDH library.
 *
 * @param h  HMODULE for the PDH library
 * @return   0 on success, negative on failure.
 */
static int
bindPdhFunctionPointers(HMODULE h) {
    assert(h);
    assert(GetCurrentThreadId() == initializationLock.owningThread);

    /* The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods */
    PdhAddCounter_i         = (PdhAddCounterFunc)GetProcAddress(h, "PdhAddCounterA");
    PdhOpenQuery_i         = (PdhOpenQueryFunc)GetProcAddress(h, "PdhOpenQueryA");
    PdhCloseQuery_i         = (PdhCloseQueryFunc)GetProcAddress(h, "PdhCloseQuery");
    PdhCollectQueryData_i     = (PdhCollectQueryDataFunc)GetProcAddress(h, "PdhCollectQueryData");
    PdhGetFormattedCounterValue_i = (PdhGetFormattedCounterValueFunc)GetProcAddress(h, "PdhGetFormattedCounterValue");
    PdhEnumObjectItems_i         = (PdhEnumObjectItemsFunc)GetProcAddress(h, "PdhEnumObjectItemsA");
    PdhRemoveCounter_i         = (PdhRemoveCounterFunc)GetProcAddress(h, "PdhRemoveCounter");
    PdhLookupPerfNameByIndex_i     = (PdhLookupPerfNameByIndexFunc)GetProcAddress(h, "PdhLookupPerfNameByIndexA");

    if (!PdhAddCounter_i || !PdhOpenQuery_i ||
        !PdhCloseQuery_i || !PdhCollectQueryData_i ||
        !PdhGetFormattedCounterValue_i || !PdhEnumObjectItems_i ||
        !PdhRemoveCounter_i || !PdhLookupPerfNameByIndex_i)
    {
        return -1;
    }
    return 0;
}

/*
 * Returns the counter value as a double for the specified query.
 * Will collect the query data and update the counter values as necessary.
 *
 * @param query       the query to update (if needed).
 * @param c           the counter to read.
 * @param value       where to store the formatted value.
 * @param format      the format to use (i.e. PDH_FMT_DOUBLE, PDH_FMT_LONG etc)
 * @return            0 if no error
 *                    -1 if PdhCollectQueryData fails
 *                    -2 if PdhGetFormattedCounterValue fails
 */
static int
getPerformanceData(UpdateQueryP query, HCOUNTER c, PDH_FMT_COUNTERVALUE* value, DWORD format) {
    clock_t now = clock();

    /*
     * Need to limit how often we update the query
     * to minimize the Heisenberg effect.
     * (PDH behaves erratically if the counters are
     * queried too often, especially counters that
     * store and use values from two consecutive updates,
     * like cpu load.)
     */
    if (now - query->lastUpdate > MIN_UPDATE_INTERVAL) {
        if (PdhCollectQueryData_i(query->query) != ERROR_SUCCESS) {
            return -1;
        }
        query->lastUpdate = now;
    }

    if (PdhGetFormattedCounterValue_i(c, format, NULL, value) != ERROR_SUCCESS) {
        return -2;
    }

    return 0;
}

static int
allocateAndInitializePdhConstants() {
    const char* pdhLocalizedProcessObject = NULL;
    const char* pdhLocalizedIDProcessCounter = NULL;
    size_t pdhIDProcessCounterFmtLen;
    int currentQueryIndex;
    int retValue = -1;

    assert(GetCurrentThreadId() == initializationLock.owningThread);

    assert(!pdhProcessImageName);
    pdhProcessImageName = getPdhProcessImageName();
    if (!pdhProcessImageName) {
        goto end;
    }

    pdhLocalizedProcessObject = getPdhLocalizedArtifact(PDH_PROCESS_IDX);
    if (!pdhLocalizedProcessObject) {
        goto end;
    }

    pdhLocalizedIDProcessCounter = getPdhLocalizedArtifact(PDH_ID_PROCESS_IDX);
    if (!pdhLocalizedIDProcessCounter) {
        goto end;
    }

    assert(!pdhIDProcessCounterFmt);

    pdhIDProcessCounterFmtLen = strlen(pdhProcessImageName);
    pdhIDProcessCounterFmtLen += strlen(pdhLocalizedProcessObject);
    pdhIDProcessCounterFmtLen += strlen(pdhLocalizedIDProcessCounter);
    pdhIDProcessCounterFmtLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
    pdhIDProcessCounterFmtLen += 2; // "%d"

    assert(pdhIDProcessCounterFmtLen < MAX_PATH);
    pdhIDProcessCounterFmt = malloc(pdhIDProcessCounterFmtLen + 1);
    if (!pdhIDProcessCounterFmt) {
        goto end;
    }

    /* "\Process(java#%d)\ID Process" */
    _snprintf(pdhIDProcessCounterFmt,
              pdhIDProcessCounterFmtLen,
              PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
              pdhLocalizedProcessObject,
              pdhProcessImageName,
              "%d",
              pdhLocalizedIDProcessCounter);

    pdhIDProcessCounterFmt[pdhIDProcessCounterFmtLen] = '\0';

    assert(0 == numberOfJavaProcessesAtInitialization);
    currentQueryIndex = currentQueryIndexForProcess();
    if (-1 == currentQueryIndex) {
        goto end;
    }

    numberOfJavaProcessesAtInitialization = currentQueryIndex + 1;
    assert(numberOfJavaProcessesAtInitialization >= 1);

    retValue = 0;

  end:

    if (pdhLocalizedProcessObject) {
        free((char*)pdhLocalizedProcessObject);
    }

    if (pdhLocalizedIDProcessCounter) {
        free((char*)pdhLocalizedIDProcessCounter);
    }

    return retValue;
}

static void
deallocatePdhConstants() {
    assert(GetCurrentThreadId() == initializationLock.owningThread);

    if (pdhProcessImageName) {
        free((char*)pdhProcessImageName);
        pdhProcessImageName = NULL;
    }

    if (pdhIDProcessCounterFmt) {
      free(pdhIDProcessCounterFmt);
      pdhIDProcessCounterFmt = NULL;
    }

    numberOfJavaProcessesAtInitialization = 0;
}

static int
initializeCPUCounters() {
    SYSTEM_INFO si;
    char* localizedProcessObject;
    char* localizedProcessorTimeCounter;
    int i;
    int retValue = -1;

    assert(GetCurrentThreadId() == initializationLock.owningThread);

    assert(0 == numCpus);
    GetSystemInfo(&si);
    numCpus = si.dwNumberOfProcessors;
    assert(numCpus >= 1);

    /* Initialize the denominator for the jvm load calculations */
    assert(.0 == cpuFactor);
    cpuFactor = numCpus * 100;

    if (lookupNameByIndex(PDH_PROCESS_IDX,
                          &localizedProcessObject) == 0) {

        if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX,
                              &localizedProcessorTimeCounter) == 0) {

            assert(processTotalCPULoad);
            assert(pdhProcessImageName);

            for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
                char instanceIndexBuffer[32];
                retValue = initializeSingleCounter(&processTotalCPULoad[i],
                                                   localizedProcessObject,
                                                   localizedProcessorTimeCounter,
                                                   pdhProcessImageName,
                                                   itoa(i, instanceIndexBuffer, 10),
                                                   TRUE);
                if (retValue != 0) {
                    break;
                }
            }
            free(localizedProcessorTimeCounter);
        }
        free(localizedProcessObject);
    }

    if (retValue != 0) {
        return -1;
    }

    assert(multiCounterCPULoad);
    return initializeMultipleCounterForCPUs(multiCounterCPULoad);
}

static void
deallocateCPUCounters() {
    int i;

    assert(GetCurrentThreadId() == initializationLock.owningThread);

    if (processTotalCPULoad) {
        for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
            destroySingleCounter(&processTotalCPULoad[i]);
        }
        free(processTotalCPULoad);
        processTotalCPULoad = NULL;
    }

    if (multiCounterCPULoad) {
        destroyMultiCounter(multiCounterCPULoad);
        free(multiCounterCPULoad);
        multiCounterCPULoad = NULL;
    }

    cpuFactor = .0;
    numCpus = 0;
}

static void
pdhInitErrorHandler(HMODULE h) {
    assert(GetCurrentThreadId() == initializationLock.owningThread);

    deallocatePdhConstants();

    if (h) {
        FreeLibrary(h);
    }
}

/*
 * Helper to initialize the PDH library, function pointers and constants.
 *
 * @return  0 if successful, negative on failure.
 */
static int
pdhInit() {
    static BOOL initialized = FALSE;
    int retValue;

    if (initialized) {
        return 0;
    }

    retValue = 0;

    EnterPdhCriticalSection(&initializationLock); {
        if (!initialized) {
            HMODULE h = NULL;
            if ((h = LoadLibrary("pdh.dll")) == NULL) {
                retValue = -1;
            } else if (bindPdhFunctionPointers(h) < 0) {
                retValue = -1;
            } else if (allocateAndInitializePdhConstants() < 0) {
                retValue = -1;
            }

            if (0 == retValue) {
                initialized = TRUE;
            } else {
                pdhInitErrorHandler(h);
            }
        }
    } LeavePdhCriticalSection(&initializationLock);

    return retValue;
}

static int
allocateCPUCounters() {
    assert(GetCurrentThreadId() == initializationLock.owningThread);
    assert(numberOfJavaProcessesAtInitialization >= 1);
    assert(!processTotalCPULoad);
    assert(!multiCounterCPULoad);

    /*
     * Create an array of Process object queries, for each instance
     * up to and including our own (java#0, java#1, java#2, ...).
     */
    processTotalCPULoad = calloc(numberOfJavaProcessesAtInitialization,
                                 sizeof(SingleCounterQueryS));

    if (!processTotalCPULoad) {
        return -1;
    }

    multiCounterCPULoad = calloc(1, sizeof(MultipleCounterQueryS));

    if (!multiCounterCPULoad) {
        return -1;
    }

    return 0;
}

static int
initializePdhCPUCounters() {
    static BOOL initialized = FALSE;
    int retValue;

    if (initialized) {
        return 0;
    }

    retValue = 0;

    EnterPdhCriticalSection(&initializationLock); {
        if (!initialized) {
            if (pdhInit() < 0) {
                retValue = -1;
            }  else if (allocateCPUCounters() < 0) {
                retValue = -1;
            } else if (initializeCPUCounters() < 0) {
                retValue = -1;
            }

            if (0 == retValue) {
                initialized = TRUE;
            } else {
              deallocateCPUCounters();
            }
        }
    } LeavePdhCriticalSection(&initializationLock);

    return retValue;
}

static int
perfCPUInit() {
    return initializePdhCPUCounters();
}

static double
perfGetProcessCPULoad() {
    PDH_FMT_COUNTERVALUE cv;
    int currentQueryIndex;

    if (perfCPUInit() < 0) {
        // warn?
        return -1.0;
    }

    currentQueryIndex = getCurrentQueryIndexForProcess();

    if (getPerformanceData(&processTotalCPULoad[currentQueryIndex].query,
                           processTotalCPULoad[currentQueryIndex].counter,
                           &cv,
                           PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == 0) {
        double d = cv.doubleValue / cpuFactor;
        d = min(1, d);
        d = max(0, d);
        return d;
    }
    return -1.0;
}

static double
perfGetCPULoad(int which) {
    PDH_FMT_COUNTERVALUE cv;
    HCOUNTER c;

    if (perfCPUInit() < 0) {
        // warn?
        return -1.0;
    }

    if (-1 == which) {
        c = multiCounterCPULoad->counters[multiCounterCPULoad->noOfCounters - 1];
    } else {
        if (which < multiCounterCPULoad->noOfCounters) {
            c = multiCounterCPULoad->counters[which];
        } else {
            return -1.0;
        }
    }
    if (getPerformanceData(&multiCounterCPULoad->query, c, &cv, PDH_FMT_DOUBLE ) == 0) {
        return cv.doubleValue / 100;
    }
    return -1.0;
}

JNIEXPORT jdouble JNICALL
Java_sun_management_OperatingSystemImpl_getSystemCpuLoad
(JNIEnv *env, jobject dummy)
{
    return perfGetCPULoad(-1);
}

JNIEXPORT jdouble JNICALL
Java_sun_management_OperatingSystemImpl_getProcessCpuLoad
(JNIEnv *env, jobject dummy)
{
    return perfGetProcessCPULoad();
}
