182498Sroberto#! @PATH_PERL@ -w 282498Sroberto 382498Srobertodie "perl5 needed\n" unless ($] > 5); 482498Sroberto 582498Srobertouse Getopt::Std; 682498Srobertouse vars qw($opt_n); 782498Sroberto 882498Srobertogetopts('d:nt:'); 982498Sroberto 1082498Sroberto#chop($ncpu = `sysctl -n hw.ncpu`); 1182498Sroberto#die "Found $ncpu CPUs; can only be run on systems with 1 CPU.\n" if ($ncpu > 1); 1282498Sroberto 1382498Sroberto$driftfile = "/etc/ntp.drift"; 1482498Sroberto$driftfile = $opt_d if defined($opt_d); 1582498Sroberto 1682498Srobertochop($timer = `sysctl -n kern.timecounter.hardware 2> /dev/null`); 1782498Sroberto 1882498Sroberto$timer =~ tr/\U/\L/; 1982498Sroberto 2082498Srobertoif ($timer eq '') { 2182498Sroberto open(DM, "/var/run/dmesg.boot"); 2282498Sroberto while(<DM>) { 2382498Sroberto # Timecounter "i8254" frequency 1193182 Hz 2482498Sroberto if (/^Timecounter "(\w+)"\s+/) { 2582498Sroberto $timer = $1; 2682498Sroberto last; 2782498Sroberto } 2882498Sroberto } 2982498Sroberto close(DM); 3082498Sroberto} 3182498Sroberto 3282498Sroberto$opt_t = $timer if !defined($opt_t); 3382498Sroberto 3482498Srobertoif ($timer ne '') { # $timer found... 3582498Sroberto if ($opt_t ne '') { # - and $opt_t found 3682498Sroberto if ($timer ne $opt_t) { # - - and they differ 3782498Sroberto warn "You specified a $opt_t timer but I detected a $timer timer.\n"; 3882498Sroberto usage(); 3982498Sroberto exit 1; 4082498Sroberto } else { # - - and they are the same 4182498Sroberto ; 4282498Sroberto } 4382498Sroberto } else { # - but no $opt_t specified; this is OK 4482498Sroberto ; 4582498Sroberto } 4682498Sroberto} else { # No $timer found... 4782498Sroberto if ($opt_t ne '') { # - but $opt_t was specified 4882498Sroberto $timer = $opt_t; # - - so use it. 4982498Sroberto } else { # - and neither was $opt_t 5082498Sroberto warn "I can't tell what timer you have. Please specify one.\n"; 5182498Sroberto usage(); 5282498Sroberto exit 1; 5382498Sroberto } 5482498Sroberto} 5582498Sroberto 5682498Srobertoopen(DF, $driftfile) || die "Can't open driftfile ($driftfile): $!\n"; 5782498Srobertowhile(<DF>) { 5882498Sroberto chop; 5982498Sroberto if (/^(-?\d+\.\d+)(\s\d)?$/) { 6082498Sroberto $drift = $1; 6182498Sroberto } else { 6282498Sroberto die "Bogus value in driftfile $driftfile: <$_>\n"; 6382498Sroberto } 6482498Sroberto} 6582498Srobertoclose(DF); 6682498Sroberto 6782498Srobertoprint "NTP drift is <$drift>\n"; 6882498Sroberto 6982498Sroberto# Convert from NTP's idea of PPM to a decimal equivalent 7082498Sroberto$freq_adj = int ( $drift * ( 10 ** 6 / 2 ** 20) ); 7182498Srobertoprint "normalized freq_adj is <$freq_adj>\n"; 7282498Sroberto 7382498Sroberto$freq_adj = int ( ( $freq_adj - 1 ) / 2 ); 7482498Srobertoprint "Applying freq_adj of <".-$freq_adj.">\n"; 7582498Sroberto 7682498Sroberto$sysctl = "machdep.".$timer."_freq"; 7782498Sroberto 7882498Srobertochop($mach_freq = `sysctl -n $sysctl`); 7982498Sroberto 8082498Srobertoprint "$sysctl is <$mach_freq>\n"; 8182498Sroberto 8282498Sroberto$n_mach_freq = $mach_freq - $freq_adj; 8382498Sroberto 8482498Srobertoif (defined($opt_n)) { 8582498Sroberto print "$sysctl $mach_freq -> $n_mach_freq\n"; 8682498Sroberto} else { 8782498Sroberto print "i8254: ".`sysctl -w $sysctl=$n_mach_freq`; 8882498Sroberto} 8982498Sroberto 9082498Srobertosub usage { 9182498Sroberto print STDERR <<EOUsage 9282498SrobertoUsage: $0 [-d drift_file] [-n] [-t timer] 9382498Srobertowhere "drift_file" defaults to /etc/ntp.drift 9482498Srobertoand "timer" is usually "tsc" or "i8254" 9582498Srobertoand "-n" says "don't really change anything, just say what would happen". 9682498SrobertoEOUsage 9782498Sroberto} 98