@@ -909,11 +909,11 @@ void disable_itimer (void) {
909909
910910static unsigned long estimate_hwtimer_freq (long cpu_num ) {
911911
912- unsigned long n = 10 ;
913- unsigned long hwtimer_start , hwtimer_stop , hwtimer_diff ;
914- unsigned long hwtimer_average = 0 ;
912+ const unsigned long n = 10 ;
913+ const struct timeval duration = { .tv_sec = 1 , .tv_usec = 0 };
915914
916- printf ("Estimating HW timer frequency on CPU %ld for %lu iterations\n" , cpu_num , n );
915+ printf ("Estimating HW timer frequency on CPU %ld for %lu iterations of %lu.%06lu seconds each\n" ,
916+ cpu_num , n , duration .tv_sec , duration .tv_usec );
917917
918918 cpu_set_t cpu_mask ;
919919
@@ -925,30 +925,7 @@ static unsigned long estimate_hwtimer_freq(long cpu_num) {
925925 exit (-1 );
926926 }
927927
928- for (unsigned long i = 0 ; i < n ; i ++ ) {
929-
930- struct timeval ts_a , ts_b , ts_diff ;
931-
932- hwtimer_start = get_raw_counter ();
933- gettimeofday (& ts_a , NULL );
934-
935- do {
936- gettimeofday (& ts_b , NULL );
937- timersub (& ts_b , & ts_a , & ts_diff );
938- } while (ts_diff .tv_sec < 1 );
939-
940- hwtimer_stop = get_raw_counter ();
941-
942- hwtimer_diff = hwtimer_stop - hwtimer_start ;
943-
944- printf ("hwtimer_diff = %lu\n" , hwtimer_diff );
945-
946- hwtimer_average += hwtimer_diff ;
947- }
948-
949- hwtimer_average /= (double ) n ;
950-
951- // printf("hwtimer_average = %lu\n", hwtimer_average);
928+ unsigned long hwtimer_average = estimate_hwclock_freq (n , 1 , duration );
952929
953930 return hwtimer_average ;
954931}
@@ -1016,4 +993,82 @@ static int get_next_available_cpu (cpu_set_t * p_avail_cpus, int num_cores, int
1016993}
1017994
1018995
996+ unsigned long estimate_hwclock_freq (size_t n , int verbose , struct timeval target_measurement_duration ) {
997+
998+ unsigned long hwcounter_start , hwcounter_stop , hwcounter_diff ;
999+ unsigned long hwcounter_average = 0 ;
1000+
1001+ assert (n != 0 ); // can't handle only 1 sample
1002+
1003+ size_t high_i = 0 , low_i = 0 ;
1004+
1005+ unsigned long hwcounter_freq_high = 0 ;
1006+ unsigned long hwcounter_freq_low = -1 ;
1007+
1008+ for (size_t i = 0 ; i < n + 2 ; i ++ ) {
1009+
1010+ struct timeval ts_a , ts_b , ts_target , ts_diff ;
1011+
1012+ do {
1013+ hwcounter_start = get_raw_counter ();
1014+ gettimeofday (& ts_a , NULL );
1015+
1016+ timeradd (& ts_a , & target_measurement_duration , & ts_target );
1017+
1018+ do {
1019+ gettimeofday (& ts_b , NULL );
1020+ hwcounter_stop = get_raw_counter ();
1021+ } while (timercmp (& ts_b , & ts_target , < ));
1022+
1023+
1024+ timersub (& ts_b , & ts_target , & ts_diff );
1025+
1026+ if (0 ) // expect 0.000000
1027+ printf ("ts_diff = %lu.%06lu\n" , ts_diff .tv_sec , ts_diff .tv_usec );
1028+
1029+ } while (ts_diff .tv_sec > 0 || ts_diff .tv_usec > 100 );
1030+
1031+ hwcounter_diff = hwcounter_stop - hwcounter_start ;
1032+
1033+ timersub (& ts_b , & ts_a , & ts_diff );
1034+
1035+ unsigned long hwcounter_freq =
1036+ hwcounter_diff / (ts_diff .tv_sec + ts_diff .tv_usec * 0.000001 );
1037+
1038+ if (verbose ) {
1039+ printf ("sample %zu, hwcounter_diff = %lu, freq = %lu\n" ,
1040+ i , hwcounter_diff , hwcounter_freq );
1041+ }
1042+
1043+ hwcounter_average += hwcounter_freq ;
1044+
1045+ if (hwcounter_freq > hwcounter_freq_high ) {
1046+ hwcounter_freq_high = hwcounter_freq ;
1047+ high_i = i ;
1048+ }
1049+
1050+ if (hwcounter_freq < hwcounter_freq_low ) {
1051+ hwcounter_freq_low = hwcounter_freq ;
1052+ low_i = i ;
1053+ }
1054+
1055+ }
1056+
1057+ if (verbose ) {
1058+ printf ("dropped sample %zu, hwcounter_freq_low = %lu\n" , low_i , hwcounter_freq_low );
1059+ printf ("dropped sample %zu, hwcounter_freq_high = %lu\n" , high_i , hwcounter_freq_high );
1060+ }
1061+
1062+ hwcounter_average -= hwcounter_freq_low ;
1063+ hwcounter_average -= hwcounter_freq_high ;
1064+
1065+ hwcounter_average /= (double ) n ;
1066+
1067+ // printf("hwcounter_average = %lu\n", hwcounter_average);
1068+
1069+ return hwcounter_average ;
1070+ }
1071+
1072+
1073+
10191074/* vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: */
0 commit comments