-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
MasterCna
committed
Feb 22, 2018
1 parent
cb087ed
commit 28290fc
Showing
2 changed files
with
134 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#include "CPULimiter.h" | ||
|
||
//constructors | ||
CPULimiter::CPULimiter(int p_ratio) | ||
:m_ratio(p_ratio) | ||
{ | ||
::ZeroMemory( &m_lastTotalSystemTime, sizeof(LARGE_INTEGER)); | ||
::ZeroMemory( &m_lastThreadUsageTime, sizeof(LARGE_INTEGER)); | ||
} | ||
|
||
CPULimiter::CPULimiter() | ||
{ | ||
::ZeroMemory( &m_lastTotalSystemTime, sizeof(LARGE_INTEGER)); | ||
::ZeroMemory( &m_lastThreadUsageTime, sizeof(LARGE_INTEGER)); | ||
m_ratio = DEFAULT_MAX_PERCENTAGE; | ||
} | ||
|
||
//**********************Main Function *************************** | ||
|
||
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 then a milli second, 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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#pragma once | ||
|
||
#include <windows.h> | ||
|
||
const int DEFAULT_MAX_PERCENTAGE = 20; | ||
|
||
/* | ||
CPULimiter: | ||
This class helps to limit the cpu usage/consumption by a thread involving | ||
some kind of repetitive/polling kind of operation in a loop. | ||
The limit can be set by a user through a function of this class. | ||
*/ | ||
|
||
class CPULimiter | ||
{ | ||
//This integer stores last total system time. | ||
//total system time is sum of time spent by system | ||
//in kernel, user and idle mode | ||
LARGE_INTEGER m_lastTotalSystemTime; | ||
|
||
//This integer stores last total time spent by this | ||
//thread in kernel space and user space | ||
LARGE_INTEGER m_lastThreadUsageTime; | ||
|
||
//Variable used to store maximum thread cpu percentage | ||
//relative to system total time. | ||
int m_ratio; | ||
public: | ||
|
||
//Constructors | ||
CPULimiter(); | ||
//Contructor with maximum thread cpu usage percentage | ||
CPULimiter(int p_ratio); | ||
|
||
//****************Main function.****************** | ||
//It evaluates cpu consumption by this thread since | ||
//last call to this function, uptill now. | ||
//Internally, it calculates if the thread has exceeds | ||
//the maximum cpu usage percentage specified. | ||
//if yes, it makes the thread to sleep for a calculated | ||
//time period, to average the total usage to the limit specified. | ||
//Returns TRUE Successful, else FALSE | ||
|
||
BOOL CalculateAndSleep(); | ||
|
||
//Inline setter function | ||
inline void SetRatio(int p_ratio){m_ratio = p_ratio;} | ||
}; |