#Article 8303 of comp.lang.perl:
#Xref: feenix.metronet.com comp.lang.perl:8303
#Newsgroups: comp.lang.perl
#Path: feenix.metronet.com!news.ecn.bgu.edu!usenet.ins.cwru.edu!agate!library.ucla.edu!europa.eng.gtefsd.com!uunet!boulder!wraeththu.cs.colorado.edu!tchrist
#From: Tom Christiansen <
[email protected]>
#Subject: Re: Why doesn't Perl use usleep and ualarm?
#Message-ID: <
[email protected]>
#Originator:
[email protected]
#Sender:
[email protected] (USENET News System)
#Reply-To:
[email protected] (Tom Christiansen)
#Organization: University of Colorado, Boulder
#References: <
[email protected]>
#Date: Wed, 24 Nov 1993 12:34:25 GMT
#Lines: 116
#
#:-> In comp.lang.perl,
[email protected] (Dov Grobgeld) writes:
#:One on the nice things about Perl is that there is that
#:floating points and integers are treated with equal respect.
#:But an exeption to this is the sleep and alarm commands. If I
#:write sleep(0.5) I expect the program to sleep for half a
#:second or 500_000 micro seconds. Shouldn't the Perl sleep
#:command really call usleep(2)? The same thing is true about the
#:alarm command which should call ualarm(). Is there a deep
#:reason which I'm missing?
#:
#:Another relevent question is about timers. Would it be possible
#:to have some interface to setitimers() in order to get a
#:periodic interrupt? Of course I can send a new alarm signal
#:inside my ISR, but that won't be as exect, and is not as
#:nicelooking, IMHO.
#
#Here's something I wrote long ago but haven't played with much lately.
#
# itimers.pl - timer manipulation functions
# written by tom christiansen <
[email protected]>
#
# alarm - like libc call but can take and returns floats
#
# getitimer, setitimer - like syscalls but return true on success
# NB: require packed data for args
#
# itimer - conversion function for packing and
# unpacking itimers. packs in scalar context,
# unpacks in array context.
package itimers;
require 'sys/syscall.ph';
require 'sys/time.ph';
defined &alarm;
defined &getitimer;
defined &setitimer;
defined &itimer;
if (defined &itimer'sizeof) {
$itimer_t = &itimer'typedef();
$itimer_s = &itimer'sizeof();
} else {
# careful: implementation dependent!
#
$itimer_t = 'L4'; # itimers consist of four longs
$itimer_s = length(pack($itimer_t, 0,0,0,0));
}
###########################################################################
#
# alarm; send me a SIGALRM in this many seconds (fractions ok)
#
#
sub alarm {
local($ticks) = @_;
local($itimer,$otimer);
local($isecs, $iusecs, $secs, $usecs);
$secs = int($ticks);
$usecs = ($ticks - $secs) * 1e6;
$otimer = &itimer(0,0,0,0);
$itimer = &itimer(0,0,$secs,$usecs);
&setitimer(&ITIMER_REAL, $itimer, $otimer)
|| warn "alarm: setitimer failed: $!";
($isecs, $iusecs, $secs, $usecs) = &itimer($otimer);
return $secs + ($usecs/1e6);
}
###########################################################################
sub setitimer {
local($which) = shift;
local($retval);
die "setitimer: input itimer not length $itimer_s"
unless length($_[0]) == $itimer_s;
$_[1] = &itimer(0,0,0,0);
!syscall(&SYS_setitimer, $which, $_[0], $_[1]);
}
###########################################################################
sub getitimer {
local($which) = shift;
$_[0] = &itimer(0,0,0,0);
!syscall(&SYS_getitimer, $which, $_[0]);
}
###########################################################################
# itimer conversion function; this one goes both ways
#
sub itimer {
if (wantarray) {
warn "itimer: only expected one arg in array context"
if @_ > 1;
warn "itimer: itimer to unpack not length $itimer_s"
unless length($_[0]) == $itimer_s;
return unpack($itimer_t, $_[0]);
} else {
warn "itimer: only expected 4 args in scalar context"
if @_ > 4;
return pack($itimer_t, $_[0], $_[1], $_[2], $_[3]);
}
}
#--
# Tom Christiansen
[email protected]
# "Will Hack Perl for Fine Food and Fun"
# Boulder Colorado 303-444-3212
#
#
1;