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

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

Generated on Tue Jul 1 15:29:59 2008 for Mobile-C by  doxygen 1.5.4