marc@athena.mit.edu (Marc Horowitz) (11/26/90)
Feature request: Is there a reason gettimeofday isn't in perl? It exists in both BSD and SYSV, the PC can approximate it, although with less precision, and it's hard to do without a primitive (syscall is "hard"). I can't imagine how it could break existing scripts. Just define gettimeofday() which returns ($tv_sec,$tv_usec). Or make it really spiffy and have it return that in a list context, and $tv_sec+$tv_usec/1000000 in a scalar context. Marc
tchrist@convex.COM (Tom Christiansen) (11/28/90)
In article <1990Nov26.042245.29893@uvaarpa.Virginia.EDU> marc@mit.edu writes: >Feature request: > >Is there a reason gettimeofday isn't in perl? It exists in both BSD >and SYSV, the PC can approximate it, although with less precision, and >it's hard to do without a primitive (syscall is "hard"). I can't >imagine how it could break existing scripts. Just define >gettimeofday() which returns ($tv_sec,$tv_usec). Or make it really >spiffy and have it return that in a list context, and >$tv_sec+$tv_usec/1000000 in a scalar context. "Spiffy" is one of the things some people (pas moi) don't like about perl. I would say gettimeofday isn't there because it isn't on every system. Yes, Tom, I hear you say, but what about socket? Yes, there is that. But socket has to work with internal datatypes that you can't mock up very well just using syscall. You say using syscall is hard, but I would say having to know contextually dependent behavior is harder still. When I want better time than "time" gives me, and I'm trying to be quick, I do this: # for milliseconds; otherwise would use built-in time. sub time { local($SYS_gettimeofday, $timeval, $timezone, $sec, $usec); $SYS_gettimeofday = 116; # should really be from sys/syscalls.ph $timeval = $timezone = ("\0" x 4) x 2; syscall($SYS_gettimeofday, $timeval, $timezone) && die "gettimeofday failed: $!"; ($sec, $usec) = unpack("L2", $timeval); return $sec + $usec/1e6; } But when I'm trying to be a little more careful, I do this: #!/usr/local/bin/perl require 'timeofday.pl'; printf "It is now %f seconds past the epoch.\n", $now = &time; printf "We are in the %s timezone, ", $zone = &zone; printf "which is considered %s time.\n", &zonename($zone); printf "Merely %g seconds have passed since the program started.\n", &time - $now; where timeofday.pl is the following: #!/usr/local/bin/perl package main; require 'syscall.ph'; $SYS_gettimeofday = &'SYS_gettimeofday unless defined $SYS_gettimeofday; package gettimeofday; $timeval_t = 'LL'; $timezone_t = 'II'; %zones_by_minute = ( 0*60, "WET", -1*60, "MET", -2*60, "EET", -8*60, "AWST", -10*60, "AEST", -10*60+30, "ACST", 4*60, "AST", 5*60, "EST", 6*60, "CST", 7*60, "MST", 8*60, "PST", ); %zones_by_abbr = ( "WET", "Western European", "MET", "Middle European", "EET", "Eastern European", "AWST", "Western Australian", "AEST", "Eastern Australian", "ACST", "Central Australian", "AST", "Atlantic", "EST", "Eastern", "CST", "Central", "MST", "Mountain", "PST", "Pacific", ); sub timeval { wantarray ? unpack($timeval_t, $_[0]) : pack($timeval_t, @_); } sub timezone { wantarray ? unpack($timezone_t, $_[0]) : pack($timezone_t, @_); } sub main'time { local($val, $zone) = &'gettimeofday; local($sec, $usec) = &timeval($val); $sec + $usec/1e6; } sub main'zone { local($val, $zone) = &'gettimeofday; ($mins, $dst) = &timezone($zone); defined $zones_by_minute{$mins} ? $zones_by_minute{$mins} : $mins; } sub main'zonename { $zones_by_abbr{$_[0]}; } sub main'gettimeofday { local($val, $zone); $val = &timeval; $zone = &timezone; syscall($'SYS_gettimeofday, $val, $zone) && do { warn "gettimeofday: SYS_gettimeofday failed: $!"; ($val, $zone) = (); }; ($val, $zone); } There's some question whether I should export &timeval and &timezone (which are protected, magic, bidirectional conversion functions), since I am exporting &gettimeofday and it is returning packed data. And of course I'm doing nothing with the $dst flag, and my table is incomplete, and so on and so forth. But it's an idea. I really don't like that I can't duplicate ctime(3) output because I can't pin down the timezone without having $TZ set. --tom
marc@athena.mit.edu (Marc Horowitz) (11/29/90)
|> "Spiffy" is one of the things some people (pas moi) don't like about perl. It's one of the things I like, too. Even if you don't make gettimeofday spiffy, it's still worthwhile, I think. |> I would say gettimeofday isn't there because it isn't on every system. |> Yes, Tom, I hear you say, but what about socket? Yes, there is that. |> But socket has to work with internal datatypes that you can't mock |> up very well just using syscall. You say using syscall is hard, but |> I would say having to know contextually dependent behavior is harder |> still. The gettimeofday syscall isn't on every system, but the functionality does exist (to some resolution < 1 sec) on almost every system I've seen (including the PC and Amiga). So implement a function, call it gettime if you don't like gettimeofday, which returns the time as a number of seconds (including fractional part) since the unix epoch. On non-unix systems, you may need to fudge by a constant factor. This is certainly more consistent, and more obvious, then using syscall on my unix box, and some other method on my pc. You could also implement gettimezone or something like that to get the time zone (this isn't implemented on all machines, though). One of the best things about perl is that it provides a uniform way of doing things across many heterogeneous platforms. syscall, although useful at times, does not keep this elegance. Marc