Code archives/Miscellaneous/Simple CPU monitor (Windows)

This code has been declared by its author to be Public Domain code.

Download source code

Simple CPU monitor (Windows) by BlitzSupport2014
This seems to work, though please note that it requires at least Windows XP SP1.

It gives the same results as Task Manager's "CPU Usage", ie. the overall processor usage across all processes/CPUs.

Please note that for reasons unknown, you must sample more than once per second or the results go haywire!

Run it and start a high CPU process to test.

Works for me, anyway...
SuperStrict

Extern "win32"
	Function GetSystemTimes (lpIdleTime:Byte Ptr, lpKernelTime:Byte Ptr, lpUserTime:Byte Ptr)
End Extern

Type Win32FileTime
	Field lo:Int
	Field hi:Int
End Type

Type CPUMonitor

	' References...
	
	' http://www.codeproject.com/Articles/9113/Get-CPU-Usage-with-GetSystemTimes
	' http://www.purebasic.fr/english/viewtopic.php?t=26200&start=3
	' http://msdn.microsoft.com/en-us/library/windows/desktop/ms724400%28v=vs.85%29.aspx

	Const SAMPLES:Int = 3

	Field cpu_sample:Int [SAMPLES]
	
	Field idle:Win32FileTime = New Win32FileTime
	Field kern:Win32FileTime = New Win32FileTime
	Field user:Win32FileTime = New Win32FileTime
	
	Field last_idle:Win32FileTime = New Win32FileTime
	Field last_kern:Win32FileTime = New Win32FileTime
	Field last_user:Win32FileTime = New Win32FileTime

	' Pass False for realtime value, though result will fluctuate a lot more...

	Method Usage:Int (average:Int = True)
	
		GetSystemTimes idle, kern, user
		
		' Apparently only need the 'low' part of the FILETIME structure...
		
		Local idl:Int = idle.lo - last_idle.lo
		Local krn:Int = kern.lo - last_kern.lo
		Local usr:Int = user.lo - last_user.lo
	
		last_idle.lo = idle.lo
		last_kern.lo = kern.lo
		last_user.lo = user.lo
	
		Local sys:Int = krn + usr
		
		Local cpu:Int
		
		If sys
			cpu = Int ((sys - idl) * 100 / sys)
		Else
			cpu = 0
		EndIf
	
		If average
		
			Local avg_cpu:Int = 0
			
			For Local loop:Int = 0 Until SAMPLES - 1
				cpu_sample [loop] = cpu_sample [loop + 1]
				'Print "cpu_sample [" + loop + "] = " + cpu_sample [loop]
				avg_cpu = avg_cpu + cpu_sample [loop]
			Next
			
			cpu_sample [SAMPLES - 1] = cpu
		
			avg_cpu = avg_cpu + cpu_sample [SAMPLES - 1]
			
			avg_cpu = avg_cpu / SAMPLES
			
			' Print "Current sample: " + cpu + " (Average of last three samples: " + avg_cpu + ")"
		
			If avg_cpu < 0 Then avg_cpu = 0
			
			Return avg_cpu
			
		Else
		
			If cpu < 0 Then cpu = 0
			
			Return cpu
			
		EndIf
		
	End Method
	
End Type

' D E M O . . .

Local cpu:CPUMonitor = New CPUMonitor

Repeat
	
	Print "Average CPU usage: " + cpu.Usage () + "%"
'	Print "Current CPU usage: " + cpu.Usage (False) + "%"
	
	Delay 100 ' Sampling every 1000 ms or more will give errors! Don't know why...
	
Until KeyHit (KEY_ESCAPE)

End

Comments

BlitzSupport2014
Just used this to create an Arduino/LoLShield-based CPU monitor! (This was in fact the reason I wrote it.)



https://www.youtube.com/watch?v=kwA0F0manK0

Download of BlitzMax/Arduino project on that link -- needs Brucey's serial.mod.


Grisu2014
Thanks for sharing! Works fine under Win 8.1 (64 Bit).


Who was John Galt?2014
Very cool James. Bonus point for anything involving an Arduino, too.


BlitzSupport2014
Glad to hear it works elsewhere!

@John, yeah, apart from the basic 'blink' and supplied LoLShield tests, this was my first Arduino test!

Just received a generic electronics kit/book aimed at the Arduino, and looking forward to trying it out... my Big-Trak seems somewhat less excited, though...


Who was John Galt?2014
Here come the killer robots... ;)


BlitzSupport2014
I think *flying* killer robots (that can also make and deliver the perfect cup of tea) will be my first project. Gotta start small...


Who was John Galt?2014
Brilliant, looking forward to seeing it! Small,eh?


Code Archives Forum