Rework Time::HiRes not to need HAS_NANOSLEEP from Configure.
[p5sagit/p5-mst-13.2.git] / ext / Time / HiRes / HiRes.xs
index 5da54c6..91249f0 100644 (file)
@@ -36,13 +36,16 @@ typedef NVTYPE NV;
 #  ifdef IVSIZE
 #      if IVSIZE == LONGSIZE
 #           define     IVdf            "ld"
+#           define     UVuf            "lu"
 #       else
 #           if IVSIZE == INTSIZE
 #               define IVdf    "d"
+#               define UVuf    "u"
 #           endif
 #       endif
 #   else
 #       define IVdf    "ld"
+#       define UVuf    "lu"
 #   endif
 #endif
 
@@ -98,77 +101,14 @@ sv_2pv_nolen(pTHX_ register SV *sv)
 #   undef ITIMER_REALPROF
 #endif
 
-static IV
-constant(char *name, int arg)
-{
-    errno = 0;
-    switch (*name) {
-    case 'd':
-      if (strEQ(name, "d_getitimer"))
-#ifdef HAS_GETITIMER
-       return 1;
-#else
-       return 0;
-#endif
-      if (strEQ(name, "d_nanosleep"))
-#ifdef HAS_NANOSLEEP
-       return 1;
-#else
-       return 0;
-#endif
-      if (strEQ(name, "d_setitimer"))
-#ifdef HAS_SETITIMER
-       return 1;
-#else
-       return 0;
-#endif
-      if (strEQ(name, "d_ualarm"))
-#ifdef HAS_UALARM
-       return 1;
-#else
-       return 0;
-#endif
-      if (strEQ(name, "d_usleep"))
-#ifdef HAS_USLEEP
-       return 1;
-#else
-       return 0;
+/* 5.004 doesn't define PL_sv_undef */
+#ifndef ATLEASTFIVEOHOHFIVE
+#ifndef PL_sv_undef
+#define PL_sv_undef sv_undef
 #endif
-      break;
-    case 'I':
-      if (strEQ(name, "ITIMER_REAL"))
-#ifdef ITIMER_REAL
-       return ITIMER_REAL;
-#else
-       goto not_there;
-#endif
-      if (strEQ(name, "ITIMER_REALPROF"))
-#ifdef ITIMER_REALPROF
-       return ITIMER_REALPROF;
-#else
-       goto not_there;
 #endif
-      if (strEQ(name, "ITIMER_VIRTUAL"))
-#ifdef ITIMER_VIRTUAL
-       return ITIMER_VIRTUAL;
-#else
-       goto not_there;
-#endif
-      if (strEQ(name, "ITIMER_PROF"))
-#ifdef ITIMER_PROF
-       return ITIMER_PROF;
-#else
-       goto not_there;
-#endif
-      break;
-    }
-    errno = EINVAL;
-    return 0;
 
-not_there:
-    errno = ENOENT;
-    return 0;
-}
+#include "const-c.inc"
 
 #if !defined(HAS_GETTIMEOFDAY) && defined(WIN32)
 #define HAS_GETTIMEOFDAY
@@ -400,7 +340,10 @@ gettimeofday (struct timeval *tp, void *tpz)
 #endif
 
 
-#if !defined(HAS_USLEEP) && defined(HAS_NANOSLEEP)
+ /* Do not use H A S _ N A N O S L E E P
+  * so that Perl Configure doesn't scan for it.
+  * The TIME_HIRES_NANOSLEEP is set by Makefile.PL. */
+#if !defined(HAS_USLEEP) && defined(TIME_HIRES_NANOSLEEP)
 #define HAS_USLEEP
 #define usleep hrt_nanosleep  /* could conflict with ncurses for static build */
 
@@ -699,10 +642,7 @@ BOOT:
 #endif
 #endif
 
-IV
-constant(name, arg)
-       char *          name
-       int             arg
+INCLUDE: const-xs.inc
 
 #if defined(HAS_USLEEP) && defined(HAS_GETTIMEOFDAY)
 
@@ -749,6 +689,17 @@ sleep(...)
                 UV useconds = (UV)(1E6 * (seconds - (UV)seconds));
                 if (seconds >= 1.0)
                     sleep((U32)seconds);
+                if ((IV)useconds < 0) {
+#if defined(__sparc64__) && defined(__GNUC__)
+                  /* Sparc64 gcc 2.95.3 (e.g. on NetBSD) has a bug
+                   * where (0.5 - (UV)(0.5)) will under certain
+                   * circumstances (if the double is cast to UV more
+                   * than once?) evaluate to -0.5, instead of 0.5. */
+                  useconds = -(IV)useconds;
+#endif
+                  if ((IV)useconds < 0)
+                    croak("Time::HiRes::sleep(%"NVgf"): internal error: useconds < 0 (unsigned %"UVuf" signed %"IVdf")", seconds, useconds, (IV)useconds);
+                }
                 usleep(useconds);
            } else
                croak("Time::HiRes::sleep(%"NVgf"): negative time not invented yet", seconds);