PolarSSL v1.1.4
|
00001 /* 00002 * Portable interface to the CPU cycle counter 00003 * 00004 * Copyright (C) 2006-2010, Brainspark B.V. 00005 * 00006 * This file is part of PolarSSL (http://www.polarssl.org) 00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00008 * 00009 * All rights reserved. 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License along 00022 * with this program; if not, write to the Free Software Foundation, Inc., 00023 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00024 */ 00025 00026 #include "polarssl/config.h" 00027 00028 #if defined(POLARSSL_TIMING_C) 00029 00030 #include "polarssl/timing.h" 00031 00032 #if defined(_WIN32) 00033 00034 #include <windows.h> 00035 #include <winbase.h> 00036 00037 struct _hr_time 00038 { 00039 LARGE_INTEGER start; 00040 }; 00041 00042 #else 00043 00044 #include <unistd.h> 00045 #include <sys/types.h> 00046 #include <sys/time.h> 00047 #include <signal.h> 00048 #include <time.h> 00049 00050 struct _hr_time 00051 { 00052 struct timeval start; 00053 }; 00054 00055 #endif 00056 00057 #if defined(POLARSSL_HAVE_ASM) && \ 00058 (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) 00059 00060 unsigned long hardclock( void ) 00061 { 00062 unsigned long tsc; 00063 __asm rdtsc 00064 __asm mov [tsc], eax 00065 return( tsc ); 00066 } 00067 00068 #else 00069 #if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) 00070 00071 unsigned long hardclock( void ) 00072 { 00073 unsigned long lo, hi; 00074 asm( "rdtsc" : "=a" (lo), "=d" (hi) ); 00075 return( lo ); 00076 } 00077 00078 #else 00079 #if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && \ 00080 (defined(__amd64__) || defined(__x86_64__)) 00081 00082 unsigned long hardclock( void ) 00083 { 00084 unsigned long lo, hi; 00085 asm( "rdtsc" : "=a" (lo), "=d" (hi) ); 00086 return( lo | (hi << 32) ); 00087 } 00088 00089 #else 00090 #if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && \ 00091 (defined(__powerpc__) || defined(__ppc__)) 00092 00093 unsigned long hardclock( void ) 00094 { 00095 unsigned long tbl, tbu0, tbu1; 00096 00097 do 00098 { 00099 asm( "mftbu %0" : "=r" (tbu0) ); 00100 asm( "mftb %0" : "=r" (tbl ) ); 00101 asm( "mftbu %0" : "=r" (tbu1) ); 00102 } 00103 while( tbu0 != tbu1 ); 00104 00105 return( tbl ); 00106 } 00107 00108 #else 00109 #if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__sparc__) 00110 00111 unsigned long hardclock( void ) 00112 { 00113 unsigned long tick; 00114 asm( ".byte 0x83, 0x41, 0x00, 0x00" ); 00115 asm( "mov %%g1, %0" : "=r" (tick) ); 00116 return( tick ); 00117 } 00118 00119 #else 00120 #if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__alpha__) 00121 00122 unsigned long hardclock( void ) 00123 { 00124 unsigned long cc; 00125 asm( "rpcc %0" : "=r" (cc) ); 00126 return( cc & 0xFFFFFFFF ); 00127 } 00128 00129 #else 00130 #if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__ia64__) 00131 00132 unsigned long hardclock( void ) 00133 { 00134 unsigned long itc; 00135 asm( "mov %0 = ar.itc" : "=r" (itc) ); 00136 return( itc ); 00137 } 00138 00139 #else 00140 #if defined(_MSC_VER) 00141 00142 unsigned long hardclock( void ) 00143 { 00144 LARGE_INTEGER offset; 00145 00146 QueryPerformanceCounter( &offset ); 00147 00148 return (unsigned long)( offset.QuadPart ); 00149 } 00150 00151 #else 00152 00153 static int hardclock_init = 0; 00154 static struct timeval tv_init; 00155 00156 unsigned long hardclock( void ) 00157 { 00158 struct timeval tv_cur; 00159 00160 if( hardclock_init == 0 ) 00161 { 00162 gettimeofday( &tv_init, NULL ); 00163 hardclock_init = 1; 00164 } 00165 00166 gettimeofday( &tv_cur, NULL ); 00167 return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 00168 + ( tv_cur.tv_usec - tv_init.tv_usec ) ); 00169 } 00170 00171 #endif /* generic */ 00172 #endif /* WIN32 */ 00173 #endif /* IA-64 */ 00174 #endif /* Alpha */ 00175 #endif /* SPARC8 */ 00176 #endif /* PowerPC */ 00177 #endif /* AMD64 */ 00178 #endif /* i586+ */ 00179 00180 volatile int alarmed = 0; 00181 00182 #if defined(_WIN32) 00183 00184 unsigned long get_timer( struct hr_time *val, int reset ) 00185 { 00186 unsigned long delta; 00187 LARGE_INTEGER offset, hfreq; 00188 struct _hr_time *t = (struct _hr_time *) val; 00189 00190 QueryPerformanceCounter( &offset ); 00191 QueryPerformanceFrequency( &hfreq ); 00192 00193 delta = (unsigned long)( ( 1000 * 00194 ( offset.QuadPart - t->start.QuadPart ) ) / 00195 hfreq.QuadPart ); 00196 00197 if( reset ) 00198 QueryPerformanceCounter( &t->start ); 00199 00200 return( delta ); 00201 } 00202 00203 DWORD WINAPI TimerProc( LPVOID uElapse ) 00204 { 00205 Sleep( (DWORD) uElapse ); 00206 alarmed = 1; 00207 return( TRUE ); 00208 } 00209 00210 void set_alarm( int seconds ) 00211 { 00212 DWORD ThreadId; 00213 00214 alarmed = 0; 00215 CloseHandle( CreateThread( NULL, 0, TimerProc, 00216 (LPVOID) ( seconds * 1000 ), 0, &ThreadId ) ); 00217 } 00218 00219 void m_sleep( int milliseconds ) 00220 { 00221 Sleep( milliseconds ); 00222 } 00223 00224 #else 00225 00226 unsigned long get_timer( struct hr_time *val, int reset ) 00227 { 00228 unsigned long delta; 00229 struct timeval offset; 00230 struct _hr_time *t = (struct _hr_time *) val; 00231 00232 gettimeofday( &offset, NULL ); 00233 00234 delta = ( offset.tv_sec - t->start.tv_sec ) * 1000 00235 + ( offset.tv_usec - t->start.tv_usec ) / 1000; 00236 00237 if( reset ) 00238 { 00239 t->start.tv_sec = offset.tv_sec; 00240 t->start.tv_usec = offset.tv_usec; 00241 } 00242 00243 return( delta ); 00244 } 00245 00246 static void sighandler( int signum ) 00247 { 00248 alarmed = 1; 00249 signal( signum, sighandler ); 00250 } 00251 00252 void set_alarm( int seconds ) 00253 { 00254 alarmed = 0; 00255 signal( SIGALRM, sighandler ); 00256 alarm( seconds ); 00257 } 00258 00259 void m_sleep( int milliseconds ) 00260 { 00261 struct timeval tv; 00262 00263 tv.tv_sec = milliseconds / 1000; 00264 tv.tv_usec = milliseconds * 1000; 00265 00266 select( 0, NULL, NULL, NULL, &tv ); 00267 } 00268 00269 #endif 00270 00271 #endif