LLC2_API
|
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