unit
qraTaskCpu;
interface
uses
windows;
function
GetCPUUsage :
byte
;
implementation
const
SystemBasicInformation =
0
;
SystemPerformanceInformation =
2
;
SystemTimeInformation =
3
;
type
TPDWord = ^DWORD;
TSystem_Basic_Information =
packed
record
dwUnknown1: DWORD;
uKeMaximumIncrement: ULONG;
uPageSize: ULONG;
uMmNumberOfPhysicalPages: ULONG;
uMmLowestPhysicalPage: ULONG;
uMmHighestPhysicalPage: ULONG;
uAllocationGranularity: ULONG;
pLowestUserAddress:
Pointer
;
pMmHighestUserAddress:
Pointer
;
uKeActiveProcessors: ULONG;
bKeNumberProcessors:
byte
;
bUnknown2:
byte
;
wUnknown3:
word
;
end
;
type
TSystem_Performance_Information =
packed
record
liIdleTime: LARGE_INTEGER;
dwSpare:
array
[
0..75
]
of
DWORD;
end
;
type
TSystem_Time_Information =
packed
record
liKeBootTime: LARGE_INTEGER;
liKeSystemTime: LARGE_INTEGER;
liExpTimeZoneBias: LARGE_INTEGER;
uCurrentTimeZoneId: ULONG;
dwReserved: DWORD;
end
;
var
NtQuerySystemInformation:
function
(infoClass: DWORD;
buffer:
Pointer
;
bufSize: DWORD;
returnSize: TPDword): DWORD; stdcall =
nil
;
liOldIdleTime: LARGE_INTEGER = ();
liOldSystemTime: LARGE_INTEGER = ();
function
Li2Double(x: LARGE_INTEGER):
Double
;
begin
Result := x
.
HighPart *
4.
294967296E9 + x
.
LowPart
end
;
function
GetCPUUsage :
byte
;
var
SysBaseInfo: TSystem_Basic_Information;
SysPerfInfo: TSystem_Performance_Information;
SysTimeInfo: TSystem_Time_Information;
status:
Longint
;
dbSystemTime:
Double
;
dbIdleTime:
Double
;
begin
if
@NtQuerySystemInformation =
nil
then
NtQuerySystemInformation := GetProcAddress(GetModuleHandle(
'ntdll.dll'
),
'NtQuerySystemInformation'
);
status := NtQuerySystemInformation(SystemBasicInformation, @SysBaseInfo,
SizeOf(SysBaseInfo),
nil
);
if
status <>
0
then
Exit;
status := NtQuerySystemInformation(SystemTimeInformation, @SysTimeInfo,
SizeOf(SysTimeInfo),
0
);
if
status <>
0
then
Exit;
status := NtQuerySystemInformation(SystemPerformanceInformation,
@SysPerfInfo, SizeOf(SysPerfInfo),
nil
);
if
status <>
0
then
Exit;
if
(liOldIdleTime
.
QuadPart <>
0
)
then
begin
dbIdleTime := Li2Double(SysPerfInfo
.
liIdleTime) -
Li2Double(liOldIdleTime);
dbSystemTime := Li2Double(SysTimeInfo
.
liKeSystemTime) -
Li2Double(liOldSystemTime);
if
dbSystemTime <>
0
then
dbIdleTime := dbIdleTime / dbSystemTime
else
dbIdleTime :=
0
;
if
SysBaseInfo
.
bKeNumberProcessors <>
0
then
dbIdleTime :=
100.0
- dbIdleTime *
100.0
/ SysBaseInfo
.
bKeNumberProcessors
+
0.5
else
dbIdleTime :=
0
;
if
dbIdleTime >
100
then
dbIdleTime :=
0
;
result := Trunc(dbIdleTime);
end
;
liOldIdleTime := SysPerfInfo
.
liIdleTime;
liOldSystemTime := SysTimeInfo
.
liKeSystemTime;
end
;
end
.