Skip Menu |

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

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

People
Owner: Nobody in particular
Requestors: TONYC [...] cpan.org
Cc:
AdminCc:

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



Subject: Time::NVtime pointer mis-documented or mis-implemented
Time::HiRes documents the Time::NVtime as returning double, per: name C prototype --------------- ---------------------- Time::NVtime double (*)() Time::U2time void (*)(pTHX_ UV ret[2]) and the examples: double (*myNVtime)(); /* Returns -1 on failure. */ 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)()); but it is actually implemented as returning an NV, which on -Duselongdouble builds is a long double. On Linux x86_64, doubles are returned on the FPU stack, while long doubles are returned in memory, as with structures. Code that uses the documentation (eg. Time::Warp, Coro) ends up either underflowing the FPU stack or leaving trash on the FPU stack, which after multiple calls can result in an FPU stack overflow. This can be hard to track down. See https://rt.perl.org/Ticket/Display.html?id=123879 for an example of the failure. Either the documentation needs to be corrected to use the NV return value, or the implementation needs to use double. Either way, some CPAN modules will need fixes, Time::Warp and Coro use the double type, Event and (to my surprise) my POE::XS::Loop::Poll use the NV prototype. Thanks Tony
On Thu Apr 16 02:00:37 2015, TONYC wrote: Show quoted text
> Either the documentation needs to be corrected to use the NV return > value, or the implementation needs to use double.
Patch, also available at https://github.com/rjbs/Time-HiRes/pull/1 Tony
Subject: 0001-correct-documentation-of-Time-NVtime-to-match-the-im.patch
From 86dbc9501e4ce56827ea83470410afd2805c8aa5 Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Tue, 18 Aug 2015 10:05:12 +1000 Subject: [PATCH] correct documentation of Time::NVtime to match the implementation Time::HiRes has always used NV as the return value of the function pointer stored in Time::NVtime, which is fine when perl is built with default settings, since NV is then just double. However, if perl is built with -Duselongdouble, NV becomes long double, and code that follows the documentation exhibits hard to debug behaviour, eg. [perl #123879]. Some modules on CPAN that use this interface follow the documentation and some follow the implementation, changing the implementation would break modules that follow the implementation and break backward compatibility, so update the documentation. --- HiRes.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/HiRes.pm b/HiRes.pm index 6cc7c3b..1435473 100644 --- a/HiRes.pm +++ b/HiRes.pm @@ -510,7 +510,7 @@ modglobal hash: name C prototype --------------- ---------------------- - Time::NVtime double (*)() + Time::NVtime NV (*)() Time::U2time void (*)(pTHX_ UV ret[2]) Both functions return equivalent information (like C<gettimeofday>) @@ -521,12 +521,12 @@ VMS have emulations for it.) Here is an example of using C<NVtime> from C: - double (*myNVtime)(); /* Returns -1 on failure. */ + NV (*myNVtime)(); /* Returns -1 on failure. */ 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)()); + myNVtime = INT2PTR(NV(*)(), SvIV(*svp)); + printf("The current time is: %" NVff "\n", (*myNVtime)()); =head1 DIAGNOSTICS -- 1.7.10.4
Thanks, this has been applied. -- rjbs