xref: /openbsd-src/gnu/usr.bin/perl/dist/Time-HiRes/t/clock.t (revision 56d68f1e19ff848c889ecfa71d3a06340ff64892)
1b8851fccSafresh1use strict;
2b8851fccSafresh1
3014083a1Safresh1use Test::More tests => 5;
4*9f11ffb7Safresh1BEGIN { push @INC, '.' }
5b8851fccSafresh1use t::Watchdog;
6b8851fccSafresh1
7b8851fccSafresh1BEGIN { require_ok "Time::HiRes"; }
8b8851fccSafresh1
9b8851fccSafresh1sub has_symbol {
10b8851fccSafresh1    my $symbol = shift;
11b8851fccSafresh1    eval "use Time::HiRes qw($symbol)";
12b8851fccSafresh1    return 0 unless $@ eq '';
13b8851fccSafresh1    eval "my \$a = $symbol";
14b8851fccSafresh1    return $@ eq '';
15b8851fccSafresh1}
16b8851fccSafresh1
17014083a1Safresh1printf("# have_clock_gettime   = %d\n", &Time::HiRes::d_clock_gettime);
18014083a1Safresh1printf("# have_clock_getres    = %d\n", &Time::HiRes::d_clock_getres);
19014083a1Safresh1printf("# have_clock_nanosleep = %d\n", &Time::HiRes::d_clock_nanosleep);
20014083a1Safresh1printf("# have_clock           = %d\n", &Time::HiRes::d_clock);
21b8851fccSafresh1
22b8851fccSafresh1# Ideally, we'd like to test that the timers are rather precise.
23b8851fccSafresh1# However, if the system is busy, there are no guarantees on how
24b8851fccSafresh1# quickly we will return.  This limit used to be 10%, but that
25b8851fccSafresh1# was occasionally triggered falsely.
26b8851fccSafresh1# So let's try 25%.
27b8851fccSafresh1# Another possibility might be to print "ok" if the test completes fine
28b8851fccSafresh1# with (say) 10% slosh, "skip - system may have been busy?" if the test
29b8851fccSafresh1# completes fine with (say) 30% slosh, and fail otherwise.  If you do that,
30b8851fccSafresh1# consider changing over to test.pl at the same time.
31b8851fccSafresh1# --A.D., Nov 27, 2001
32b8851fccSafresh1my $limit = 0.25; # 25% is acceptable slosh for testing timers
33b8851fccSafresh1
34b8851fccSafresh1SKIP: {
35b8851fccSafresh1    skip "no clock_gettime", 1
36b8851fccSafresh1        unless &Time::HiRes::d_clock_gettime && has_symbol("CLOCK_REALTIME");
37b8851fccSafresh1    my $ok = 0;
38b8851fccSafresh1 TRY: {
39b8851fccSafresh1        for my $try (1..3) {
40014083a1Safresh1            print("# CLOCK_REALTIME: try = $try\n");
41b8851fccSafresh1            my $t0 = Time::HiRes::clock_gettime(&CLOCK_REALTIME);
42b8851fccSafresh1            my $T = 1.5;
43b8851fccSafresh1            Time::HiRes::sleep($T);
44b8851fccSafresh1            my $t1 = Time::HiRes::clock_gettime(&CLOCK_REALTIME);
45b8851fccSafresh1            if ($t0 > 0 && $t1 > $t0) {
46014083a1Safresh1                print("# t1 = $t1, t0 = $t0\n");
47b8851fccSafresh1                my $dt = $t1 - $t0;
48b8851fccSafresh1                my $rt = abs(1 - $dt / $T);
49014083a1Safresh1                print("# dt = $dt, rt = $rt\n");
50b8851fccSafresh1                if ($rt <= 2 * $limit) {
51b8851fccSafresh1                    $ok = 1;
52b8851fccSafresh1                    last TRY;
53b8851fccSafresh1                }
54b8851fccSafresh1            } else {
55014083a1Safresh1                print("# Error: t0 = $t0, t1 = $t1\n");
56b8851fccSafresh1            }
57b8851fccSafresh1            my $r = rand() + rand();
58014083a1Safresh1            printf("# Sleeping for %.6f seconds...\n", $r);
59b8851fccSafresh1            Time::HiRes::sleep($r);
60b8851fccSafresh1        }
61b8851fccSafresh1    }
62b8851fccSafresh1    ok $ok;
63b8851fccSafresh1}
64b8851fccSafresh1
65b8851fccSafresh1SKIP: {
66b8851fccSafresh1    skip "no clock_getres", 1 unless &Time::HiRes::d_clock_getres;
67b8851fccSafresh1    my $tr = Time::HiRes::clock_getres();
68014083a1Safresh1    ok $tr > 0 or print("# tr = $tr\n");
69b8851fccSafresh1}
70b8851fccSafresh1
71b8851fccSafresh1SKIP: {
72b8851fccSafresh1    skip "no clock_nanosleep", 1
73b8851fccSafresh1        unless &Time::HiRes::d_clock_nanosleep && has_symbol("CLOCK_REALTIME");
74b8851fccSafresh1    my $s = 1.5e9;
75b8851fccSafresh1    my $t = Time::HiRes::clock_nanosleep(&CLOCK_REALTIME, $s);
76b8851fccSafresh1    my $r = abs(1 - $t / $s);
77014083a1Safresh1    ok $r < 2 * $limit or print("# t = $t, r = $r\n");
78b8851fccSafresh1}
79b8851fccSafresh1
80b8851fccSafresh1SKIP: {
81b8851fccSafresh1    skip "no clock", 1 unless &Time::HiRes::d_clock;
82*9f11ffb7Safresh1    skip "no CLOCKS_PER_SEC", 1 unless has_symbol("CLOCKS_PER_SEC");
83b8851fccSafresh1    my @clock = Time::HiRes::clock();
84*9f11ffb7Safresh1    # If we have a relatively low precision clock() and we haven't seen much
85*9f11ffb7Safresh1    # CPU usage thus far with clock(), we will want to have a bit longer delay.
86*9f11ffb7Safresh1    my $delay = $clock[0] < (5 / &Time::HiRes::CLOCKS_PER_SEC) ? 1e7 : 1e6;
87*9f11ffb7Safresh1    printf("# CLOCKS_PER_SEC = %d\n", &Time::HiRes::CLOCKS_PER_SEC);
88*9f11ffb7Safresh1    printf("# delay = %d\n", $delay);
89014083a1Safresh1    print("# clock = @clock\n");
90b8851fccSafresh1    for my $i (1..3) {
91*9f11ffb7Safresh1        for (my $j = 0; $j < $delay; $j++) { }
92b8851fccSafresh1        push @clock, Time::HiRes::clock();
93014083a1Safresh1        print("# clock = @clock\n");
94b8851fccSafresh1    }
95b8851fccSafresh1    ok $clock[0] >= 0 &&
96b8851fccSafresh1        $clock[1] > $clock[0] &&
97b8851fccSafresh1        $clock[2] > $clock[1] &&
98b8851fccSafresh1        $clock[3] > $clock[2];
99b8851fccSafresh1}
100b8851fccSafresh1
101b8851fccSafresh11;
102