home *** CD-ROM | disk | FTP | other *** search
/ Clickx 47 / Clickx 47.iso / assets / software / sswitchxp152.exe / source / SpeedswitchXP / CPUSpeed.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-06-14  |  3.4 KB  |  128 lines

  1. /*
  2.    SpeedswitchXP V1.5
  3.    - Windows XP CPU Frequency Control for Notebooks -
  4.  
  5.    Copyright(c) 2002-2006 Christian Diefer
  6.  
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License version 2 as 
  9.    published by the Free Software Foundation.
  10.    
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.    
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20.  
  21. #define _UNICODE
  22.  
  23. #include "stdafx.h"
  24. #include "AtlBase.h"
  25. #include "TOptions.h"
  26. #include "CPUSpeed.h"
  27.  
  28. #define RDTSC_INSTRUCTION            _asm _emit 0x0f _asm _emit 0x31
  29. #define    CPUSPEED_I32TO64(x, y)        (((__int64) x << 32) + y)
  30.  
  31. CPUSpeed::CPUSpeed ()
  32. {
  33.     unsigned int uiRepetitions = 1;
  34.     unsigned int uiMSecPerRepetition = 50;
  35.     __int64    i64Total = 0, i64Overhead = 0;
  36.  
  37.     for (unsigned int nCounter = 0; nCounter < uiRepetitions; nCounter ++) {
  38.         i64Total += GetCyclesDifference (CPUSpeed::Delay, uiMSecPerRepetition);
  39.         i64Overhead += GetCyclesDifference (CPUSpeed::DelayOverhead, uiMSecPerRepetition);
  40.     }
  41.  
  42.     // Calculate the MHz speed.
  43.     i64Total -= i64Overhead;
  44.     i64Total /= uiRepetitions;
  45.     i64Total /= uiMSecPerRepetition;
  46.     i64Total /= 1000;
  47.  
  48.     // Save the CPU speed.
  49.     CPUSpeedInMHz = (int) i64Total;
  50. }
  51.  
  52. CPUSpeed::~CPUSpeed ()
  53. {
  54. }
  55.  
  56. __int64    __cdecl CPUSpeed::GetCyclesDifference (DELAY_FUNC DelayFunction, unsigned int uiParameter)
  57. {
  58.     unsigned int edx1, eax1;
  59.     unsigned int edx2, eax2;
  60.         
  61.     // Calculate the frequency of the CPU instructions.
  62.     __try {
  63.         _asm {
  64.             push uiParameter        ; push parameter param
  65.             mov ebx, DelayFunction    ; store func in ebx
  66.  
  67.             RDTSC_INSTRUCTION
  68.  
  69.             mov esi, eax            ; esi = eax
  70.             mov edi, edx            ; edi = edx
  71.  
  72.             call ebx                ; call the delay functions
  73.  
  74.             RDTSC_INSTRUCTION
  75.  
  76.             pop ebx
  77.  
  78.             mov edx2, edx            ; edx2 = edx
  79.             mov eax2, eax            ; eax2 = eax
  80.  
  81.             mov edx1, edi            ; edx2 = edi
  82.             mov eax1, esi            ; eax2 = esi
  83.         }
  84.     }
  85.  
  86.     // A generic catch-all just to be sure...
  87.     __except (1) {
  88.         return -1;
  89.     }
  90.  
  91.     return (CPUSPEED_I32TO64 (edx2, eax2) - CPUSPEED_I32TO64 (edx1, eax1));
  92. }
  93.  
  94. void CPUSpeed::Delay (unsigned int uiMS)
  95. {
  96.     LARGE_INTEGER Frequency, StartCounter, EndCounter;
  97.     __int64 x;
  98.  
  99.     // Get the frequency of the high performance counter.
  100.     if (!QueryPerformanceFrequency (&Frequency)) return;
  101.     x = Frequency.QuadPart / 1000 * uiMS;
  102.  
  103.     // Get the starting position of the counter.
  104.     QueryPerformanceCounter (&StartCounter);
  105.  
  106.     do {
  107.         // Get the ending position of the counter.    
  108.         QueryPerformanceCounter (&EndCounter);
  109.     } while (EndCounter.QuadPart - StartCounter.QuadPart < x);
  110. }
  111.  
  112. void CPUSpeed::DelayOverhead (unsigned int uiMS)
  113. {
  114.     LARGE_INTEGER Frequency, StartCounter, EndCounter;
  115.     __int64 x;
  116.  
  117.     // Get the frequency of the high performance counter.
  118.     if (!QueryPerformanceFrequency (&Frequency)) return;
  119.     x = Frequency.QuadPart / 1000 * uiMS;
  120.  
  121.     // Get the starting position of the counter.
  122.     QueryPerformanceCounter (&StartCounter);
  123.     
  124.     do {
  125.         // Get the ending position of the counter.    
  126.         QueryPerformanceCounter (&EndCounter);
  127.     } while (EndCounter.QuadPart - StartCounter.QuadPart == x);
  128. }