|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
procmon.c
Abstract:
Little program for recording the various idle states of a machine
Author:
John Vert (jvert) 1/14/2000
Revision History:
--*/ #include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <stdio.h>
#include <conio.h>
#define DISPLAY_TOTAL 0
#define DISPLAY_DELTA 1
#define DISPLAY_RAW 2
#define DISPLAY_INFO 3
#define DISPLAY_TRANS 4
int Display=DISPLAY_TOTAL; int LastDisplay=DISPLAY_TOTAL; LONG DelayTime = 5;
#define printtime(_x_) { \
ULONGLONG ms = (_x_)/10000; \ ULONG hours, minutes, seconds; \ hours = (ULONG)ms/(1000*60*60); \ if (hours) printf("%3d:",(ULONG)(ms/(1000*60*60))); \ ms=ms%(1000*60*60); \ minutes = (ULONG)ms/(1000*60); \ if (minutes || hours) printf("%02d:",(ULONG)(ms/(1000*60))); \ ms=ms%(1000*60); \ seconds = (ULONG)ms/1000; \ printf("%02d.",seconds); \ ms=ms%1000; \ printf("%03d",(ULONG)ms); \ }
__cdecl main (argc, argv) int argc; char *argv[]; { CHAR Buff[sizeof(SYSTEM_PROCESSOR_POWER_INFORMATION)*MAXIMUM_PROCESSORS]; PSYSTEM_PROCESSOR_POWER_INFORMATION PowerInfo = (PSYSTEM_PROCESSOR_POWER_INFORMATION)Buff; ULONG Length; NTSTATUS Status; UCHAR LastAdjustedBusyFrequency[MAXIMUM_PROCESSORS]; UCHAR LastBusyFrequency[MAXIMUM_PROCESSORS]; UCHAR LastC3Frequency[MAXIMUM_PROCESSORS]; ULONGLONG LastFrequencyTime[MAXIMUM_PROCESSORS]; ULONG PromotionCount[MAXIMUM_PROCESSORS]; ULONG DemotionCount[MAXIMUM_PROCESSORS]; ULONGLONG LastIdleTime[MAXIMUM_PROCESSORS]; ULONGLONG LastKernelTime[MAXIMUM_PROCESSORS]; ULONGLONG DeltaTime; ULONG i; ULONG NumProc; LARGE_INTEGER Delay; ULONG Delta;
for (i = 0; i < MAXIMUM_PROCESSORS; i++) {
LastFrequencyTime[i] = 0; PromotionCount[i] = DemotionCount[i] = 0;
}
while (1) { if (_kbhit()) { int Char=_getch(); switch (toupper(Char)) { case 'T': LastDisplay = Display = DISPLAY_TOTAL; break; case 'E': LastDisplay = Display = DISPLAY_TRANS; break; case 'D': LastDisplay = Display = DISPLAY_DELTA; break; case 'R': LastDisplay = Display = DISPLAY_RAW; break; case 'I': LastDisplay = Display; Display = DISPLAY_INFO; break; case '+': DelayTime++; printf("New delay is %d seconds.\n",DelayTime); break; case '-': if (DelayTime > 2) { DelayTime--; printf("New delay is %d seconds.\n",DelayTime); } else { printf("Delay cannot drop below %d seconds.\n",DelayTime); } break; case 'Q': return 0; case 'P': printf("Hit a key to continue\n"); _getch(); break;
default: printf("Type :\n"); printf("\t'T' - display Total\n"); printf("\t'E' - display Transitions\n"); printf("\t'D' - display Delta\n"); printf("\t'R' - display Raw\n"); printf("\t'I' - display quick info\n"); printf("\t'+'/'-' - increase/decrease time pause\n"); printf("\t'Q' - Quit\n"); printf("\t'P' - Pause\n");
} } Status = NtQuerySystemInformation( SystemProcessorPowerInformation, PowerInfo, sizeof(Buff), &Length ); if (!NT_SUCCESS(Status)) {
fprintf(stderr, "NtQuerySystemInformation failed: %lx\n",Status); return(Status);
}
NumProc = Length/sizeof(SYSTEM_PROCESSOR_POWER_INFORMATION); for (i=0;i<NumProc;i++) {
if (NumProc > 1) {
printf("%2d>",i);
}
switch (Display) { case DISPLAY_TOTAL: printf("Freq %3d%% (%3d%% %3d%% %3d%%) ", PowerInfo[i].CurrentFrequency, PowerInfo[i].LastAdjustedBusyFrequency, PowerInfo[i].LastBusyFrequency, PowerInfo[i].LastC3Frequency ); printtime(PowerInfo[i].CurrentFrequencyTime); printf(" Sys "); printtime(PowerInfo[i].CurrentProcessorTime); printf(" Idle "); printtime(PowerInfo[i].CurrentProcessorIdleTime); break; case DISPLAY_TRANS: printf("Freq %3d%% (%3d%% %3d%% %3d%%) ", PowerInfo[i].CurrentFrequency, PowerInfo[i].LastAdjustedBusyFrequency, PowerInfo[i].LastBusyFrequency, PowerInfo[i].LastC3Frequency ); printf("#P: %d #D %d #E: %d #R: %d", PowerInfo[i].PromotionCount, PowerInfo[i].DemotionCount, PowerInfo[i].ErrorCount, PowerInfo[i].RetryCount ); break; case DISPLAY_DELTA: printf("Freq %3d%% (%3d%% %3d%% %3d%%) ", PowerInfo[i].CurrentFrequency, (PowerInfo[i].LastAdjustedBusyFrequency - LastAdjustedBusyFrequency[i]), (PowerInfo[i].LastBusyFrequency - LastBusyFrequency[i]), (PowerInfo[i].LastC3Frequency - LastC3Frequency[i]) ); DeltaTime = PowerInfo[i].CurrentFrequencyTime - LastFrequencyTime[i]; printtime(DeltaTime); printf(" Sys "); printtime((PowerInfo[i].CurrentProcessorTime - LastKernelTime[i])); printf(" Idle "); printtime((PowerInfo[i].CurrentProcessorIdleTime - LastIdleTime[i])); break;
case DISPLAY_RAW: printf("Freq %3d%% (%3d%% %3d%% %3d%%) %I64X #E %8d #R %8d", PowerInfo[i].CurrentFrequency, PowerInfo[i].LastAdjustedBusyFrequency, PowerInfo[i].LastBusyFrequency, PowerInfo[i].LastC3Frequency, PowerInfo[i].CurrentFrequencyTime, PowerInfo[i].ErrorCount, PowerInfo[i].RetryCount ); break; case DISPLAY_INFO: printf("Frequencies: Current =%3d%% MaxProc =%3d%% MinProc =%3d%%\n" "Percentages: Adjusted=%3d%% Busy =%3d%% C3 =%3d%%\n" "Limiters: Thermal =%3d%% Constant=%3d%% Degraded=%3d%%\n" "Counts: Promote =%4d Demote =%4d\n" "Status: Retries =%4d Errors =%4d", PowerInfo[i].CurrentFrequency, PowerInfo[i].ProcessorMaxThrottle, PowerInfo[i].ProcessorMinThrottle, PowerInfo[i].LastAdjustedBusyFrequency, PowerInfo[i].LastBusyFrequency, PowerInfo[i].LastC3Frequency, PowerInfo[i].ThermalLimitFrequency, PowerInfo[i].ConstantThrottleFrequency, PowerInfo[i].DegradedThrottleFrequency, PowerInfo[i].PromotionCount, PowerInfo[i].DemotionCount, PowerInfo[i].RetryCount, PowerInfo[i].ErrorCount ); break; }
LastAdjustedBusyFrequency[i] = PowerInfo[i].LastAdjustedBusyFrequency; LastBusyFrequency[i] = PowerInfo[i].LastBusyFrequency; LastC3Frequency[i] = PowerInfo[i].LastC3Frequency; LastFrequencyTime[i] = PowerInfo[i].CurrentFrequencyTime; PromotionCount[i] = PowerInfo[i].PromotionCount; DemotionCount[i] = PowerInfo[i].DemotionCount; LastIdleTime[i] = PowerInfo[i].CurrentProcessorIdleTime; LastKernelTime[i] = PowerInfo[i].CurrentProcessorTime; printf("\n"); }
//
// Revert Back to whatever we were displaying before...
//
if (Display != LastDisplay) {
Display = LastDisplay;
}
Delay.QuadPart = - DelayTime * 1000 * 1000 * 10; NtDelayExecution(FALSE, &Delay); } return 0; }
|