-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathCPULimiter.cpp
More file actions
80 lines (63 loc) · 2.56 KB
/
Copy pathCPULimiter.cpp
File metadata and controls
80 lines (63 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "CPULimiter.h"
CPULimiter::CPULimiter(int p_ratio)
{
m_ratio = p_ratio;
}
bool CPULimiter::CalculateAndSleep()
{
// Declare variables;
FILETIME sysidle, kerusage, userusage, threadkern
, threaduser, threadcreat, threadexit;
LARGE_INTEGER tmpvar, thissystime, thisthreadtime;
// Get system kernel, user and idle times
if (!::GetSystemTimes(&sysidle, &kerusage, &userusage))
return false;
// Get Thread user and kernel times
if (!::GetThreadTimes(GetCurrentThread(), &threadcreat, &threadexit
, &threadkern, &threaduser))
return false;
// Calculates total system times
// This is sum of time used by system in kernel, user and idle mode.
tmpvar.LowPart = sysidle.dwLowDateTime;
tmpvar.HighPart = sysidle.dwHighDateTime;
thissystime.QuadPart = tmpvar.QuadPart;
tmpvar.LowPart = kerusage.dwLowDateTime;
tmpvar.HighPart = kerusage.dwHighDateTime;
thissystime.QuadPart = thissystime.QuadPart + tmpvar.QuadPart;
tmpvar.LowPart = userusage.dwLowDateTime;
tmpvar.HighPart = userusage.dwHighDateTime;
thissystime.QuadPart = thissystime.QuadPart + tmpvar.QuadPart;
// Calculates time spent by this thread in user and kernel mode.
tmpvar.LowPart = threadkern.dwLowDateTime;
tmpvar.HighPart = threadkern.dwHighDateTime;
thisthreadtime.QuadPart = tmpvar.QuadPart;
tmpvar.LowPart = threaduser.dwLowDateTime;
tmpvar.HighPart = threaduser.dwHighDateTime;
thisthreadtime.QuadPart = thisthreadtime.QuadPart + tmpvar.QuadPart;
// Check if this is first time this function is called
// if yes, escape rest after copying current system and thread time
// for further use
// Also check if the ratio of differences between current and previous times
// exceeds the specified ratio.
if (thisthreadtime.QuadPart != 0
&& (((thisthreadtime.QuadPart - m_lastThreadUsageTime.QuadPart) * 100)
- ((thissystime.QuadPart - m_lastTotalSystemTime.QuadPart)*m_ratio)) > 0)
{
// Calculate the time interval to sleep for averaging the extra CPU usage
// by this thread.
LARGE_INTEGER timetosleepin100ns;
timetosleepin100ns.QuadPart = (((thisthreadtime.QuadPart
- m_lastThreadUsageTime.QuadPart) * 100) / m_ratio)
- (thissystime.QuadPart
- m_lastTotalSystemTime.QuadPart);
// Check if time is less than a millisecond, if yes, keep it for next time.
if ((timetosleepin100ns.QuadPart / 10000) <= 0)
return false;
// Time to Sleep :)
Sleep(timetosleepin100ns.QuadPart / 10000);
}
// Copy usage time values for next time calculations.
m_lastTotalSystemTime.QuadPart = thissystime.QuadPart;
m_lastThreadUsageTime.QuadPart = thisthreadtime.QuadPart;
return true;
}