#include #include #include #include "dxwnd.h" #include "dxwcore.hpp" #define MAX_THREAD_ARRAY 40 // forward declarations BOOL SlowCpuSpeed(DWORD, DWORD, int); BOOL LimitCpuUsage(DWORD, DWORD, int); DWORD WINAPI CpuSlow(LPVOID lpThreadParameter) { int iSlowDownRatio = dxw.SlowRatio; DWORD dwOwnerPID = GetCurrentProcessId(); DWORD dwOwnerThread = GetCurrentThreadId(); OutTrace("starting CPUSlow dwOwnerPID=%x Ratio=1:%d\n", dwOwnerPID, iSlowDownRatio); if(!dwOwnerPID) return FALSE; if(iSlowDownRatio < 1) return FALSE; Sleep(100); while(TRUE) SlowCpuSpeed(dwOwnerPID, dwOwnerThread, iSlowDownRatio); return TRUE; } DWORD WINAPI CpuLimit(LPVOID lpThreadParameter) { int iSlowDownRatio = dxw.SlowRatio; DWORD dwOwnerPID = GetCurrentProcessId(); DWORD dwOwnerThread = GetCurrentThreadId(); OutTrace("starting CPULimit dwOwnerPID=%x Ratio=1:%d\n", dwOwnerPID, iSlowDownRatio); if(!dwOwnerPID) return FALSE; if(iSlowDownRatio < 1) return FALSE; //while(TRUE) return LimitCpuUsage(dwOwnerPID, dwOwnerThread, iSlowDownRatio); } BOOL SlowCpuSpeed(DWORD dwOwnerPID, DWORD dwOwnerThread, int iSlowDownRatio) { HANDLE hThreadSnap = INVALID_HANDLE_VALUE; THREADENTRY32 te32; HANDLE SuspThreads[MAX_THREAD_ARRAY]; int iThreadIndex, iNumThreads; // Take a snapshot of all running threads hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); if(hThreadSnap == INVALID_HANDLE_VALUE) { OutTrace("LimitCpuUsage: CreateToolhelp32Snapshot ERROR err=%d\n", GetLastError()); return FALSE; } // Fill in the size of the structure before using it. te32.dwSize = sizeof(THREADENTRY32); // Retrieve information about the first thread, and exit if unsuccessful if(!Thread32First(hThreadSnap, &te32)){ OutTrace("Thread32First ERROR: err=%d\n", GetLastError()); // Show cause of failure CloseHandle(hThreadSnap); // Must clean up the snapshot object! return FALSE; } // Now walk the thread list of the system, // and stop each low-priority thread iThreadIndex = 0; do { if((te32.th32OwnerProcessID == dwOwnerPID) && (te32.th32ThreadID != dwOwnerThread)){ if (te32.tpBasePri < THREAD_PRIORITY_TIME_CRITICAL) { HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID); SuspendThread(hThread); SuspThreads[iThreadIndex++] = hThread; } } } while(Thread32Next(hThreadSnap, &te32) && (iThreadIndex 100) cycle=0; // every 100 cyces forces a thread list refresh Sleep(DELTA_TIME); for(iThreadIndex=0; iThreadIndexhThread == NULL) continue; // skip terminated ones if(!GetThreadTimes(t->hThread, &CreationTime, &ExitTime, &KernelTime, &UserTime)) { //OutTrace("Tid[%d]=%x died at %d\n", iThreadIndex, t->hThread, __LINE__); //CloseHandle(t->hThread); t->hThread = NULL; continue; } if (t->Suspended) { t->DeltaUsed -= iTimeSlot; //OutTrace("Tid[%d]=%x suspended delta=%ld\n", iThreadIndex, t->hThread, t->DeltaUsed); if(t->DeltaUsed < 0) { if (ResumeThread(t->hThread)== -1){ //OutTrace("Tid[%d]=%x died at %d\n", iThreadIndex, t->hThread, __LINE__); //CloseHandle(t->hThread); t->hThread = NULL; continue; } t->Suspended = FALSE; } } else { iUserTime = UserTime.dwLowDateTime; iKernelTime = KernelTime.dwLowDateTime; t->DeltaUsed = t->DeltaUsed + (iUserTime + iKernelTime) - t->LastUsed; t->LastUsed = iUserTime + iKernelTime; //OutTrace("Tid[%d]=%x active delta=%ld\n", iThreadIndex, t->hThread, t->DeltaUsed); if (t->DeltaUsed > (signed long)iTimeLimit) { //OutTrace("Tid[%d]=%x stopped last=%ld\n", iThreadIndex, t->hThread, t->DeltaUsed); if (SuspendThread(t->hThread)== -1) { //OutTrace("Tid[%d]=%x died at %d\n", iThreadIndex, t->hThread, __LINE__); //CloseHandle(t->hThread); t->hThread = NULL; continue; } t->Suspended = TRUE; t->DeltaUsed -= iTimeSlot; } } } } // should never go here .... OutTrace("end of cycle\n"); for(int i=0; i