Sunday, February 12, 2012

Measure CPU usage on Windows with PDH

On Windows to measure the CPU usage you need to use the Performance Data Helper (PDH). Microsoft distribute a dll (pdh.dll). Although not ideal you can link with this. Pdh.lib would be better but I have no idea where to get it. I'm going to describe how to measure total CPU usage using pdh.dll, and three headers, windows.h, pdh.h and pdhmsg.h. The latter two come with the Microsoft SDK. The tools I used were the MinGW tool set in NetBeans.

You have to do five things:

  1. Create a query using PdhOpenQuery.
  2. Add a counter to it via PdhAddCounter
  3. Call PdhCollectQueryData twice on the query, sleeping in between
  4. Call PdhGetFormattedCounterValue on the counter
  5. Close the query

Now you should have a formatted data value you can display using printf or whatever. Here's a minimal program that does it (proper error-handling is left as an exercise for the reader):

PDH_HQUERY query;
PDH_STATUS status = PdhOpenQuery(NULL,(DWORD_PTR)NULL,&query);
if (status==ERROR_SUCCESS )
{
  HCOUNTER hCounter;
  status = PdhAddCounter( query, 
    "\Processor(_Total)\% Processor Time", 0, &hCounter );
    if (status==ERROR_SUCCESS)
    {
      status = PdhCollectQueryData(query);
      if (status==ERROR_SUCCESS)
      {
        Sleep(1000);
        status = PdhCollectQueryData(query);
        DWORD ret;
        PDH_FMT_COUNTERVALUE value;
        status = PdhGetFormattedCounterValue(hCounter, 
          PDH_FMT_DOUBLE|PDH_FMT_NOCAP100,&ret,&value);
        if (status==ERROR_SUCCESS)
        {
          printf("CPU Total usage: %2.2f\n",value.doubleValue);
        }
        else
          printf("error\n");
      }
      else
        printf("error\n");
    }
    else
      printf("error\n");
    PdhCloseQuery( query );
  }
  else
    printf("error\n");
}

No comments:

Post a Comment