LLC2_API
x86timer.cpp
Go to the documentation of this file.
00001 /** @file: x86timer.c  API for x86 time funcs.
00002  * thanks to Ben Penaflor 
00003 
00004 First run
00005 
00006 . ./setup.clocks2 3 0 64 2
00007 init_clocks_mbcb
00008 
00009     telnet 192.5.166.179
00010     /tmp/trigger_toggler
00011 
00012 ******************************************************************************
00013 */
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 
00018 #include "x86timer.h"
00019 
00020 static unsigned int CPU_CLOCK_SPEED = -1;
00021 
00022 #define rdtscll(val) \
00023      __asm__ __volatile__ ("rdtsc" : "=A" (val))
00024 
00025 
00026 unsigned long long get_cpu_ticks(void)
00027 {
00028         unsigned long long ticks;
00029         
00030         rdtscll(ticks);
00031         return ticks;
00032 }
00033 unsigned long long get_cpu_usecs(void)
00034 {
00035         unsigned long long ticks;
00036         
00037         rdtscll(ticks);
00038         return ticks/CPU_CLOCK_SPEED;
00039 }
00040 
00041 
00042 /*
00043 ******************************************************************************
00044 SUBROUTINE: get_cpu_clock_speed
00045 ******************************************************************************
00046 */
00047 
00048 unsigned int get_cpu_clock_speed(void)
00049 {
00050         char line[256];
00051         FILE *inputfile;
00052         float fspeed = 0;
00053         unsigned int speed;
00054 
00055         if(CPU_CLOCK_SPEED == -1)
00056         {
00057                 speed = 0;
00058                 /*
00059                   Get the cpu speed.
00060                   Open the file.
00061                 */
00062                 inputfile = fopen("/proc/cpuinfo", "r");
00063                 if(inputfile != NULL)
00064                 {
00065                         /*
00066                           Read the data from the file.
00067                         */
00068                         while(fgets(line, 256, inputfile) != NULL)
00069                         {
00070                                 if(strstr(line,"cycle frequency [Hz]") != NULL)
00071                                 {
00072                                         fspeed = (float)atoi(strchr(line,':')+1)/1000000.0;
00073                                         break;
00074                                 }
00075                                 if(strstr(line,"cpu MHz") != NULL)
00076                                 {
00077                                         fspeed = (float)atoi(strchr(line,':')+1);
00078                                         break;
00079                                 }
00080                         }
00081                         fclose(inputfile);
00082                         speed = (int)(fspeed);
00083                 }
00084                 else
00085                         fprintf(stderr,"Cannot get cpu speed from /proc/cpuinfo\n");
00086 
00087                 fprintf(stderr,"speed=%d ticks per microsecond\n", speed);
00088                 CPU_CLOCK_SPEED=speed;
00089         }
00090 
00091         return(CPU_CLOCK_SPEED);
00092 }
00093 
00094 
00095 
00096 /*
00097 ******************************************************************************
00098 SUBROUTINE: cpu_delay_awhile
00099 
00100 Delay the specified number of input microseconds.
00101 
00102 {// for testing, this delays for 10 seconds
00103 int ii;
00104 printf("delaying\n");
00105 for(ii=0;ii<1000*10;ii++)
00106     cpu_delay_awhile(1000);
00107 printf("done\n");
00108 }
00109 ******************************************************************************
00110 */
00111 
00112 
00113 static unsigned long
00114 _get_elapsed_microseconds(int reset, unsigned long long* start)
00115 {
00116         unsigned long long now;
00117 
00118         if(reset==1){
00119                 *start = get_cpu_usecs();
00120                 return 0;
00121         }
00122         now = get_cpu_usecs();
00123 
00124         if (now >= *start){
00125                 return now - *start;
00126         }else{
00127                 *start = 0;
00128                 return 0xffffffffffffffffULL - *start + now;
00129                 /**    0x1234567890abcdefULL */
00130         }
00131 }
00132 
00133 
00134 unsigned long
00135 get_elapsed_microseconds(int reset)
00136 {
00137         static unsigned long long start;
00138 
00139         return _get_elapsed_microseconds(reset, &start);
00140 }
00141 
00142 
00143 void cpu_delay_awhile(unsigned int delay_microseconds)
00144 {
00145         unsigned long long _start;
00146         unsigned long start = _get_elapsed_microseconds(1, &_start);
00147         unsigned long now;
00148 
00149         do {
00150                 now = _get_elapsed_microseconds(0, &_start);
00151         } while( now < start + delay_microseconds);
00152 }
00153 
00154