Previous patch contained one mistake, here's an updated version:
diff --git a/HiRes.pm b/HiRes.pm
index b0bf2c840b..1548251459 100644
--- a/HiRes.pm
+++ b/HiRes.pm
@@ -95,13 +95,6 @@ XSLoader::load( 'Time::HiRes', $XS_VERSION );
# Preloaded methods go here.
-sub tv_interval {
- # probably could have been done in C
- my ($a, $b) = @_;
- $b = [gettimeofday()] unless defined($b);
- (${$b}[0] - ${$a}[0]) + ((${$b}[1] - ${$a}[1]) / 1_000_000);
-}
-
# Autoload methods go after =cut, and are processed by the autosplit program.
1;
diff --git a/HiRes.xs b/HiRes.xs
index b9eaa17cde..b9fa136592 100644
--- a/HiRes.xs
+++ b/HiRes.xs
@@ -1318,6 +1318,61 @@ time()
OUTPUT:
RETVAL
+NV
+tv_interval(SV* start, ...)
+ PREINIT:
+ struct timeval Tp;
+ struct timezone Tz;
+ SV* end;
+ UV end_sec;
+ IV end_usec;
+ SV** avalue;
+
+ CODE:
+
+ if (items >= 2) {
+ end = ST(1);
+ } else {
+ end = NULL;
+ }
+
+ if (!end || !SvROK(end)) {
+ int status;
+ status = gettimeofday (&Tp, &Tz);
+
+ if (status == 0) {
+ Tp.tv_sec += Tz.tz_minuteswest * 60; /* adjust for TZ */
+
+ end_sec = Tp.tv_sec;
+ end_usec = Tp.tv_usec;
+ } else {
+ end_sec = 0;
+ end_usec = 0;
+ }
+ } else {
+ end = SvRV(end);
+ if (SvTYPE(end) != SVt_PVAV) croak("Not an array reference in tv_interval()");
+
+ avalue = av_fetch((AV*)end, 0, FALSE);
+ end_sec = avalue ? SvIV(*avalue) : 0;
+
+ avalue = av_fetch((AV*)end, 1, FALSE);
+ end_usec = avalue ? SvIV(*avalue) : 0;
+ }
+
+ if (!SvROK(start)) croak("Not an array reference in tv_interval()");
+ start = SvRV(start);
+ if (SvTYPE(start) != SVt_PVAV) croak("Not an array reference in tv_interval()");
+
+ avalue = av_fetch((AV*)start, 0, FALSE);
+ RETVAL = end_sec - (avalue ? SvUV(*avalue) : 0);
+
+ avalue = av_fetch((AV*)start, 1, FALSE);
+ RETVAL += ((end_usec - (avalue ? SvIV(*avalue) : 0)) / NV_1E6);
+
+ OUTPUT:
+ RETVAL
+
# else /* MACOS_TRADITIONAL */
void
gettimeofday()
@@ -1352,6 +1407,58 @@ time()
OUTPUT:
RETVAL
+NV
+tv_interval(SV* start, ...)
+ PREINIT:
+ struct timeval Tp;
+ struct timezone Tz;
+ SV* end;
+ IV end_sec, end_usec;
+ SV** avalue;
+
+ CODE:
+
+ if (items >= 2) {
+ end = ST(1);
+ } else {
+ end = NULL;
+ }
+
+ if (!end || !SvROK(end)) {
+ int status;
+ status = gettimeofday (&Tp, &Tz);
+
+ if (status == 0) {
+ end_sec = Tp.tv_sec;
+ end_usec = Tp.tv_usec;
+ } else {
+ end_sec = 0;
+ end_usec = 0;
+ }
+ } else {
+ end = SvRV(end);
+ if (SvTYPE(end) != SVt_PVAV) croak("Not an array reference in tv_interval()");
+
+ avalue = av_fetch((AV*)end, 0, FALSE);
+ end_sec = avalue ? SvIV(*avalue) : 0;
+
+ avalue = av_fetch((AV*)end, 1, FALSE);
+ end_usec = avalue ? SvIV(*avalue) : 0;
+ }
+
+ if (!SvROK(start)) croak("Not an array reference in tv_interval()");
+ start = SvRV(start);
+ if (SvTYPE(start) != SVt_PVAV) croak("Not an array reference in tv_interval()");
+
+ avalue = av_fetch((AV*)start, 0, FALSE);
+ RETVAL = end_sec - (avalue ? SvIV(*avalue) : 0);
+
+ avalue = av_fetch((AV*)start, 1, FALSE);
+ RETVAL += ((end_usec - (avalue ? SvIV(*avalue) : 0)) / NV_1E6);
+
+ OUTPUT:
+ RETVAL
+
# endif /* MACOS_TRADITIONAL */
#endif /* #ifdef HAS_GETTIMEOFDAY */