📄 hires.t
字号:
#!./perl -wBEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = '../lib'; require Config; import Config; if (" $Config{'extensions'} " !~ m[ Time/HiRes ]) { print "1..0 # Skip -- Perl configured without Time::HiRes module\n"; exit 0; } }}BEGIN { $| = 1; print "1..38\n"; }END { print "not ok 1\n" unless $loaded }use Time::HiRes 1.9704; # Remember to bump this once in a while.use Time::HiRes qw(tv_interval);$loaded = 1;print "ok 1\n";use strict;my $have_gettimeofday = &Time::HiRes::d_gettimeofday;my $have_usleep = &Time::HiRes::d_usleep;my $have_nanosleep = &Time::HiRes::d_nanosleep;my $have_ualarm = &Time::HiRes::d_ualarm;my $have_clock_gettime = &Time::HiRes::d_clock_gettime;my $have_clock_getres = &Time::HiRes::d_clock_getres;my $have_clock_nanosleep = &Time::HiRes::d_clock_nanosleep;my $have_clock = &Time::HiRes::d_clock;my $have_hires_stat = &Time::HiRes::d_hires_stat;sub has_symbol { my $symbol = shift; eval "use Time::HiRes qw($symbol)"; return 0 unless $@ eq ''; eval "my \$a = $symbol"; return $@ eq '';}printf "# have_gettimeofday = %d\n", $have_gettimeofday;printf "# have_usleep = %d\n", $have_usleep;printf "# have_nanosleep = %d\n", $have_nanosleep;printf "# have_ualarm = %d\n", $have_ualarm;printf "# have_clock_gettime = %d\n", $have_clock_gettime;printf "# have_clock_getres = %d\n", $have_clock_getres;printf "# have_clock_nanosleep = %d\n", $have_clock_nanosleep;printf "# have_clock = %d\n", $have_clock;printf "# have_hires_stat = %d\n", $have_hires_stat;import Time::HiRes 'gettimeofday' if $have_gettimeofday;import Time::HiRes 'usleep' if $have_usleep;import Time::HiRes 'nanosleep' if $have_nanosleep;import Time::HiRes 'ualarm' if $have_ualarm;import Time::HiRes 'clock_gettime' if $have_clock_gettime;import Time::HiRes 'clock_getres' if $have_clock_getres;import Time::HiRes 'clock_nanosleep' if $have_clock_nanosleep;import Time::HiRes 'clock' if $have_clock;use Config;use Time::HiRes qw(gettimeofday);my $have_alarm = $Config{d_alarm};my $have_fork = $Config{d_fork};my $waitfor = 180; # 30-45 seconds is normal (load affects this).my $timer_pid;my $TheEnd;if ($have_fork) { print "# I am the main process $$, starting the timer process...\n"; $timer_pid = fork(); if (defined $timer_pid) { if ($timer_pid == 0) { # We are the kid, set up the timer. my $ppid = getppid(); print "# I am the timer process $$, sleeping for $waitfor seconds...\n"; sleep($waitfor); warn "\n$0: overall time allowed for tests (${waitfor}s) exceeded!\n"; print "# Terminating main process $ppid...\n"; kill('TERM', $ppid); print "# This is the timer process $$, over and out.\n"; exit(0); } else { print "# The timer process $timer_pid launched, continuing testing...\n"; $TheEnd = time() + $waitfor; } } else { warn "$0: fork failed: $!\n"; }} else { print "# No timer process (need fork)\n";}my $xdefine = ''; if (open(XDEFINE, "xdefine")) { chomp($xdefine = <XDEFINE>); close(XDEFINE);}# Ideally, we'd like to test that the timers are rather precise.# However, if the system is busy, there are no guarantees on how# quickly we will return. This limit used to be 10%, but that# was occasionally triggered falsely. # So let's try 25%.# Another possibility might be to print "ok" if the test completes fine# with (say) 10% slosh, "skip - system may have been busy?" if the test# completes fine with (say) 30% slosh, and fail otherwise. If you do that,# consider changing over to test.pl at the same time.# --A.D., Nov 27, 2001my $limit = 0.25; # 25% is acceptable slosh for testing timerssub skip { map { print "ok $_ # skipped\n" } @_;}sub ok { my ($n, $result, @info) = @_; if ($result) { print "ok $n\n"; } else { print "not ok $n\n"; print "# @info\n" if @info; }}unless ($have_gettimeofday) { skip 2..6;}else { my @one = gettimeofday(); ok 2, @one == 2, 'gettimeofday returned ', 0+@one, ' args'; ok 3, $one[0] > 850_000_000, "@one too small"; sleep 1; my @two = gettimeofday(); ok 4, ($two[0] > $one[0] || ($two[0] == $one[0] && $two[1] > $one[1])), "@two is not greater than @one"; my $f = Time::HiRes::time(); ok 5, $f > 850_000_000, "$f too small"; ok 6, $f - $two[0] < 2, "$f - $two[0] >= 2";}unless ($have_usleep) { skip 7..8;}else { use Time::HiRes qw(usleep); my $one = time; usleep(10_000); my $two = time; usleep(10_000); my $three = time; ok 7, $one == $two || $two == $three, "slept too long, $one $two $three"; unless ($have_gettimeofday) { skip 8; } else { my $f = Time::HiRes::time(); usleep(500_000); my $f2 = Time::HiRes::time(); my $d = $f2 - $f; ok 8, $d > 0.4 && $d < 0.9, "slept $d secs $f to $f2"; }}# Two-arg tv_interval() is always available.{ my $f = tv_interval [5, 100_000], [10, 500_000]; ok 9, abs($f - 5.4) < 0.001, $f;}unless ($have_gettimeofday) { skip 10;}else { my $r = [gettimeofday()]; my $f = tv_interval $r; ok 10, $f < 2, $f;}unless ($have_usleep && $have_gettimeofday) { skip 11;}else { my $r = [ gettimeofday() ]; Time::HiRes::sleep( 0.5 ); my $f = tv_interval $r; ok 11, $f > 0.4 && $f < 0.9, "slept $f instead of 0.5 secs.";}unless ($have_ualarm && $have_alarm) { skip 12..13;}else { my $tick = 0; local $SIG{ ALRM } = sub { $tick++ }; my $one = time; $tick = 0; ualarm(10_000); while ($tick == 0) { } my $two = time; $tick = 0; ualarm(10_000); while ($tick == 0) { } my $three = time; ok 12, $one == $two || $two == $three, "slept too long, $one $two $three"; print "# tick = $tick, one = $one, two = $two, three = $three\n"; $tick = 0; ualarm(10_000, 10_000); while ($tick < 3) { } ok 13, 1; ualarm(0); print "# tick = $tick, one = $one, two = $two, three = $three\n";}# Did we even get close?unless ($have_gettimeofday) { skip 14;} else { my ($s, $n, $i) = (0); for $i (1 .. 100) { $s += Time::HiRes::time() - time(); $n++; } # $s should be, at worst, equal to $n # (time() may be rounding down, up, or closest), # but allow 10% of slop. ok 14, abs($s) / $n <= 1.10, "Time::HiRes::time() not close to time()"; print "# s = $s, n = $n, s/n = ", abs($s)/$n, "\n";}my $has_ualarm = $Config{d_ualarm};$has_ualarm ||= $xdefine =~ /-DHAS_UALARM/;unless ( defined &Time::HiRes::gettimeofday && defined &Time::HiRes::ualarm && defined &Time::HiRes::usleep && $has_ualarm) { for (15..17) { print "ok $_ # Skip: no gettimeofday or no ualarm or no usleep\n"; }} else { use Time::HiRes qw(time alarm sleep); eval { require POSIX }; my $use_sigaction = !$@ && defined &POSIX::sigaction && &POSIX::SIGALRM > 0; my ($f, $r, $i, $not, $ok); $f = time; print "# time...$f\n"; print "ok 15\n"; $r = [Time::HiRes::gettimeofday()]; sleep (0.5); print "# sleep...", Time::HiRes::tv_interval($r), "\nok 16\n"; $r = [Time::HiRes::gettimeofday()]; $i = 5; my $oldaction; if ($use_sigaction) { $oldaction = new POSIX::SigAction; printf "# sigaction tick, ALRM = %d\n", &POSIX::SIGALRM; # Perl's deferred signals may be too wimpy to break through # a restartable select(), so use POSIX::sigaction if available. sub tick { $i--; my $ival = Time::HiRes::tv_interval ($r); print "# Tick! $i $ival\n"; my $exp = 0.3 * (5 - $i); # This test is more sensitive, so impose a softer limit. if (abs($ival/$exp - 1) > 4*$limit) { my $ratio = abs($ival/$exp); $not = "tick: $exp sleep took $ival ratio $ratio"; $i = 0; } } POSIX::sigaction(&POSIX::SIGALRM, POSIX::SigAction->new("tick"), $oldaction) or die "Error setting SIGALRM handler with sigaction: $!\n"; } else { print "# SIG tick\n"; $SIG{ALRM} = "tick"; } # On VMS timers can not interrupt select. if ($^O eq 'VMS') { $ok = "Skip: VMS select() does not get interrupted."; } else { while ($i > 0) { alarm(0.3); select (undef, undef, undef, 3); my $ival = Time::HiRes::tv_interval ($r); print "# Select returned! $i $ival\n"; print "# ", abs($ival/3 - 1), "\n"; # Whether select() gets restarted after signals is # implementation dependent. If it is restarted, we # will get about 3.3 seconds: 3 from the select, 0.3 # from the alarm. If this happens, let's just skip # this particular test. --jhi if (abs($ival/3.3 - 1) < $limit) { $ok = "Skip: your select() may get restarted by your SIGALRM (or just retry test)"; undef $not; last; } my $exp = 0.3 * (5 - $i); # This test is more sensitive, so impose a softer limit. if (abs($ival/$exp - 1) > 3*$limit) { my $ratio = abs($ival/$exp); $not = "while: $exp sleep took $ival ratio $ratio"; last; } $ok = $i; } } if ($use_sigaction) { POSIX::sigaction(&POSIX::SIGALRM, $oldaction); } else { alarm(0); # can't cancel usig %SIG } print $not ? "not ok 17 # $not\n" : "ok 17 # $ok\n";}unless ( defined &Time::HiRes::setitimer && defined &Time::HiRes::getitimer && has_symbol('ITIMER_VIRTUAL') && $Config{sig_name} =~ m/\bVTALRM\b/ && $^O !~ /^(nto)$/) { # nto: QNX 6 has the API but no implementation for (18..19) { print "ok $_ # Skip: no virtual interval timers\n"; }} else { use Time::HiRes qw(setitimer getitimer ITIMER_VIRTUAL); my $i = 3; my $r = [Time::HiRes::gettimeofday()]; $SIG{VTALRM} = sub { $i ? $i-- : setitimer(&ITIMER_VIRTUAL, 0); print "# Tick! $i ", Time::HiRes::tv_interval($r), "\n"; }; print "# setitimer: ", join(" ", setitimer(ITIMER_VIRTUAL, 0.5, 0.4)), "\n"; # Assume interval timer granularity of $limit * 0.5 seconds. Too bold? my $virt = getitimer(&ITIMER_VIRTUAL); print "not " unless defined $virt && abs($virt / 0.5) - 1 < $limit; print "ok 18\n"; print "# getitimer: ", join(" ", getitimer(ITIMER_VIRTUAL)), "\n";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -