diff options
author | Staszek Wawrykiewicz <staw@gust.org.pl> | 2006-12-18 03:24:34 +0000 |
---|---|---|
committer | Staszek Wawrykiewicz <staw@gust.org.pl> | 2006-12-18 03:24:34 +0000 |
commit | fbf4a6e8014789c67a381e0b4f05de5bdadbce24 (patch) | |
tree | 20cc48dd29799a673fe0a628e825114d823493b1 /Master/perltl/lib/Time | |
parent | 34c11d2616bb32772199abf210ae88d99665a824 (diff) |
perltl added
git-svn-id: svn://tug.org/texlive/trunk@2778 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/perltl/lib/Time')
-rw-r--r-- | Master/perltl/lib/Time/HiRes.pm | 357 | ||||
-rw-r--r-- | Master/perltl/lib/Time/Local.pm | 255 |
2 files changed, 612 insertions, 0 deletions
diff --git a/Master/perltl/lib/Time/HiRes.pm b/Master/perltl/lib/Time/HiRes.pm new file mode 100644 index 00000000000..63375320408 --- /dev/null +++ b/Master/perltl/lib/Time/HiRes.pm @@ -0,0 +1,357 @@ +package Time::HiRes; + +use strict; +use vars qw($VERSION $XS_VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD); + +require Exporter; +use XSLoader; + +@ISA = qw(Exporter); + +@EXPORT = qw( ); +@EXPORT_OK = qw (usleep sleep ualarm alarm gettimeofday time tv_interval + getitimer setitimer ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF); + +$VERSION = '1.20_00'; +$XS_VERSION = $VERSION; +$VERSION = eval $VERSION; + +sub AUTOLOAD { + my $constname; + ($constname= $AUTOLOAD) =~ s/.*:://; + my $val = constant($constname, @_ ? $_[0] : 0); + if ($!) { + my ($pack,$file,$line) = caller; + die "Your vendor has not defined Time::HiRes macro $constname, used at $file line $line.\n"; + } + { + no strict 'refs'; + *$AUTOLOAD = sub { $val }; + } + goto &$AUTOLOAD; +} + +XSLoader::load 'Time::HiRes', $XS_VERSION; + +# Preloaded methods go here. + +sub tv_interval { + # probably could have been done in C + my ($a, $b) = @_; + $b = [gettimeofday()] unless defined($b); + (${$b}[0] - ${$a}[0]) + ((${$b}[1] - ${$a}[1]) / 1_000_000); +} + +# Autoload methods go after =cut, and are processed by the autosplit program. + +1; +__END__ + +=head1 NAME + +Time::HiRes - High resolution alarm, sleep, gettimeofday, interval timers + +=head1 SYNOPSIS + + use Time::HiRes qw( usleep ualarm gettimeofday tv_interval ); + + usleep ($microseconds); + + ualarm ($microseconds); + ualarm ($microseconds, $interval_microseconds); + + $t0 = [gettimeofday]; + ($seconds, $microseconds) = gettimeofday; + + $elapsed = tv_interval ( $t0, [$seconds, $microseconds]); + $elapsed = tv_interval ( $t0, [gettimeofday]); + $elapsed = tv_interval ( $t0 ); + + use Time::HiRes qw ( time alarm sleep ); + + $now_fractions = time; + sleep ($floating_seconds); + alarm ($floating_seconds); + alarm ($floating_seconds, $floating_interval); + + use Time::HiRes qw( setitimer getitimer + ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF ); + + setitimer ($which, $floating_seconds, $floating_interval ); + getitimer ($which); + +=head1 DESCRIPTION + +The C<Time::HiRes> module implements a Perl interface to the usleep, +ualarm, gettimeofday, and setitimer/getitimer system calls. See the +EXAMPLES section below and the test scripts for usage; see your system +documentation for the description of the underlying usleep, ualarm, +gettimeofday, and setitimer/getitimer calls. + +If your system lacks gettimeofday(2) or an emulation of it you don't +get gettimeofday() or the one-arg form of tv_interval(). +If you don't have usleep(3) or select(2) you don't get usleep() +or sleep(). If your system don't have ualarm(3) or setitimer(2) you +don't get ualarm() or alarm(). If you try to import an unimplemented +function in the C<use> statement it will fail at compile time. + +The following functions can be imported from this module. +No functions are exported by default. + +=over 4 + +=item gettimeofday () + +In array context returns a 2 element array with the seconds and +microseconds since the epoch. In scalar context returns floating +seconds like Time::HiRes::time() (see below). + +=item usleep ( $useconds ) + +Sleeps for the number of microseconds specified. Returns the number +of microseconds actually slept. Can sleep for more than one second +unlike the usleep system call. See also Time::HiRes::sleep() below. + +=item ualarm ( $useconds [, $interval_useconds ] ) + +Issues a ualarm call; interval_useconds is optional and will be 0 if +unspecified, resulting in alarm-like behaviour. + +=item tv_interval + +C<tv_interval ( $ref_to_gettimeofday [, $ref_to_later_gettimeofday] )> + +Returns the floating seconds between the two times, which should have +been returned by gettimeofday(). If the second argument is omitted, +then the current time is used. + +=item time () + +Returns a floating seconds since the epoch. This function can be +imported, resulting in a nice drop-in replacement for the C<time> +provided with core Perl, see the EXAMPLES below. + +B<NOTE 1>: this higher resolution timer can return values either less or +more than the core time(), depending on whether your platforms rounds +the higher resolution timer values up, down, or to the nearest to get +the core time(), but naturally the difference should be never more than +half a second. + +B<NOTE 2>: Since Sunday, September 9th, 2001 at 01:46:40 AM GMT +(when the time() seconds since epoch rolled over to 1_000_000_000), +the default floating point format of Perl and the seconds since epoch +have conspired to produce an apparent bug: if you print the value of +Time::HiRes::time() you seem to be getting only five decimals, not six +as promised (microseconds). Not to worry, the microseconds are there +(assuming your platform supports such granularity). What is going on +is that the default floating point format of Perl only outputs 15 +digits. In this case that means ten digits before the decimal +separator and five after. To see the microseconds you can use either +printf/sprintf with C<%.6f>, or the gettimeofday() function in list +context, which will give you the seconds and microseconds as two +separate values. + +=item sleep ( $floating_seconds ) + +Sleeps for the specified amount of seconds. Returns the number of +seconds actually slept (a floating point value). This function can be +imported, resulting in a nice drop-in replacement for the C<sleep> +provided with perl, see the EXAMPLES below. + +=item alarm ( $floating_seconds [, $interval_floating_seconds ] ) + +The SIGALRM signal is sent after the specfified number of seconds. +Implemented using ualarm(). The $interval_floating_seconds argument +is optional and will be 0 if unspecified, resulting in alarm()-like +behaviour. This function can be imported, resulting in a nice drop-in +replacement for the C<alarm> provided with perl, see the EXAMPLES below. + +=item setitimer + +C<setitimer ( $which, $floating_seconds [, $interval_floating_seconds ] )> + +Start up an interval timer: after a certain time, a signal arrives, +and more signals may keep arriving at certain intervals. To disable +a timer, use time of zero. If interval is set to zero (or unspecified), +the timer is disabled B<after> the next delivered signal. + +Use of interval timers may interfere with alarm(), sleep(), and usleep(). +In standard-speak the "interaction is unspecified", which means that +I<anything> may happen: it may work, it may not. + +In scalar context, the remaining time in the timer is returned. + +In list context, both the remaining time and the interval are returned. + +There are three interval timers: the $which can be ITIMER_REAL, +ITIMER_VIRTUAL, or ITIMER_PROF. + +ITIMER_REAL results in alarm()-like behavior. Time is counted in +I<real time>, that is, wallclock time. SIGALRM is delivered when +the timer expires. + +ITIMER_VIRTUAL counts time in (process) I<virtual time>, that is, only +when the process is running. In multiprocessor/user/CPU systems this +may be more or less than real or wallclock time. (This time is also +known as the I<user time>.) SIGVTALRM is delivered when the timer expires. + +ITIMER_PROF counts time when either the process virtual time or when +the operating system is running on behalf of the process (such as +I/O). (This time is also known as the I<system time>.) (Collectively +these times are also known as the I<CPU time>.) SIGPROF is delivered +when the timer expires. SIGPROF can interrupt system calls. + +The semantics of interval timers for multithreaded programs are +system-specific, and some systems may support additional interval +timers. See your setitimer() documentation. + +=item getitimer ( $which ) + +Return the remaining time in the interval timer specified by $which. + +In scalar context, the remaining time is returned. + +In list context, both the remaining time and the interval are returned. +The interval is always what you put in using setitimer(). + +=back + +=head1 EXAMPLES + + use Time::HiRes qw(usleep ualarm gettimeofday tv_interval); + + $microseconds = 750_000; + usleep $microseconds; + + # signal alarm in 2.5s & every .1s thereafter + ualarm 2_500_000, 100_000; + + # get seconds and microseconds since the epoch + ($s, $usec) = gettimeofday; + + # measure elapsed time + # (could also do by subtracting 2 gettimeofday return values) + $t0 = [gettimeofday]; + # do bunch of stuff here + $t1 = [gettimeofday]; + # do more stuff here + $t0_t1 = tv_interval $t0, $t1; + + $elapsed = tv_interval ($t0, [gettimeofday]); + $elapsed = tv_interval ($t0); # equivalent code + + # + # replacements for time, alarm and sleep that know about + # floating seconds + # + use Time::HiRes; + $now_fractions = Time::HiRes::time; + Time::HiRes::sleep (2.5); + Time::HiRes::alarm (10.6666666); + + use Time::HiRes qw ( time alarm sleep ); + $now_fractions = time; + sleep (2.5); + alarm (10.6666666); + + # Arm an interval timer to go off first at 10 seconds and + # after that every 2.5 seconds, in process virtual time + + use Time::HiRes qw ( setitimer ITIMER_VIRTUAL time ); + + $SIG{VTLARM} = sub { print time, "\n" }; + setitimer(ITIMER_VIRTUAL, 10, 2.5); + +=head1 C API + +In addition to the perl API described above, a C API is available for +extension writers. The following C functions are available in the +modglobal hash: + + name C prototype + --------------- ---------------------- + Time::NVtime double (*)() + Time::U2time void (*)(UV ret[2]) + +Both functions return equivalent information (like C<gettimeofday>) +but with different representations. The names C<NVtime> and C<U2time> +were selected mainly because they are operating system independent. +(C<gettimeofday> is Un*x-centric.) + +Here is an example of using NVtime from C: + + double (*myNVtime)(); + SV **svp = hv_fetch(PL_modglobal, "Time::NVtime", 12, 0); + if (!svp) croak("Time::HiRes is required"); + if (!SvIOK(*svp)) croak("Time::NVtime isn't a function pointer"); + myNVtime = INT2PTR(double(*)(), SvIV(*svp)); + printf("The current time is: %f\n", (*myNVtime)()); + +=head1 CAVEATS + +Notice that the core time() maybe rounding rather than truncating. +What this means that the core time() may be giving time one second +later than gettimeofday(), also known as Time::HiRes::time(). + +=head1 AUTHORS + +D. Wegscheid <wegscd@whirlpool.com> +R. Schertler <roderick@argon.org> +J. Hietaniemi <jhi@iki.fi> +G. Aas <gisle@aas.no> + +=head1 REVISION + +$Id: HiRes.pm,v 1.20 1999/03/16 02:26:13 wegscd Exp $ + +$Log: HiRes.pm,v $ +Revision 1.20 1999/03/16 02:26:13 wegscd +Add documentation for NVTime and U2Time. + +Revision 1.19 1998/09/30 02:34:42 wegscd +No changes, bump version. + +Revision 1.18 1998/07/07 02:41:35 wegscd +No changes, bump version. + +Revision 1.17 1998/07/02 01:45:13 wegscd +Bump version to 1.17 + +Revision 1.16 1997/11/13 02:06:36 wegscd +version bump to accomodate HiRes.xs fix. + +Revision 1.15 1997/11/11 02:17:59 wegscd +POD editing, courtesy of Gisle Aas. + +Revision 1.14 1997/11/06 03:14:35 wegscd +Update version # for Makefile.PL and HiRes.xs changes. + +Revision 1.13 1997/11/05 05:36:25 wegscd +change version # for Makefile.pl and HiRes.xs changes. + +Revision 1.12 1997/10/13 20:55:33 wegscd +Force a new version for Makefile.PL changes. + +Revision 1.11 1997/09/05 19:59:33 wegscd +New version to bump version for README and Makefile.PL fixes. +Fix bad RCS log. + +Revision 1.10 1997/05/23 01:11:38 wegscd +Conditional compilation; EXPORT_FAIL fixes. + +Revision 1.2 1996/12/30 13:28:40 wegscd +Update documentation for what to do when missing ualarm() and friends. + +Revision 1.1 1996/10/17 20:53:31 wegscd +Fix =head1 being next to __END__ so pod2man works + +Revision 1.0 1996/09/03 18:25:15 wegscd +Initial revision + +=head1 COPYRIGHT + +Copyright (c) 1996-1997 Douglas E. Wegscheid. +All rights reserved. This program is free software; you can +redistribute it and/or modify it under the same terms as Perl itself. + +=cut diff --git a/Master/perltl/lib/Time/Local.pm b/Master/perltl/lib/Time/Local.pm new file mode 100644 index 00000000000..faef1d78694 --- /dev/null +++ b/Master/perltl/lib/Time/Local.pm @@ -0,0 +1,255 @@ +package Time::Local; +use 5.006; +require Exporter; +use Carp; +use Config; +use strict; +use integer; + +our $VERSION = '1.04'; +our @ISA = qw( Exporter ); +our @EXPORT = qw( timegm timelocal ); +our @EXPORT_OK = qw( timegm_nocheck timelocal_nocheck ); + +my @MonthDays = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + +# Determine breakpoint for rolling century +my $ThisYear = (localtime())[5]; +my $Breakpoint = ($ThisYear + 50) % 100; +my $NextCentury = $ThisYear - $ThisYear % 100; + $NextCentury += 100 if $Breakpoint < 50; +my $Century = $NextCentury - 100; +my $SecOff = 0; + +my (%Options, %Cheat); + +my $MaxInt = ((1<<(8 * $Config{intsize} - 2))-1)*2 + 1; +my $MaxDay = int(($MaxInt-43200)/86400)-1; + +# Determine the EPOC day for this machine +my $Epoc = 0; +if ($^O eq 'vos') { +# work around posix-977 -- VOS doesn't handle dates in +# the range 1970-1980. + $Epoc = _daygm((0, 0, 0, 1, 0, 70, 4, 0)); +} +elsif ($^O eq 'MacOS') { + no integer; + + $MaxDay *=2 if $^O eq 'MacOS'; # time_t unsigned ... quick hack? + # MacOS time() is seconds since 1 Jan 1904, localtime + # so we need to calculate an offset to apply later + $Epoc = 693901; + $SecOff = timelocal(localtime(0)) - timelocal(gmtime(0)); + $Epoc += _daygm(gmtime(0)); +} +else { + $Epoc = _daygm(gmtime(0)); +} + +%Cheat=(); # clear the cache as epoc has changed + +sub _daygm { + $_[3] + ($Cheat{pack("ss",@_[4,5])} ||= do { + my $month = ($_[4] + 10) % 12; + my $year = $_[5] + 1900 - $month/10; + 365*$year + $year/4 - $year/100 + $year/400 + ($month*306 + 5)/10 - $Epoc + }); +} + + +sub _timegm { + my $sec = $SecOff + $_[0] + 60 * $_[1] + 3600 * $_[2]; + + no integer; + + $sec + 86400 * &_daygm; +} + + +sub timegm { + my ($sec,$min,$hour,$mday,$month,$year) = @_; + + if ($year >= 1000) { + $year -= 1900; + } + elsif ($year < 100 and $year >= 0) { + $year += ($year > $Breakpoint) ? $Century : $NextCentury; + } + + unless ($Options{no_range_check}) { + if (abs($year) >= 0x7fff) { + $year += 1900; + croak "Cannot handle date ($sec, $min, $hour, $mday, $month, $year)"; + } + + croak "Month '$month' out of range 0..11" if $month > 11 or $month < 0; + + my $md = $MonthDays[$month]; + ++$md unless $month != 1 or $year % 4 or !($year % 400); + + croak "Day '$mday' out of range 1..$md" if $mday > $md or $mday < 1; + croak "Hour '$hour' out of range 0..23" if $hour > 23 or $hour < 0; + croak "Minute '$min' out of range 0..59" if $min > 59 or $min < 0; + croak "Second '$sec' out of range 0..59" if $sec > 59 or $sec < 0; + } + + my $days = _daygm(undef, undef, undef, $mday, $month, $year); + + unless ($Options{no_range_check} or abs($days) < $MaxDay) { + $year += 1900; + croak "Cannot handle date ($sec, $min, $hour, $mday, $month, $year)"; + } + + $sec += $SecOff + 60*$min + 3600*$hour; + + no integer; + + $sec + 86400*$days; +} + + +sub timegm_nocheck { + local $Options{no_range_check} = 1; + &timegm; +} + + +sub timelocal { + no integer; + my $ref_t = &timegm; + my $loc_t = _timegm(localtime($ref_t)); + + # Is there a timezone offset from GMT or are we done + my $zone_off = $ref_t - $loc_t + or return $loc_t; + + # Adjust for timezone + $loc_t = $ref_t + $zone_off; + + # Are we close to a DST change or are we done + my $dst_off = $ref_t - _timegm(localtime($loc_t)) + or return $loc_t; + + # Adjust for DST change + $loc_t + $dst_off; +} + + +sub timelocal_nocheck { + local $Options{no_range_check} = 1; + &timelocal; +} + +1; + +__END__ + +=head1 NAME + +Time::Local - efficiently compute time from local and GMT time + +=head1 SYNOPSIS + + $time = timelocal($sec,$min,$hour,$mday,$mon,$year); + $time = timegm($sec,$min,$hour,$mday,$mon,$year); + +=head1 DESCRIPTION + +These routines are the inverse of built-in perl functions localtime() +and gmtime(). They accept a date as a six-element array, and return +the corresponding time(2) value in seconds since the Epoch (Midnight, +January 1, 1970). This value can be positive or negative. + +It is worth drawing particular attention to the expected ranges for +the values provided. The value for the day of the month is the actual day +(ie 1..31), while the month is the number of months since January (0..11). +This is consistent with the values returned from localtime() and gmtime(). + +The timelocal() and timegm() functions perform range checking on the +input $sec, $min, $hour, $mday, and $mon values by default. If you'd +rather they didn't, you can explicitly import the timelocal_nocheck() +and timegm_nocheck() functions. + + use Time::Local 'timelocal_nocheck'; + + { + # The 365th day of 1999 + print scalar localtime timelocal_nocheck 0,0,0,365,0,99; + + # The twenty thousandth day since 1970 + print scalar localtime timelocal_nocheck 0,0,0,20000,0,70; + + # And even the 10,000,000th second since 1999! + print scalar localtime timelocal_nocheck 10000000,0,0,1,0,99; + } + +Your mileage may vary when trying these with minutes and hours, +and it doesn't work at all for months. + +Strictly speaking, the year should also be specified in a form consistent +with localtime(), i.e. the offset from 1900. +In order to make the interpretation of the year easier for humans, +however, who are more accustomed to seeing years as two-digit or four-digit +values, the following conventions are followed: + +=over 4 + +=item * + +Years greater than 999 are interpreted as being the actual year, +rather than the offset from 1900. Thus, 1963 would indicate the year +Martin Luther King won the Nobel prize, not the year 2863. + +=item * + +Years in the range 100..999 are interpreted as offset from 1900, +so that 112 indicates 2012. This rule also applies to years less than zero +(but see note below regarding date range). + +=item * + +Years in the range 0..99 are interpreted as shorthand for years in the +rolling "current century," defined as 50 years on either side of the current +year. Thus, today, in 1999, 0 would refer to 2000, and 45 to 2045, +but 55 would refer to 1955. Twenty years from now, 55 would instead refer +to 2055. This is messy, but matches the way people currently think about +two digit dates. Whenever possible, use an absolute four digit year instead. + +=back + +The scheme above allows interpretation of a wide range of dates, particularly +if 4-digit years are used. + +Please note, however, that the range of dates that can be actually be handled +depends on the size of an integer (time_t) on a given platform. +Currently, this is 32 bits for most systems, yielding an approximate range +from Dec 1901 to Jan 2038. + +Both timelocal() and timegm() croak if given dates outside the supported +range. + +=head1 IMPLEMENTATION + +These routines are quite efficient and yet are always guaranteed to agree +with localtime() and gmtime(). We manage this by caching the start times +of any months we've seen before. If we know the start time of the month, +we can always calculate any time within the month. The start times +are calculated using a mathematical formula. Unlike other algorithms +that do multiple calls to gmtime(). + +timelocal() is implemented using the same cache. We just assume that we're +translating a GMT time, and then fudge it when we're done for the timezone +and daylight savings arguments. Note that the timezone is evaluated for +each date because countries occasionally change their official timezones. +Assuming that localtime() corrects for these changes, this routine will +also be correct. + +=head1 BUGS + +The whole scheme for interpreting two-digit years can be considered a bug. + +The proclivity to croak() is probably a bug. + +=cut + |