PolarSSL v1.1.4
timing.c
Go to the documentation of this file.
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