BEGIN {
push
@INC
,
'.'
}
BEGIN { require_ok
"Time::HiRes"
; }
my
$limit
= 0.25;
my
$xdefine
=
''
;
if
(
open
(XDEFINE,
"<"
,
"xdefine"
)) {
chomp
(
$xdefine
= <XDEFINE> ||
""
);
close
(XDEFINE);
}
my
$can_subsecond_alarm
=
defined
&Time::HiRes::gettimeofday
&&
defined
&Time::HiRes::ualarm
&&
defined
&Time::HiRes::usleep
&&
(
$Config
{d_ualarm} ||
$xdefine
=~ /-DHAS_UALARM/);
SKIP: {
skip
"no subsecond alarm"
, 1
unless
$can_subsecond_alarm
;
my
$use_sigaction
=
!$@ &&
defined
&POSIX::sigaction
&&
&POSIX::SIGALRM
> 0;
my
(
$r
,
$i
,
$not
,
$ok
);
$not
=
""
;
$r
= [Time::HiRes::gettimeofday()];
$i
= 5;
my
$oldaction
;
if
(
$use_sigaction
) {
$oldaction
= new POSIX::SigAction;
printf
(
"# sigaction tick, ALRM = %d\n"
,
&POSIX::SIGALRM
);
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"
;
}
if
($^O eq
'VMS'
) {
$ok
=
"Skip: VMS select() does not get interrupted."
;
}
else
{
while
(
$i
> 0) {
Time::HiRes::
alarm
(0.3);
select
(
undef
,
undef
,
undef
, 3);
my
$ival
= Time::HiRes::tv_interval (
$r
);
print
(
"# Select returned! $i $ival\n"
);
printf
(
"# %s\n"
,
abs
(
$ival
/3 - 1));
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
);
if
(
$exp
== 0) {
$not
=
"while: divisor became zero"
;
last
;
}
if
(
abs
(
$ival
/
$exp
- 1) > 4
*$limit
) {
my
$ratio
=
abs
(
$ival
/
$exp
);
$not
=
"while: $exp sleep took $ival ratio $ratio"
;
last
;
}
$ok
=
$i
;
}
}
sub
tick {
$i
--;
my
$ival
= Time::HiRes::tv_interval (
$r
);
print
(
"# Tick! $i $ival\n"
);
my
$exp
= 0.3 * (5 -
$i
);
if
(
$exp
== 0) {
$not
=
"tick: divisor became zero"
;
last
;
}
if
(
abs
(
$ival
/
$exp
- 1) > 4
*$limit
) {
my
$ratio
=
abs
(
$ival
/
$exp
);
$not
=
"tick: $exp sleep took $ival ratio $ratio"
;
$i
= 0;
}
}
if
(
$use_sigaction
) {
POSIX::sigaction(
&POSIX::SIGALRM
,
$oldaction
);
}
else
{
Time::HiRes::
alarm
(0);
}
print
(
"# $not\n"
);
ok !
$not
;
}
SKIP: {
skip
"no ualarm"
, 1
unless
&Time::HiRes::d_ualarm
;
eval
{ Time::HiRes::
alarm
(-3) };
like $@,
qr/::alarm\(-3, 0\): negative time not invented yet/
,
"negative time error"
;
}
SKIP: {
skip
"no ualarm"
, 1
unless
&Time::HiRes::d_ualarm
;
skip
"perl bug"
, 1
unless
$] >= 5.008001;
print
(
"# Finding delay loop...\n"
);
my
$T
= 0.01;
my
$DelayN
= 1024;
my
$i
;
N: {
do
{
my
$t0
= Time::HiRes::
time
();
for
(
$i
= 0;
$i
<
$DelayN
;
$i
++) { }
my
$t1
= Time::HiRes::
time
();
my
$dt
=
$t1
-
$t0
;
print
(
"# N = $DelayN, t1 = $t1, t0 = $t0, dt = $dt\n"
);
last
N
if
$dt
>
$T
;
$DelayN
*= 2;
}
while
(1);
}
my
$Delay
=
sub
{
my
$c
=
@_
?
shift
: 1;
my
$n
=
$c
*
$DelayN
;
my
$i
;
for
(
$i
= 0;
$i
<
$n
;
$i
++) { }
};
my
$a
= 0;
my
$A
= 2;
$SIG
{ALRM} =
sub
{
$a
++;
printf
(
"# Alarm $a - %s\n"
, Time::HiRes::
time
());
Time::HiRes::
alarm
(0)
if
$a
>=
$A
;
$Delay
->(2);
};
Time::HiRes::
alarm
(
$T
,
$T
);
$Delay
->(10);
ok 1;
}
SKIP: {
skip
"no subsecond alarm"
, 6
unless
$can_subsecond_alarm
;
{
my
$alrm
;
$SIG
{ALRM} =
sub
{
$alrm
++ };
Time::HiRes::
alarm
(0.1);
my
$t0
= Time::HiRes::
time
();
1
while
Time::HiRes::
time
() -
$t0
<= 1;
ok
$alrm
;
}
{
my
$alrm
;
$SIG
{ALRM} =
sub
{
$alrm
++ };
Time::HiRes::
alarm
(1.1);
my
$t0
= Time::HiRes::
time
();
1
while
Time::HiRes::
time
() -
$t0
<= 2;
ok
$alrm
;
}
{
my
$alrm
= 0;
$SIG
{ALRM} =
sub
{
$alrm
++ };
my
$got
= Time::HiRes::
alarm
(2.7);
ok
$got
== 0 or
print
(
"# $got\n"
);
my
$t0
= Time::HiRes::
time
();
1
while
Time::HiRes::
time
() -
$t0
<= 1;
$got
= Time::HiRes::
alarm
(0);
ok
$got
> 0 &&
$got
< 1.8 or
print
(
"# $got\n"
);
ok
$alrm
== 0 or
print
(
"# $alrm\n"
);
$got
= Time::HiRes::
alarm
(0);
ok
$got
== 0 or
print
(
"# $got\n"
);
}
}
1;