home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2005 March / PCpro_2005_03.ISO / files / systools / speedswitchxp / sswitchxp14.exe / Typical / HTSpeed.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-01-14  |  3.6 KB  |  125 lines

  1. /*
  2.    SpeedswitchXP V1.4
  3.    - Windows XP CPU Frequency Control for Notebooks -
  4.  
  5.    Copyright(c) 2002-2004 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. #include "stdafx.h"
  22. #include <stdio.h>
  23. #include <math.h>
  24. #include <limits.h>
  25.  
  26. #include "speed.h"
  27. #include "cpuid.h"
  28.  
  29. static int firstrun = 1;
  30. static ushort sproc;
  31. static DWORD sfeat;
  32.  
  33.  
  34. // compute CPU speed with TSC and performance counter
  35. int cpuSpeedHT()
  36. {
  37.     UINT64 t0;      // ticks at beginning of test
  38.   UINT64 t1;      // ticks at end of test
  39.   UINT64 stamp0;  // cycles at beginning of test
  40.   UINT64 stamp1;  // cycles at end of test
  41.   UINT64 countFreq;
  42.   UINT64 elapsedCycles;
  43.   UINT64 elapsedTicks;
  44.   double elapsedTime;
  45.     HANDLE hProcess = GetCurrentProcess();
  46.     HANDLE hThread = GetCurrentThread();
  47.     ULONG dwProcessMask;
  48.   ULONG dwSystemMask;
  49.  
  50.   if( firstrun )    // init once (at first call only)
  51.   {
  52.     sproc = wincpuid();
  53.     sfeat = wincpufeatures();
  54.     firstrun = 0;
  55.   }
  56.  
  57.   if( !(sfeat & TSC_SUPPORT) )    // no TSC support
  58.         return 0;
  59.  
  60.     // get the frequency of the high-resolution performance counter
  61.     if( !QueryPerformanceFrequency((LARGE_INTEGER*)&countFreq) )
  62.         return 0;
  63.  
  64.     // get current process & thread priorities for later restoration
  65.   ULONG dwCurPriorityClass = GetPriorityClass( hProcess );
  66.     int iCurThreadPriority = GetThreadPriority( hThread );
  67.  
  68.   // get process & system affinity masks for later restoration
  69.     GetProcessAffinityMask( hProcess, &dwProcessMask, &dwSystemMask );
  70.  
  71.     // set this process & thread to max priorities so we don't get interrupted too often
  72.   if( dwCurPriorityClass != 0 )
  73.     SetPriorityClass( hProcess, REALTIME_PRIORITY_CLASS );
  74.  
  75.   if( iCurThreadPriority != THREAD_PRIORITY_ERROR_RETURN )
  76.     SetThreadPriority( hThread, THREAD_PRIORITY_TIME_CRITICAL );
  77.  
  78.   // nail this process onto the first CPU
  79.     SetProcessAffinityMask( hProcess, 1 );
  80.  
  81.   // get starting ticks
  82.     QueryPerformanceCounter( (LARGE_INTEGER*)&t0 );
  83.  
  84.     // serialize for in-order-execution and get starting cycles 
  85.   __asm { 
  86.     push ebx
  87.     xor eax,eax
  88.     cpuid
  89.     rdtsc
  90.         mov dword ptr [stamp0],eax
  91.         mov dword ptr [stamp0+4],edx
  92.     pop ebx
  93.     }
  94.  
  95.     Sleep( 50 );    // wait for 50msec to let the ticks and cycles counters advance
  96.  
  97.   // get ending ticks
  98.   QueryPerformanceCounter( (LARGE_INTEGER*)&t1 );
  99.  
  100.     // serialize again for in-order-execution and get ending cycles 
  101.     __asm 
  102.     {
  103.     push ebx
  104.     xor eax,eax
  105.     cpuid
  106.     rdtsc
  107.         mov dword ptr [stamp1],eax
  108.         mov dword ptr [stamp1+4],edx
  109.     pop ebx
  110.     }
  111.  
  112.   // restore process affinity and process&thread priorities
  113.     SetProcessAffinityMask( hProcess, dwProcessMask );
  114.     SetThreadPriority( hThread, iCurThreadPriority );
  115.     SetPriorityClass( hProcess, dwCurPriorityClass );
  116.  
  117.   // now compute the frequency...
  118.     elapsedCycles = stamp1 - stamp0;
  119.     elapsedTicks = t1 - t0;
  120.   elapsedTime = (double)elapsedTicks / (double)countFreq;
  121.  
  122.   // MHz = elapsed cycles / elapsed time / 1 million
  123.   return (int)((UINT64)(((double)elapsedCycles) / elapsedTime) / 1000000);
  124. }
  125.