//
// Include files
//
// #include <ntos.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntexapi.h>
#include <windows.h>
extern VOID printf(UCHAR *,...);
// extern LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER);
#define MAX_CPUS 64 // supports maximum of 64 cpus...
// #include "tpdefs.h"
// #include "media.h"
// #include "tpprocs.h"
// #include "string.h"
PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION pStartData;
PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION pEndData;
ULONG NumCpus;
ULONG ProcessorBufSize;
PULONG pKernelPercent;
DWORD StartTestTime;
// --------------------------------------------------
//
// Function: TpPerfInitCpuUsage
//
// Arguments: none
//
// Returns: none
//
// Descript: This function allocates and initializes all the structures
// necessary for finding the %cpu usage during performance tests
//
// --------------------------------------------------
VOID
CpuUsageInit(VOID)
{
if (!NumCpus) // if NumCpus is zero, need to do first pass initializations
{ // (allocate all buffers, set NumCpus)
SYSTEM_BASIC_INFORMATION BasicInfo;
//
// First get the number of processors...
//
NtQuerySystemInformation(SystemBasicInformation,
&BasicInfo,
sizeof(SYSTEM_BASIC_INFORMATION),
NULL);
NumCpus = BasicInfo.NumberOfProcessors;
if ( (NumCpus < 1) || (NumCpus > MAX_CPUS) )
{
printf("CpuUsageInit: Illegal number of cpus\n");
goto init_abort;
}
//
// get the memory for the processor instance data
//
ProcessorBufSize = NumCpus * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
if ( (pStartData = GlobalAlloc(GMEM_FIXED, ProcessorBufSize)) == NULL)
{
printf("CpuUsageInit: unable to allocate pStartData buffer\n");
goto init_abort;
}
if ( (pEndData = GlobalAlloc(GMEM_FIXED, ProcessorBufSize)) == NULL)
{
printf("CpuUsageInit: unable to allocate pEndData buffer\n");
goto init_abort;
}
if ( (pKernelPercent = GlobalAlloc(GMEM_FIXED , (NumCpus + 1) * sizeof(ULONG))) == NULL)
{
printf("CpuUsageInit: unable to allocate pKernelPercent buffer\n");
init_abort:
if (pStartData)
{
GlobalFree(pStartData);
// pStartData = NULL;
}
if (pEndData)
{
GlobalFree(pEndData);
// pEndData = NULL
}
if (pKernelPercent)
{
GlobalFree(pKernelPercent);
// pKernelPercent = NULL;
}
NumCpus = 0;
return;
}
}
NtQuerySystemInformation(SystemProcessorPerformanceInformation,
pStartData,
ProcessorBufSize,
NULL);
StartTestTime = GetTickCount();
}
// ------------------------------------------------
//
// Function: TpPerfGetCpuUsage
//
// Arguments: oldptr -- cpu processor performance data from time 0
// ProcessorTime -- place to put processor times
// KernelTime -- place to put kernel times
//
// Returns: number of processors--0 if error
//
// Descript: This function reads the performance counters
// at the end of the test, stored them in an appropriate
// location, and then cleans up the structures and exits
//
// -------------------------------------------------
ULONG
CpuUsageGetData(PULONG *ppKernPC,
ULONG TestTime)
{
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *pOldProcessorInformation;
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *pNewProcessorInformation;
ULONG CurProc;
LARGE_INTEGER TotalProcessorTime;
LARGE_INTEGER TotalKernelTime;
LARGE_INTEGER TempUser;
LARGE_INTEGER TempKern;
LARGE_INTEGER TempIdle;
LARGE_INTEGER trash;
LARGE_INTEGER WholeTestTime;
DWORD EndTestTime;
ULONG flag;
if (!NumCpus)
{
printf("CpuUsageGetData: called before initialization\n");
return 0;
}
NtQuerySystemInformation(SystemProcessorPerformanceInformation,
pEndData,
ProcessorBufSize,
NULL);
//
// find the total time in milliseconds
//
EndTestTime = GetTickCount();
// if (EndTestTime > StartTestTime)
// {
WholeTestTime.LowPart = EndTestTime - StartTestTime;
// }
// else
// {
//
// }
// WholeTestTime.LowPart = GetTickCount() - StartTestTime;
WholeTestTime.HighPart = 0;
// printf("Kludge factor = %d/%d\n", TestTime, WholeTestTime.LowPart);
TotalProcessorTime.HighPart = 0;
TotalProcessorTime.LowPart = 0;
TotalKernelTime.HighPart = 0;
TotalKernelTime.LowPart = 0;
//
// Total time = UserTime + KernelTime
// KernelTime = IdleTime + Priviledged time
// We need total time and priviledged time
//
pOldProcessorInformation = pStartData;
pNewProcessorInformation = pEndData;
for ( CurProc = 0; CurProc < NumCpus; CurProc++ )
{
// DEBUG
// printf("\nCpuUsageGetData: processor %d\n", CurProc);
// printf("Initial Idletime = %08x%08x\n", pOldProcessorInformation->IdleTime.HighPart,
// pOldProcessorInformation->IdleTime.LowPart);
// printf("Initial Usertime = %08x%08x\n", pOldProcessorInformation->UserTime.HighPart,
// pOldProcessorInformation->UserTime.LowPart);
// printf("Initial Kerntime = %08x%08x\n\n", pOldProcessorInformation->KernelTime.HighPart,
// pOldProcessorInformation->KernelTime.LowPart);
//
// printf("Final Idletime = %08x%08x\n", pNewProcessorInformation->IdleTime.HighPart,
// pNewProcessorInformation->IdleTime.LowPart);
// printf("Final Usertime = %08x%08x\n", pNewProcessorInformation->UserTime.HighPart,
// pNewProcessorInformation->UserTime.LowPart);
// printf("Final Kerntime = %08x%08x\n\n", pNewProcessorInformation->KernelTime.HighPart,
// pNewProcessorInformation->KernelTime.LowPart);
// END DEBUG
// first, find all the deltas...
TempUser = RtlLargeIntegerSubtract(pNewProcessorInformation->UserTime,
pOldProcessorInformation->UserTime);
TempKern = RtlLargeIntegerSubtract(pNewProcessorInformation->KernelTime,
pOldProcessorInformation->KernelTime);
TempIdle = RtlLargeIntegerSubtract(pNewProcessorInformation->IdleTime,
pOldProcessorInformation->IdleTime);
// check for wrapping
// if (pOldProcessor->UserTime.HighPart > pNewProcessorInformation->UserTime.HighPart)
// {
//
// }
// printf("Delta IdleTime = %08x%08x\n", TempIdle.HighPart, TempIdle.LowPart);
// printf("Delta UserTime = %08x%08x\n", TempUser.HighPart, TempUser.LowPart);
// printf("Delta KernTime = %08x%08x\n", TempKern.HighPart, TempKern.LowPart);
// now find the total processor time = UserTime + KernelTime
TempUser = RtlLargeIntegerAdd(TempUser, TempKern);
// printf("Total ProcTime = %08x%08x\n", TempUser.HighPart, TempUser.LowPart);
// adjust by kludge factor -- TestTime/WholeTestTime
TempUser = RtlExtendedIntegerMultiply(TempUser, TestTime);
TempUser = RtlLargeIntegerDivide(TempUser, WholeTestTime, &trash);
if ((TempUser.HighPart == 0) && (TempUser.LowPart < 10)) // sanity check
{
flag = 0;
printf("Kludge factor = %d/%d\n", TestTime, WholeTestTime.LowPart);
printf("Adjusted ProcTime = %08x%08x\n", TempUser.HighPart, TempUser.LowPart);
}
else
{
flag = 1;
}
TotalProcessorTime = RtlLargeIntegerAdd(TotalProcessorTime, TempUser);
// now find the true kernel time = KernelTime - IdleTime
TempKern = RtlLargeIntegerSubtract(TempKern, TempIdle);
// printf("True KernTime = %08x%08x\n", TempKern.HighPart, TempKern.LowPart);
if (TempKern.HighPart < 0)
{
TempKern.HighPart = 0;
TempKern.LowPart = 0;
}
TotalKernelTime = RtlLargeIntegerAdd(TotalKernelTime, TempKern);
//
// finally, calc the percent kernel is of total
//
if (flag)
{
TempKern = RtlExtendedIntegerMultiply(TempKern, 1000);
TempKern = RtlLargeIntegerDivide(TempKern, TempUser, &trash);
}
else
{
TempKern.LowPart = 0;
}
pKernelPercent[CurProc+1] = TempKern.LowPart;
// move to info for next processor
pNewProcessorInformation++;
pOldProcessorInformation++;
}
//
// last of all, calc the percent kernel is of total
//
if ((TotalProcessorTime.HighPart == 0) && (TotalProcessorTime.LowPart < 10))
{
TempKern.LowPart = 0;
}
else
{
TempKern = RtlExtendedIntegerMultiply(TotalKernelTime, 1000);
TempKern = RtlLargeIntegerDivide(TempKern, TotalProcessorTime, &trash);
}
pKernelPercent[0] = TempKern.LowPart;
*ppKernPC = pKernelPercent;
return NumCpus;
}