mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
307 lines
9.5 KiB
307 lines
9.5 KiB
//
|
|
// 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;
|
|
}
|
|
|