5 unless(&Time::HiRes::d_ualarm) {
7 Test::More::plan(skip_all => "no ualarm()");
11 use Test::More tests => 12;
12 BEGIN { push @INC, '.' }
18 skip "no alarm", 2 unless $Config{d_alarm};
20 local $SIG{ ALRM } = sub { $tick++ };
23 $tick = 0; Time::HiRes::ualarm(10_000); while ($tick == 0) { }
25 $tick = 0; Time::HiRes::ualarm(10_000); while ($tick == 0) { }
26 my $three = CORE::time;
27 ok $one == $two || $two == $three
28 or print("# slept too long, $one $two $three\n");
29 print("# tick = $tick, one = $one, two = $two, three = $three\n");
31 $tick = 0; Time::HiRes::ualarm(10_000, 10_000); while ($tick < 3) { }
33 Time::HiRes::ualarm(0);
34 print("# tick = $tick, one = $one, two = $two, three = $three\n");
37 eval { Time::HiRes::ualarm(-4) };
38 like $@, qr/::ualarm\(-4, 0\): negative time not invented yet/,
39 "negative time error";
41 # Find the loop size N (a for() loop 0..N-1)
42 # that will take more than T seconds.
44 sub bellish { # Cheap emulation of a bell curve.
46 my $rand = ($max - $min) / 5;
54 # 1_100_000 slightly over 1_000_000,
55 # 2_200_000 slightly over 2**31/1000,
56 # 4_300_000 slightly over 2**32/1000.
57 for my $n (100_000, 1_100_000, 2_200_000, 4_300_000) {
59 for my $retry (1..10) {
61 local $SIG{ ALRM } = sub { $alarmed++ };
62 my $t0 = Time::HiRes::time();
63 print("# t0 = $t0\n");
64 print("# ualarm($n)\n");
65 Time::HiRes::ualarm($n); 1 while $alarmed == 0;
66 my $t1 = Time::HiRes::time();
67 print("# t1 = $t1\n");
69 print("# dt = $dt\n");
70 my $r = $dt / ($n/1e6);
73 ($n < 1_000_000 || # Too much noise.
74 ($r >= 0.8 && $r <= 1.6));
76 my $nap = bellish(3, 15);
77 printf("# Retrying in %.1f seconds...\n", $nap);
78 Time::HiRes::sleep($nap);
80 ok $ok or print("# ualarm($n) close enough\n");
86 $SIG{ALRM} = sub { $alrm0++ };
87 my $t0 = Time::HiRes::time();
88 my $got0 = Time::HiRes::ualarm(500_000);
93 $t1 = Time::HiRes::time();
94 } while $t1 - $t0 <= 0.3;
95 my $got1 = Time::HiRes::ualarm(0);
97 print("# t0 = $t0\n");
98 print("# got0 = $got0\n");
99 print("# t1 = $t1\n");
100 printf("# t1 - t0 = %s\n", ($t1 - $t0));
101 print("# got1 = $got1\n");
102 ok $got0 == 0 or print("# $got0\n");
104 skip "alarm interval exceeded", 2 if $t1 - $t0 >= 0.5;
109 my $got2 = Time::HiRes::ualarm(0);
110 ok $got2 == 0 or print("# $got2\n");