1b8851fccSafresh1use strict; 2b8851fccSafresh1 3b8851fccSafresh1sub has_symbol { 4b8851fccSafresh1 my $symbol = shift; 5b8851fccSafresh1 eval "use Time::HiRes qw($symbol)"; 6b8851fccSafresh1 return 0 unless $@ eq ''; 7b8851fccSafresh1 eval "my \$a = $symbol"; 8b8851fccSafresh1 return $@ eq ''; 9b8851fccSafresh1} 10b8851fccSafresh1 11b8851fccSafresh1use Config; 12b8851fccSafresh1 13b8851fccSafresh1BEGIN { 14b8851fccSafresh1 require Time::HiRes; 15b8851fccSafresh1 unless(defined &Time::HiRes::setitimer 16b8851fccSafresh1 && defined &Time::HiRes::getitimer 17b8851fccSafresh1 && has_symbol('ITIMER_VIRTUAL') 18b8851fccSafresh1 && $Config{sig_name} =~ m/\bVTALRM\b/ 19b8851fccSafresh1 && $^O ne 'nto' # nto: QNX 6 has the API but no implementation 20b8851fccSafresh1 && $^O ne 'haiku' # haiku: has the API but no implementation 21b8851fccSafresh1 && $^O ne 'gnu' # GNU/Hurd: has the API but no implementation 22b8851fccSafresh1 ) { 23b8851fccSafresh1 require Test::More; 24b8851fccSafresh1 Test::More::plan(skip_all => "no itimer"); 25b8851fccSafresh1 } 26b8851fccSafresh1} 27b8851fccSafresh1 28014083a1Safresh1use Test::More tests => 2; 299f11ffb7Safresh1BEGIN { push @INC, '.' } 30b8851fccSafresh1use t::Watchdog; 31b8851fccSafresh1 32b8851fccSafresh1my $limit = 0.25; # 25% is acceptable slosh for testing timers 33b8851fccSafresh1 34b8851fccSafresh1my $i = 3; 35b8851fccSafresh1my $r = [Time::HiRes::gettimeofday()]; 36b8851fccSafresh1 37b8851fccSafresh1$SIG{VTALRM} = sub { 38b8851fccSafresh1 $i ? $i-- : Time::HiRes::setitimer(&Time::HiRes::ITIMER_VIRTUAL, 0); 39014083a1Safresh1 printf("# Tick! $i %s\n", Time::HiRes::tv_interval($r)); 40b8851fccSafresh1}; 41b8851fccSafresh1 42014083a1Safresh1printf("# setitimer: %s\n", join(" ", 43014083a1Safresh1 Time::HiRes::setitimer(&Time::HiRes::ITIMER_VIRTUAL, 0.5, 0.4))); 44b8851fccSafresh1 45b8851fccSafresh1# Assume interval timer granularity of $limit * 0.5 seconds. Too bold? 46b8851fccSafresh1my $virt = Time::HiRes::getitimer(&Time::HiRes::ITIMER_VIRTUAL); 47b8851fccSafresh1ok(defined $virt && abs($virt / 0.5) - 1 < $limit, 48b8851fccSafresh1 "ITIMER_VIRTUAL defined with sufficient granularity") 49b8851fccSafresh1 or diag "virt=" . (defined $virt ? $virt : 'undef'); 50b8851fccSafresh1 51014083a1Safresh1printf("# getitimer: %s\n", join(" ", 52014083a1Safresh1 Time::HiRes::getitimer(&Time::HiRes::ITIMER_VIRTUAL))); 53b8851fccSafresh1 54*b46d8ef2Safresh1# burn CPU until the VTALRM signal handler sets the repeat interval to 55*b46d8ef2Safresh1# zero, indicating that the timer has fired 4 times. 56*b46d8ef2Safresh1while ((Time::HiRes::getitimer(&Time::HiRes::ITIMER_VIRTUAL))[1]) { 57b8851fccSafresh1 my $j; 58b8851fccSafresh1 for (1..1000) { $j++ } # Can't be unbreakable, must test getitimer(). 59b8851fccSafresh1} 60b8851fccSafresh1 61014083a1Safresh1printf("# getitimer: %s\n", join(" ", 62014083a1Safresh1 Time::HiRes::getitimer(&Time::HiRes::ITIMER_VIRTUAL))); 63b8851fccSafresh1 64b8851fccSafresh1$virt = Time::HiRes::getitimer(&Time::HiRes::ITIMER_VIRTUAL); 65014083a1Safresh1print("# at end, i=$i\n"); 66b8851fccSafresh1is($virt, 0, "time left should be zero"); 67b8851fccSafresh1 68b8851fccSafresh1$SIG{VTALRM} = 'DEFAULT'; 69b8851fccSafresh1 70b8851fccSafresh11; 71