00001 unsigned long long int sched_time;
00002 unsigned long cpu_khz;
00003 unsigned long fast_gettimeoffset_quotient;
00004
00005 #include <sys/time.h>
00006 #include <stdio.h>
00007
00008 static inline long long llimd(long long ll, int mult, int div);
00009
00010
00011 static inline unsigned long long int us2clock(unsigned long u)
00012 {
00013 return llimd(u, cpu_khz, 1000);
00014 }
00015
00016 static inline unsigned long int clock2ms(unsigned long long c)
00017 {
00018 return (unsigned long int)(llimd(c, fast_gettimeoffset_quotient, 1000) >> 32);
00019 }
00020
00021 static inline unsigned long int clock2us(unsigned long long c)
00022 {
00023 return (unsigned long int) ((c * fast_gettimeoffset_quotient) >> 32);
00024 }
00025
00026 static inline unsigned long long sched_read_clock(void)
00027 {
00028 unsigned long long res;
00029
00030 __asm__ __volatile__( "rdtsc" : "=A" (res));
00031 return res;
00032 }
00033
00034 static inline unsigned long sched_read_clock_us(void)
00035 {
00036 return clock2us(sched_read_clock());
00037 }
00038
00039
00040 static inline long long llimd(long long ll, int mult, int div)
00041 {
00042 __asm__ __volatile (\
00043 "movl %%edx,%%ecx; mull %%esi; movl %%eax,%%ebx; \n\t"
00044 "movl %%ecx,%%eax; movl %%edx,%%ecx; mull %%esi; \n\t"
00045 "addl %%ecx,%%eax; adcl $0,%%edx; divl %%edi; \n\t"
00046 "movl %%eax,%%ecx; movl %%ebx,%%eax; divl %%edi; \n\t"
00047 "sal $1,%%edx; cmpl %%edx,%%edi; movl %%ecx,%%edx; \n\t"
00048 "jge 1f; addl $1,%%eax; adcl $0,%%edx; 1:"
00049 : "=A" (ll)
00050 : "A" (ll), "S" (mult), "D" (div)
00051 : "%ebx", "%ecx");
00052 return ll;
00053 }
00054
00055 int main() {
00056 unsigned long long clocks = 0;
00057 unsigned long long clocks1, clocks2;
00058 unsigned long long clocks_per_sec;
00059 unsigned long usecs_old = 0;
00060 unsigned long usecs;
00061 struct timeval tv1, tv2;
00062 printf("Computing HZ\n");
00063 gettimeofday(&tv1, NULL);
00064 clocks1 = sched_read_clock();
00065 do {
00066 gettimeofday(&tv2, NULL);
00067 clocks2 = sched_read_clock();
00068 usecs = (tv2.tv_sec-tv1.tv_sec)*1000000L + (tv2.tv_usec-tv1.tv_usec);
00069 } while(usecs < 1000000L);
00070 clocks_per_sec = clocks2-clocks1;
00071 printf("clk1=%llu, clk2=%llu, passed clocks=%llu\n", clocks1, clocks2, clocks_per_sec);
00072 fast_gettimeoffset_quotient = llimd(1ULL << 32, usecs, clocks_per_sec);
00073 printf("quotient=%lu\n", fast_gettimeoffset_quotient);
00074
00075 usecs = 0;
00076 do {
00077 unsigned long long ull1, ull2, ulld;
00078 clocks += clocks_per_sec * 100;
00079 usecs_old = usecs;
00080 usecs = clock2us(clocks);
00081 ull1 = (unsigned long long) usecs;
00082 ull2 = (unsigned long long) usecs_old;
00083 ulld = (unsigned long long) (usecs-usecs_old);
00084 if (usecs < usecs_old)
00085 printf("XX ");
00086 else
00087 printf(" ");
00088 printf("clk=%llu, us=%llu, us_old=%llu, us_d=%llu\n", clocks, ull1, ull2, ulld);
00089 } while(1);
00090 return 0;
00091 }