/home/dko/projects/mobilec/trunk/src/security/xyssl-0.7/library/timing.c

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

Generated on Fri May 16 14:49:55 2008 for Mobile-C by  doxygen 1.5.4