home *** CD-ROM | disk | FTP | other *** search
- /*
- SpeedswitchXP V1.5
- - Windows XP CPU Frequency Control for Notebooks -
-
- Copyright(c) 2002-2006 Christian Diefer
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #define _UNICODE
-
- #include "stdafx.h"
- #include "AtlBase.h"
- #include "TOptions.h"
- #include "CPUSpeed.h"
-
- #define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31
- #define CPUSPEED_I32TO64(x, y) (((__int64) x << 32) + y)
-
- CPUSpeed::CPUSpeed ()
- {
- unsigned int uiRepetitions = 1;
- unsigned int uiMSecPerRepetition = 50;
- __int64 i64Total = 0, i64Overhead = 0;
-
- for (unsigned int nCounter = 0; nCounter < uiRepetitions; nCounter ++) {
- i64Total += GetCyclesDifference (CPUSpeed::Delay, uiMSecPerRepetition);
- i64Overhead += GetCyclesDifference (CPUSpeed::DelayOverhead, uiMSecPerRepetition);
- }
-
- // Calculate the MHz speed.
- i64Total -= i64Overhead;
- i64Total /= uiRepetitions;
- i64Total /= uiMSecPerRepetition;
- i64Total /= 1000;
-
- // Save the CPU speed.
- CPUSpeedInMHz = (int) i64Total;
- }
-
- CPUSpeed::~CPUSpeed ()
- {
- }
-
- __int64 __cdecl CPUSpeed::GetCyclesDifference (DELAY_FUNC DelayFunction, unsigned int uiParameter)
- {
- unsigned int edx1, eax1;
- unsigned int edx2, eax2;
-
- // Calculate the frequency of the CPU instructions.
- __try {
- _asm {
- push uiParameter ; push parameter param
- mov ebx, DelayFunction ; store func in ebx
-
- RDTSC_INSTRUCTION
-
- mov esi, eax ; esi = eax
- mov edi, edx ; edi = edx
-
- call ebx ; call the delay functions
-
- RDTSC_INSTRUCTION
-
- pop ebx
-
- mov edx2, edx ; edx2 = edx
- mov eax2, eax ; eax2 = eax
-
- mov edx1, edi ; edx2 = edi
- mov eax1, esi ; eax2 = esi
- }
- }
-
- // A generic catch-all just to be sure...
- __except (1) {
- return -1;
- }
-
- return (CPUSPEED_I32TO64 (edx2, eax2) - CPUSPEED_I32TO64 (edx1, eax1));
- }
-
- void CPUSpeed::Delay (unsigned int uiMS)
- {
- LARGE_INTEGER Frequency, StartCounter, EndCounter;
- __int64 x;
-
- // Get the frequency of the high performance counter.
- if (!QueryPerformanceFrequency (&Frequency)) return;
- x = Frequency.QuadPart / 1000 * uiMS;
-
- // Get the starting position of the counter.
- QueryPerformanceCounter (&StartCounter);
-
- do {
- // Get the ending position of the counter.
- QueryPerformanceCounter (&EndCounter);
- } while (EndCounter.QuadPart - StartCounter.QuadPart < x);
- }
-
- void CPUSpeed::DelayOverhead (unsigned int uiMS)
- {
- LARGE_INTEGER Frequency, StartCounter, EndCounter;
- __int64 x;
-
- // Get the frequency of the high performance counter.
- if (!QueryPerformanceFrequency (&Frequency)) return;
- x = Frequency.QuadPart / 1000 * uiMS;
-
- // Get the starting position of the counter.
- QueryPerformanceCounter (&StartCounter);
-
- do {
- // Get the ending position of the counter.
- QueryPerformanceCounter (&EndCounter);
- } while (EndCounter.QuadPart - StartCounter.QuadPart == x);
- }