- Main Page
- Data Structures
- Files

# timing.c

Go to the documentation of this file.

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