#!/usr/bin/perl -w
#< test-time.pl
# Various time tests...
use strict;
use warnings;
use IO::Socket;
use Time::HiRes qw( usleep gettimeofday tv_interval );

my $microseconds = 7500000;
my $seconds = 1;

sub prt($) {
    print shift;
}

sub get_time_stg($) {
    my $elap = shift;
    my $negative = 0;
    my $units = '';
    if ($elap < 0) {
        $negative = 1;
        $elap = -$elap;
    }
    if ( !($elap > 0.0) ) {
        return "0.0 s";
    }
    if ($elap < 1e-21) {
        #// yocto - 10^-24
        $elap *= 1e+21;
        $units = "ys";
    } elsif ($elap < 1e-18) {
        #// zepto - 10^-21
        $elap *= 1e+18;
        $units = "zs";
    } elsif ($elap < 1e-15) {
        #// atto - 10^-18
        $elap *= 1e+15;
        $units = "as";
    } elsif ($elap < 1e-12) {
        #// femto - 10^-15
        $elap *= 1e+12;
        $units = "fs";
    } elsif ($elap < 1e-9) {
        #// pico - 10^-12
        $elap *= 1e+9;
        $units = "ps";
    } elsif ($elap < 1e-6) {
        #// nanosecond - one thousand millionth (10?9) of a second
        $elap *= 1e+6;
        $units = "ns";
    } elsif ($elap < 1e-3) {
        #// microsecond - one millionth (10?6) of a second
        $elap *= 1e+3;
        $units = "us";
    } elsif ($elap < 1.0) {
        #// millisecond
        $elap *= 1000.0;
        $units = "ms";
    } elsif ($elap < 60.0) {
        $units = "s";
    } else {
        my $secs = int($elap + 0.5);
        my $mins = int($secs / 60);
        $secs = ($secs % 60);
        if ($mins >= 60) {
            my $hrs = int($mins / 60);
            $mins = $mins % 60;
            if ($hrs >= 24) {
                my $days = int($hrs / 24);
                $hrs = $hrs % 24;
                return sprintf("%d days %2d:%02d:%02d hh:mm:ss", $days, $hrs, $mins, $secs);
            } else {
                return sprintf("%2d:%02d:%02d hh:mm:ss", $hrs, $mins, $secs);
            }
        } else {
            return sprintf("%2d:%02d mm:ss", $mins, $secs);
        }
    }
    my $res = '';
    if ($negative) {
        $res = '-';
    }
    $res .= "$elap $units";
    return $res;
}

sub do_usleep_for($) {
    my $ms = shift;
    my ($t1,$t2,$s,$tm);
    $s =$ms / 1000000;
    $tm = get_time_stg($s);
    prt("Trying 'usleep' for $ms microseconds ($tm)...\n");
    $t1 = [gettimeofday];
    usleep($ms);
    $t2 = [gettimeofday];
    $s = tv_interval( $t1, $t2 );
    $tm = get_time_stg($s);
    prt("Using usleep for $ms us - elapsed = $s seconds ($tm)\n");
}

sub test_usleep($) {
    my $ms = shift;
    while ($ms > 10) {
        do_usleep_for($ms);
        $ms /= 10;
    }
}

my $TB = [gettimeofday];
my ($T1,$T2,$TE,$elap);

prt("Trying 'sleep' for $seconds seconds...\n");
$T1 = [gettimeofday];
sleep $seconds;
$T2 = [gettimeofday];
$elap = tv_interval( $T1, $T2 );
prt("Using sleep 1 - Elapsed = $elap seconds (".get_time_stg($elap)."\n");

test_usleep($microseconds);
do_usleep_for(65 * 1000);
do_usleep_for(150 * 1000);

$TE = [gettimeofday];
$elap = tv_interval( $TB, $TE );
prt("\nTotal Elapsed = $elap seconds\n");

exit 0;

# eof - test-time.pl

