Skip Menu |

This queue is for tickets about the Time-HiRes CPAN distribution.

Report information
The Basics
Id: 78266
Status: resolved
Priority: 0/
Queue: Time-HiRes

People
Owner: Nobody in particular
Requestors: m.ramakers [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.9721
Fixed in: (no value)



Subject: "usleep( 1000000 )" does not sleep on NetBSD (while 999999 and 1000001 do)
(copied more or less from NetBSD's issue 'pkg/46673' (http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=46673): ENVIRONMENT DETAILS: - uname -a: NetBSD main.LAN 6.0_BETA2 NetBSD 6.0_BETA2 (GENERIC) amd64 - perl version: This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-netbsd-thread-multi - module version: 1.972101 (1.9721p1 ?) TESTED ON: tested on NetBSD 6.0 BETA2 amd64 with Time::HiRes 1.972101, NetBSD 5.1 i386 with Time::HiRes 1.9719, and unknown NetBSD with Time::HiRes 1.9724; all expose this symptom. Tested on unknown Linux with Time::HiRes 1.9711, which passes (see 'ANALYSIS'). TO REPRODUCE: 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 ANALYSIS: (sorry; sources from HiRes 1.9724, since sources for 1.972101 were unavailable; I confirmed HiRes 1.9725 contains similar code-snippet. However, tested and failed on NetBSD + HiRes 1.9724 on another system - not mine - as listed in 'TESTED ON', above.) From Time::HiRes 1.9724 (same version as in NetBSD's 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.
Fixed in Time-HiRes-1.9726, now on CPAN.