pkgsrc-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
pkg/46673: time/p5-Time-HiRes: "usleep( 1000000 )" does not sleep on NetBSD
>Number: 46673
>Category: pkg
>Synopsis: time/p5-Time-HiRes: "usleep( 1000000 )" does not sleep on
>NetBSD
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: pkg-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jul 08 16:45:00 +0000 2012
>Originator: Michai Ramakers
>Release: 6.0 BETA2
>Organization:
>Environment:
NetBSD main.LAN 6.0_BETA2 NetBSD 6.0_BETA2 (GENERIC) amd64
>Description:
sleeping exactly 1000000 us using Time::HiRes::usleep() incorrectly returns
(almost) immediately, while sleeping 999999 us or 1000001 us correctly sleeps
around 1 s.
tested on NetBSD 6.0 BETA2 amd64 with Time::HiRes 1.972101, and NetBSD 5.1 i386
with Time::HiRes 1.9719, both expose this symptom.
Analysis:
From Time::HiRes 1.9724 (same version as in pkgsrc-2012Q1) 'HiRes.xs':
785 #if defined(HAS_USLEEP) && defined(HAS_GETTIMEOFDAY)
786
787 NV
788 usleep(useconds)
789 NV useconds
790 PREINIT:
791 struct timeval Ta, Tb;
792 CODE:
793 gettimeofday(&Ta, NULL);
794 if (items > 0) {
795 if (useconds > 1E6) {
796 IV seconds = (IV) (useconds / 1E6);
797 /* If usleep() has been implemented using setitimer()
798 * then this contortion is unnecessary-- but usleep()
799 * may be implemented in some other way, so let's contort. */
800 if (seconds) {
801 sleep(seconds);
802 useconds -= 1E6 * seconds;
803 }
804 } else if (useconds < 0.0)
805 croak("Time::HiRes::usleep(%"NVgf"): negative time not invented
yet", useconds);
806 usleep((U32)useconds);
807 } else
808 PerlProc_pause();
809 gettimeofday(&Tb, NULL);
810 #if 0
811 printf("[%ld %ld] [%ld %ld]\n", Tb.tv_sec, Tb.tv_usec, Ta.tv_sec,
Ta.tv_usec);
812 #endif
813 RETVAL = 1E6*(Tb.tv_sec-Ta.tv_sec)+(NV)((IV)Tb.tv_usec-(IV)Ta.tv_usec);
814
815 OUTPUT:
816 RETVAL
817
818 #if defined(TIME_HIRES_NANOSLEEP)
...it seems to me there is an off-by-one error in the check at line 795 for
systems that provide usleep(); the check should be for greater-or-equal than,
instead of greater-than.
The usleep(3) on the 6.0 BETA2 system does not support sleep-times of 1M us and
more, as per manual, and returns an error when called with 1M as argument.
Tested on a Linux system with Time::HiRes 1.9711 and an usleep(3) that accepts
arguments including and beyond 1M us (verified using C-program) showed the
desired behaviour for sleeping around 1 second when argument to
Time::HiRes::usleep is around 1M. I did not look at code of Time::HiRes 1.9711.
>How-To-Repeat:
execute from shell:
perl -MTime::HiRes -e 'print Time::HiRes::usleep( 1000000 ) . "\n"'
Call seems to return immediately, sleeping around 3 us (as per return-value).
Changing the argument to either 999999 or 1000001 correctly sleeps around 1
second.
>Fix:
Home |
Main Index |
Thread Index |
Old Index