     1			/*
     2			 * This file was generated automatically by ExtUtils::ParseXS version 2.10 from the
     3			 * contents of HiRes.xs. Do not edit this file, edit HiRes.xs instead.
     4			 *
     5			 *	ANY CHANGES MADE HERE WILL BE LOST! 
     6			 *
     7			 */
     8			
     9			#line 1 "HiRes.xs"
    10			/*
    11			 * 
    12			 * Copyright (c) 1996-2002 Douglas E. Wegscheid.  All rights reserved.
    13			 * 
    14			 * Copyright (c) 2002,2003,2004,2005 Jarkko Hietaniemi.  All rights reserved.
    15			 * 
    16			 * This program is free software; you can redistribute it and/or modify
    17			 * it under the same terms as Perl itself.
    18			 */
    19			
    20			#ifdef __cplusplus
    21			extern "C" {
    22			#endif
    23			#define PERL_NO_GET_CONTEXT
    24			#include "EXTERN.h"
    25			#include "perl.h"
    26			#include "XSUB.h"
    27			#include "ppport.h"
    28			#if defined(__CYGWIN__) && defined(HAS_W32API_WINDOWS_H)
    29			# include <w32api/windows.h>
    30			# define CYGWIN_WITH_W32API
    31			#endif
    32			#ifdef WIN32
    33			# include <time.h>
    34			#else
    35			# include <sys/time.h>
    36			#endif
    37			#ifdef HAS_SELECT
    38			# ifdef I_SYS_SELECT
    39			#  include <sys/select.h>
    40			# endif
    41			#endif
    42			#ifdef __cplusplus
    43			}
    44			#endif
    45			
    46			#ifndef PerlProc_pause
    47			#   define PerlProc_pause() Pause()
    48			#endif
    49			
    50			#ifdef HAS_PAUSE
    51			#   define Pause   pause
    52			#else
    53			#   undef Pause /* In case perl.h did it already. */
    54			#   define Pause() sleep(~0) /* Zzz for a long time. */
    55			#endif
    56			
    57			/* Though the cpp define ITIMER_VIRTUAL is available the functionality
    58			 * is not supported in Cygwin as of August 2004, ditto for Win32.
    59			 * Neither are ITIMER_PROF or ITIMER_REALPROF implemented.  --jhi
    60			 */
    61			#if defined(__CYGWIN__) || defined(WIN32)
    62			#   undef ITIMER_VIRTUAL
    63			#   undef ITIMER_PROF
    64			#   undef ITIMER_REALPROF
    65			#endif
    66			
    67			/* 5.004 doesn't define PL_sv_undef */
    68			#ifndef ATLEASTFIVEOHOHFIVE
    69			# ifndef PL_sv_undef
    70			#  define PL_sv_undef sv_undef
    71			# endif
    72			#endif
    73			
    74			#include "const-c.inc"
    75			
    76			#if defined(WIN32) || defined(CYGWIN_WITH_W32API)
    77			
    78			#ifndef HAS_GETTIMEOFDAY
    79			#   define HAS_GETTIMEOFDAY
    80			#endif
    81			
    82			/* shows up in winsock.h?
    83			struct timeval {
    84			 long tv_sec;
    85			 long tv_usec;
    86			}
    87			*/
    88			
    89			typedef union {
    90			    unsigned __int64	ft_i64;
    91			    FILETIME		ft_val;
    92			} FT_t;
    93			
    94			#define MY_CXT_KEY "Time::HiRes_" XS_VERSION
    95			
    96			typedef struct {
    97			    unsigned long run_count;
    98			    unsigned __int64 base_ticks;
    99			    unsigned __int64 tick_frequency;
   100			    FT_t base_systime_as_filetime;
   101			    unsigned __int64 reset_time;
   102			} my_cxt_t;
   103			
   104			START_MY_CXT
   105			
   106			/* Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 */
   107			#ifdef __GNUC__
   108			# define Const64(x) x##LL
   109			#else
   110			# define Const64(x) x##i64
   111			#endif
   112			#define EPOCH_BIAS  Const64(116444736000000000)
   113			
   114			/* NOTE: This does not compute the timezone info (doing so can be expensive,
   115			 * and appears to be unsupported even by glibc) */
   116			
   117			/* dMY_CXT needs a Perl context and we don't want to call PERL_GET_CONTEXT
   118			   for performance reasons */
   119			
   120			#undef gettimeofday
   121			#define gettimeofday(tp, not_used) _gettimeofday(aTHX_ tp, not_used)
   122			
   123			/* If the performance counter delta drifts more than 0.5 seconds from the
   124			 * system time then we recalibrate to the system time.  This means we may
   125			 * move *backwards* in time! */
   126			#define MAX_PERF_COUNTER_SKEW Const64(5000000) /* 0.5 seconds */
   127			
   128			/* Reset reading from the performance counter every five minutes.
   129			 * Many PC clocks just seem to be so bad. */
   130			#define MAX_PERF_COUNTER_TICKS Const64(300000000) /* 300 seconds */
   131			
   132			static int
   133			_gettimeofday(pTHX_ struct timeval *tp, void *not_used)
   134			{
   135			    dMY_CXT;
   136			
   137			    unsigned __int64 ticks;
   138			    FT_t ft;
   139			
   140			    if (MY_CXT.run_count++ == 0 ||
   141				MY_CXT.base_systime_as_filetime.ft_i64 > MY_CXT.reset_time) {
   142			        QueryPerformanceFrequency((LARGE_INTEGER*)&MY_CXT.tick_frequency);
   143			        QueryPerformanceCounter((LARGE_INTEGER*)&MY_CXT.base_ticks);
   144			        GetSystemTimeAsFileTime(&MY_CXT.base_systime_as_filetime.ft_val);
   145			        ft.ft_i64 = MY_CXT.base_systime_as_filetime.ft_i64;
   146				MY_CXT.reset_time = ft.ft_i64 + MAX_PERF_COUNTER_TICKS;
   147			    }
   148			    else {
   149				__int64 diff;
   150			        QueryPerformanceCounter((LARGE_INTEGER*)&ticks);
   151			        ticks -= MY_CXT.base_ticks;
   152			        ft.ft_i64 = MY_CXT.base_systime_as_filetime.ft_i64
   153			                    + Const64(10000000) * (ticks / MY_CXT.tick_frequency)
   154			                    +(Const64(10000000) * (ticks % MY_CXT.tick_frequency)) / MY_CXT.tick_frequency;
   155				diff = ft.ft_i64 - MY_CXT.base_systime_as_filetime.ft_i64;
   156				if (diff < -MAX_PERF_COUNTER_SKEW || diff > MAX_PERF_COUNTER_SKEW) {
   157				    MY_CXT.base_ticks += ticks;
   158			            GetSystemTimeAsFileTime(&MY_CXT.base_systime_as_filetime.ft_val);
   159			            ft.ft_i64 = MY_CXT.base_systime_as_filetime.ft_i64;
   160				}
   161			    }
   162			
   163			    /* seconds since epoch */
   164			    tp->tv_sec = (long)((ft.ft_i64 - EPOCH_BIAS) / Const64(10000000));
   165			
   166			    /* microseconds remaining */
   167			    tp->tv_usec = (long)((ft.ft_i64 / Const64(10)) % Const64(1000000));
   168			
   169			    return 0;
   170			}
   171			#endif
   172			
   173			#if defined(WIN32) && !defined(ATLEASTFIVEOHOHFIVE)
   174			static unsigned int
   175			sleep(unsigned int t)
   176			{
   177			    Sleep(t*1000);
   178			    return 0;
   179			}
   180			#endif
   181			
   182			#if !defined(HAS_GETTIMEOFDAY) && defined(VMS)
   183			#define HAS_GETTIMEOFDAY
   184			
   185			#include <lnmdef.h>
   186			#include <time.h> /* gettimeofday */
   187			#include <stdlib.h> /* qdiv */
   188			#include <starlet.h> /* sys$gettim */
   189			#include <descrip.h>
   190			#ifdef __VAX
   191			#include <lib$routines.h> /* lib$ediv() */
   192			#endif
   193			
   194			/*
   195			        VMS binary time is expressed in 100 nano-seconds since
   196			        system base time which is 17-NOV-1858 00:00:00.00
   197			*/
   198			
   199			#define DIV_100NS_TO_SECS  10000000L
   200			#define DIV_100NS_TO_USECS 10L
   201			
   202			/* 
   203			        gettimeofday is supposed to return times since the epoch
   204			        so need to determine this in terms of VMS base time
   205			*/
   206			static $DESCRIPTOR(dscepoch,"01-JAN-1970 00:00:00.00");
   207			
   208			#ifdef __VAX
   209			static long base_adjust[2]={0L,0L};
   210			#else
   211			static __int64 base_adjust=0;
   212			#endif
   213			
   214			/* 
   215			
   216			   If we don't have gettimeofday, then likely we are on a VMS machine that
   217			   operates on local time rather than UTC...so we have to zone-adjust.
   218			   This code gleefully swiped from VMS.C 
   219			
   220			*/
   221			/* method used to handle UTC conversions:
   222			 *   1 == CRTL gmtime();  2 == SYS$TIMEZONE_DIFFERENTIAL;  3 == no correction
   223			 */
   224			static int gmtime_emulation_type;
   225			/* number of secs to add to UTC POSIX-style time to get local time */
   226			static long int utc_offset_secs;
   227			static struct dsc$descriptor_s fildevdsc = 
   228			  { 12, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$FILE_DEV" };
   229			static struct dsc$descriptor_s *fildev[] = { &fildevdsc, NULL };
   230			
   231			static time_t toutc_dst(time_t loc) {
   232			  struct tm *rsltmp;
   233			
   234			  if ((rsltmp = localtime(&loc)) == NULL) return -1;
   235			  loc -= utc_offset_secs;
   236			  if (rsltmp->tm_isdst) loc -= 3600;
   237			  return loc;
   238			}
   239			
   240			static time_t toloc_dst(time_t utc) {
   241			  struct tm *rsltmp;
   242			
   243			  utc += utc_offset_secs;
   244			  if ((rsltmp = localtime(&utc)) == NULL) return -1;
   245			  if (rsltmp->tm_isdst) utc += 3600;
   246			  return utc;
   247			}
   248			
   249			#define _toutc(secs)  ((secs) == (time_t) -1 ? (time_t) -1 : \
   250			       ((gmtime_emulation_type || timezone_setup()), \
   251			       (gmtime_emulation_type == 1 ? toutc_dst(secs) : \
   252			       ((secs) - utc_offset_secs))))
   253			
   254			#define _toloc(secs)  ((secs) == (time_t) -1 ? (time_t) -1 : \
   255			       ((gmtime_emulation_type || timezone_setup()), \
   256			       (gmtime_emulation_type == 1 ? toloc_dst(secs) : \
   257			       ((secs) + utc_offset_secs))))
   258			
   259			static int
   260			timezone_setup(void) 
   261			{
   262			  struct tm *tm_p;
   263			
   264			  if (gmtime_emulation_type == 0) {
   265			    int dstnow;
   266			    time_t base = 15 * 86400; /* 15jan71; to avoid month/year ends between    */
   267			                              /* results of calls to gmtime() and localtime() */
   268			                              /* for same &base */
   269			
   270			    gmtime_emulation_type++;
   271			    if ((tm_p = gmtime(&base)) == NULL) { /* CRTL gmtime() is a fake */
   272			      char off[LNM$C_NAMLENGTH+1];;
   273			
   274			      gmtime_emulation_type++;
   275			      if (!Perl_vmstrnenv("SYS$TIMEZONE_DIFFERENTIAL",off,0,fildev,0)) {
   276			        gmtime_emulation_type++;
   277			        utc_offset_secs = 0;
   278			        Perl_warn(aTHX_ "no UTC offset information; assuming local time is UTC");
   279			      }
   280			      else { utc_offset_secs = atol(off); }
   281			    }
   282			    else { /* We've got a working gmtime() */
   283			      struct tm gmt, local;
   284			
   285			      gmt = *tm_p;
   286			      tm_p = localtime(&base);
   287			      local = *tm_p;
   288			      utc_offset_secs  = (local.tm_mday - gmt.tm_mday) * 86400;
   289			      utc_offset_secs += (local.tm_hour - gmt.tm_hour) * 3600;
   290			      utc_offset_secs += (local.tm_min  - gmt.tm_min)  * 60;
   291			      utc_offset_secs += (local.tm_sec  - gmt.tm_sec);
   292			    }
   293			  }
   294			  return 1;
   295			}
   296			
   297			
   298			int
   299			gettimeofday (struct timeval *tp, void *tpz)
   300			{
   301			 long ret;
   302			#ifdef __VAX
   303			 long quad[2];
   304			 long quad1[2];
   305			 long div_100ns_to_secs;
   306			 long div_100ns_to_usecs;
   307			 long quo,rem;
   308			 long quo1,rem1;
   309			#else
   310			 __int64 quad;
   311			 __qdiv_t ans1,ans2;
   312			#endif
   313			/*
   314			        In case of error, tv_usec = 0 and tv_sec = VMS condition code.
   315			        The return from function is also set to -1.
   316			        This is not exactly as per the manual page.
   317			*/
   318			
   319			 tp->tv_usec = 0;
   320			
   321			#ifdef __VAX
   322			 if (base_adjust[0]==0 && base_adjust[1]==0) {
   323			#else
   324			 if (base_adjust==0) { /* Need to determine epoch adjustment */
   325			#endif
   326			        ret=sys$bintim(&dscepoch,&base_adjust);
   327			        if (1 != (ret &&1)) {
   328			                tp->tv_sec = ret;
   329			                return -1;
   330			        }
   331			 }
   332			
   333			 ret=sys$gettim(&quad); /* Get VMS system time */
   334			 if ((1 && ret) == 1) {
   335			#ifdef __VAX
   336			        quad[0] -= base_adjust[0]; /* convert to epoch offset */
   337			        quad[1] -= base_adjust[1]; /* convert 2nd half of quadword */
   338			        div_100ns_to_secs = DIV_100NS_TO_SECS;
   339			        div_100ns_to_usecs = DIV_100NS_TO_USECS;
   340			        lib$ediv(&div_100ns_to_secs,&quad,&quo,&rem);
   341			        quad1[0] = rem;
   342			        quad1[1] = 0L;
   343			        lib$ediv(&div_100ns_to_usecs,&quad1,&quo1,&rem1);
   344			        tp->tv_sec = quo; /* Whole seconds */
   345			        tp->tv_usec = quo1; /* Micro-seconds */
   346			#else
   347			        quad -= base_adjust; /* convert to epoch offset */
   348			        ans1=qdiv(quad,DIV_100NS_TO_SECS);
   349			        ans2=qdiv(ans1.rem,DIV_100NS_TO_USECS);
   350			        tp->tv_sec = ans1.quot; /* Whole seconds */
   351			        tp->tv_usec = ans2.quot; /* Micro-seconds */
   352			#endif
   353			 } else {
   354			        tp->tv_sec = ret;
   355			        return -1;
   356			 }
   357			# ifdef VMSISH_TIME
   358			# ifdef RTL_USES_UTC
   359			  if (VMSISH_TIME) tp->tv_sec = _toloc(tp->tv_sec);
   360			# else
   361			  if (!VMSISH_TIME) tp->tv_sec = _toutc(tp->tv_sec);
   362			# endif
   363			# endif
   364			 return 0;
   365			}
   366			#endif
   367			
   368			
   369			 /* Do not use H A S _ N A N O S L E E P
   370			  * so that Perl Configure doesn't scan for it.
   371			  * The TIME_HIRES_NANOSLEEP is set by Makefile.PL. */
   372			#if !defined(HAS_USLEEP) && defined(TIME_HIRES_NANOSLEEP)
   373			#define HAS_USLEEP
   374			#define usleep hrt_unanosleep  /* could conflict with ncurses for static build */
   375			
   376			void
   377			hrt_unanosleep(unsigned long usec) /* This is used to emulate usleep. */
   378			{
   379			    struct timespec res;
   380			    res.tv_sec = usec/1000/1000;
   381			    res.tv_nsec = ( usec - res.tv_sec*1000*1000 ) * 1000;
   382			    nanosleep(&res, NULL);
   383			}
   384			
   385			#endif /* #if !defined(HAS_USLEEP) && defined(TIME_HIRES_NANOSLEEP) */
   386			
   387			#if !defined(HAS_USLEEP) && defined(HAS_SELECT)
   388			#ifndef SELECT_IS_BROKEN
   389			#define HAS_USLEEP
   390			#define usleep hrt_usleep  /* could conflict with ncurses for static build */
   391			
   392			void
   393			hrt_usleep(unsigned long usec)
   394			{
   395			    struct timeval tv;
   396			    tv.tv_sec = 0;
   397			    tv.tv_usec = usec;
   398			    select(0, (Select_fd_set_t)NULL, (Select_fd_set_t)NULL,
   399					(Select_fd_set_t)NULL, &tv);
   400			}
   401			#endif
   402			#endif /* #if !defined(HAS_USLEEP) && defined(HAS_SELECT) */
   403			
   404			#if !defined(HAS_USLEEP) && defined(WIN32)
   405			#define HAS_USLEEP
   406			#define usleep hrt_usleep  /* could conflict with ncurses for static build */
   407			
   408			void
   409			hrt_usleep(unsigned long usec)
   410			{
   411			    long msec;
   412			    msec = usec / 1000;
   413			    Sleep (msec);
   414			}
   415			#endif /* #if !defined(HAS_USLEEP) && defined(WIN32) */
   416			
   417			
   418			#if !defined(HAS_UALARM) && defined(HAS_SETITIMER)
   419			#define HAS_UALARM
   420			#define ualarm hrt_ualarm  /* could conflict with ncurses for static build */
   421			
   422			int
   423			hrt_ualarm(int usec, int interval)
   424			{
   425			   struct itimerval itv;
   426			   itv.it_value.tv_sec = usec / 1000000;
   427			   itv.it_value.tv_usec = usec % 1000000;
   428			   itv.it_interval.tv_sec = interval / 1000000;
   429			   itv.it_interval.tv_usec = interval % 1000000;
   430			   return setitimer(ITIMER_REAL, &itv, 0);
   431			}
   432			#endif /* #if !defined(HAS_UALARM) && defined(HAS_SETITIMER) */
   433			
   434			#if !defined(HAS_UALARM) && defined(VMS)
   435			#define HAS_UALARM
   436			#define ualarm vms_ualarm 
   437			
   438			#include <lib$routines.h>
   439			#include <ssdef.h>
   440			#include <starlet.h>
   441			#include <descrip.h>
   442			#include <signal.h>
   443			#include <jpidef.h>
   444			#include <psldef.h>
   445			
   446			#define VMSERR(s)   (!((s)&1))
   447			
   448			static void
   449			us_to_VMS(useconds_t mseconds, unsigned long v[])
   450			{
   451			    int iss;
   452			    unsigned long qq[2];
   453			
   454			    qq[0] = mseconds;
   455			    qq[1] = 0;
   456			    v[0] = v[1] = 0;
   457			
   458			    iss = lib$addx(qq,qq,qq);
   459			    if (VMSERR(iss)) lib$signal(iss);
   460			    iss = lib$subx(v,qq,v);
   461			    if (VMSERR(iss)) lib$signal(iss);
   462			    iss = lib$addx(qq,qq,qq);
   463			    if (VMSERR(iss)) lib$signal(iss);
   464			    iss = lib$subx(v,qq,v);
   465			    if (VMSERR(iss)) lib$signal(iss);
   466			    iss = lib$subx(v,qq,v);
   467			    if (VMSERR(iss)) lib$signal(iss);
   468			}
   469			
   470			static int
   471			VMS_to_us(unsigned long v[])
   472			{
   473			    int iss;
   474			    unsigned long div=10,quot, rem;
   475			
   476			    iss = lib$ediv(&div,v,&quot,&rem);
   477			    if (VMSERR(iss)) lib$signal(iss);
   478			
   479			    return quot;
   480			}
   481			
   482			typedef unsigned short word;
   483			typedef struct _ualarm {
   484			    int function;
   485			    int repeat;
   486			    unsigned long delay[2];
   487			    unsigned long interval[2];
   488			    unsigned long remain[2];
   489			} Alarm;
   490			
   491			
   492			static int alarm_ef;
   493			static Alarm *a0, alarm_base;
   494			#define UAL_NULL   0
   495			#define UAL_SET    1
   496			#define UAL_CLEAR  2
   497			#define UAL_ACTIVE 4
   498			static void ualarm_AST(Alarm *a);
   499			
   500			static int 
   501			vms_ualarm(int mseconds, int interval)
   502			{
   503			    Alarm *a, abase;
   504			    struct item_list3 {
   505			        word length;
   506			        word code;
   507			        void *bufaddr;
   508			        void *retlenaddr;
   509			    } ;
   510			    static struct item_list3 itmlst[2];
   511			    static int first = 1;
   512			    unsigned long asten;
   513			    int iss, enabled;
   514			
   515			    if (first) {
   516			        first = 0;
   517			        itmlst[0].code       = JPI$_ASTEN;
   518			        itmlst[0].length     = sizeof(asten);
   519			        itmlst[0].retlenaddr = NULL;
   520			        itmlst[1].code       = 0;
   521			        itmlst[1].length     = 0;
   522			        itmlst[1].bufaddr    = NULL;
   523			        itmlst[1].retlenaddr = NULL;
   524			
   525			        iss = lib$get_ef(&alarm_ef);
   526			        if (VMSERR(iss)) lib$signal(iss);
   527			
   528			        a0 = &alarm_base;
   529			        a0->function = UAL_NULL;
   530			    }
   531			    itmlst[0].bufaddr    = &asten;
   532			    
   533			    iss = sys$getjpiw(0,0,0,itmlst,0,0,0);
   534			    if (VMSERR(iss)) lib$signal(iss);
   535			    if (!(asten&0x08)) return -1;
   536			
   537			    a = &abase;
   538			    if (mseconds) {
   539			        a->function = UAL_SET;
   540			    } else {
   541			        a->function = UAL_CLEAR;
   542			    }
   543			
   544			    us_to_VMS(mseconds, a->delay);
   545			    if (interval) {
   546			        us_to_VMS(interval, a->interval);
   547			        a->repeat = 1;
   548			    } else 
   549			        a->repeat = 0;
   550			
   551			    iss = sys$clref(alarm_ef);
   552			    if (VMSERR(iss)) lib$signal(iss);
   553			
   554			    iss = sys$dclast(ualarm_AST,a,0);
   555			    if (VMSERR(iss)) lib$signal(iss);
   556			
   557			    iss = sys$waitfr(alarm_ef);
   558			    if (VMSERR(iss)) lib$signal(iss);
   559			
   560			    if (a->function == UAL_ACTIVE) 
   561			        return VMS_to_us(a->remain);
   562			    else
   563			        return 0;
   564			}
   565			
   566			
   567			
   568			static void
   569			ualarm_AST(Alarm *a)
   570			{
   571			    int iss;
   572			    unsigned long now[2];
   573			
   574			    iss = sys$gettim(now);
   575			    if (VMSERR(iss)) lib$signal(iss);
   576			
   577			    if (a->function == UAL_SET || a->function == UAL_CLEAR) {
   578			        if (a0->function == UAL_ACTIVE) {
   579			            iss = sys$cantim(a0,PSL$C_USER);
   580			            if (VMSERR(iss)) lib$signal(iss);
   581			
   582			            iss = lib$subx(a0->remain, now, a->remain);
   583			            if (VMSERR(iss)) lib$signal(iss);
   584			
   585			            if (a->remain[1] & 0x80000000) 
   586			                a->remain[0] = a->remain[1] = 0;
   587			        }
   588			
   589			        if (a->function == UAL_SET) {
   590			            a->function = a0->function;
   591			            a0->function = UAL_ACTIVE;
   592			            a0->repeat = a->repeat;
   593			            if (a0->repeat) {
   594			                a0->interval[0] = a->interval[0];
   595			                a0->interval[1] = a->interval[1];
   596			            }
   597			            a0->delay[0] = a->delay[0];
   598			            a0->delay[1] = a->delay[1];
   599			
   600			            iss = lib$subx(now, a0->delay, a0->remain);
   601			            if (VMSERR(iss)) lib$signal(iss);
   602			
   603			            iss = sys$setimr(0,a0->delay,ualarm_AST,a0);
   604			            if (VMSERR(iss)) lib$signal(iss);
   605			        } else {
   606			            a->function = a0->function;
   607			            a0->function = UAL_NULL;
   608			        }
   609			        iss = sys$setef(alarm_ef);
   610			        if (VMSERR(iss)) lib$signal(iss);
   611			    } else if (a->function == UAL_ACTIVE) {
   612			        if (a->repeat) {
   613			            iss = lib$subx(now, a->interval, a->remain);
   614			            if (VMSERR(iss)) lib$signal(iss);
   615			
   616			            iss = sys$setimr(0,a->interval,ualarm_AST,a);
   617			            if (VMSERR(iss)) lib$signal(iss);
   618			        } else {
   619			            a->function = UAL_NULL;
   620			        }
   621			        iss = sys$wake(0,0);
   622			        if (VMSERR(iss)) lib$signal(iss);
   623			        lib$signal(SS$_ASTFLT);
   624			    } else {
   625			        lib$signal(SS$_BADPARAM);
   626			    }
   627			}
   628			
   629			#endif /* #if !defined(HAS_UALARM) && defined(VMS) */
   630			
   631			#ifdef HAS_GETTIMEOFDAY
   632			
   633			static int
   634			myU2time(pTHX_ UV *ret)
   635			{
   636			  struct timeval Tp;
   637			  int status;
   638			  status = gettimeofday (&Tp, NULL);
   639			  ret[0] = Tp.tv_sec;
   640			  ret[1] = Tp.tv_usec;
   641			  return status;
   642			}
   643			
   644			static NV
   645			myNVtime()
   646			{
   647			#ifdef WIN32
   648			  dTHX;
   649			#endif
   650			  struct timeval Tp;
   651			  int status;
   652			  status = gettimeofday (&Tp, NULL);
   653			  return status == 0 ? Tp.tv_sec + (Tp.tv_usec / 1000000.) : -1.0;
   654			}
   655			
   656			#endif /* #ifdef HAS_GETTIMEOFDAY */
   657			
   658			#ifndef PERL_UNUSED_VAR
   659			#  define PERL_UNUSED_VAR(var) if (0) var = var
   660			#endif
   661			
   662			#line 663 "HiRes.c"
   663			#if defined(USE_ITHREADS) && defined(MY_CXT_KEY)
   664			#define XSubPPtmpAAAA 1
   665			
   666			
   667			XS(XS_Time__HiRes_CLONE); /* prototype to pass -Wmissing-prototypes */
   668			XS(XS_Time__HiRes_CLONE)
   669			{
   670			    dXSARGS;
   671			    PERL_UNUSED_VAR(cv); /* -W */
   672			    {
   673			#line 675 "HiRes.xs"
   674			    MY_CXT_CLONE;
   675			#line 676 "HiRes.c"
   676			    }
   677			    XSRETURN_EMPTY;
   678			}
   679			
   680			#endif
   681			
   682			/* INCLUDE:  Including 'const-xs.inc' from 'HiRes.xs' */
   683			
   684			
   685			XS(XS_Time__HiRes_constant); /* prototype to pass -Wmissing-prototypes */
   686			XS(XS_Time__HiRes_constant)
   687	           1    {
   688	           1        dXSARGS;
   689	           1        if (items != 1)
   690	      ######    	Perl_croak(aTHX_ "Usage: Time::HiRes::constant(sv)");
   691	           1        PERL_UNUSED_VAR(cv); /* -W */
   692	           1        PERL_UNUSED_VAR(ax); /* -Wall */
   693	           1        SP -= items;
   694			    {
   695			#line 4 "HiRes.xs"
   696			#ifdef dXSTARG
   697				dXSTARG; /* Faster if we have it.  */
   698			#else
   699				dTARGET;
   700			#endif
   701				STRLEN		len;
   702			        int		type;
   703				IV		iv;
   704				/* NV		nv;	Uncomment this if you need to return NVs */
   705				/* const char	*pv;	Uncomment this if you need to return PVs */
   706			#line 707 "HiRes.c"
   707	           1    	SV *	sv = ST(0);
   708	           1    	const char *	s = SvPV(sv, len);
   709			#line 18 "HiRes.xs"
   710			        /* Change this to constant(aTHX_ s, len, &iv, &nv);
   711			           if you need to return both NVs and IVs */
   712				type = constant(aTHX_ s, len, &iv);
   713			      /* Return 1 or 2 items. First is error message, or undef if no error.
   714			           Second, if present, is found value */
   715			        switch (type) {
   716			        case PERL_constant_NOTFOUND:
   717			          sv = sv_2mortal(newSVpvf("%s is not a valid Time::HiRes macro", s));
   718			          PUSHs(sv);
   719			          break;
   720			        case PERL_constant_NOTDEF:
   721			          sv = sv_2mortal(newSVpvf(
   722				    "Your vendor has not defined Time::HiRes macro %s, used", s));
   723			          PUSHs(sv);
   724			          break;
   725			        case PERL_constant_ISIV:
   726			          EXTEND(SP, 1);
   727			          PUSHs(&PL_sv_undef);
   728			          PUSHi(iv);
   729			          break;
   730				/* Uncomment this if you need to return NOs
   731			        case PERL_constant_ISNO:
   732			          EXTEND(SP, 1);
   733			          PUSHs(&PL_sv_undef);
   734			          PUSHs(&PL_sv_no);
   735			          break; */
   736				/* Uncomment this if you need to return NVs
   737			        case PERL_constant_ISNV:
   738			          EXTEND(SP, 1);
   739			          PUSHs(&PL_sv_undef);
   740			          PUSHn(nv);
   741			          break; */
   742				/* Uncomment this if you need to return PVs
   743			        case PERL_constant_ISPV:
   744			          EXTEND(SP, 1);
   745			          PUSHs(&PL_sv_undef);
   746			          PUSHp(pv, strlen(pv));
   747			          break; */
   748				/* Uncomment this if you need to return PVNs
   749			        case PERL_constant_ISPVN:
   750			          EXTEND(SP, 1);
   751			          PUSHs(&PL_sv_undef);
   752			          PUSHp(pv, iv);
   753			          break; */
   754				/* Uncomment this if you need to return SVs
   755			        case PERL_constant_ISSV:
   756			          EXTEND(SP, 1);
   757			          PUSHs(&PL_sv_undef);
   758			          PUSHs(sv);
   759			          break; */
   760				/* Uncomment this if you need to return UNDEFs
   761			        case PERL_constant_ISUNDEF:
   762			          break; */
   763				/* Uncomment this if you need to return UVs
   764			        case PERL_constant_ISUV:
   765			          EXTEND(SP, 1);
   766			          PUSHs(&PL_sv_undef);
   767			          PUSHu((UV)iv);
   768			          break; */
   769				/* Uncomment this if you need to return YESs
   770			        case PERL_constant_ISYES:
   771			          EXTEND(SP, 1);
   772			          PUSHs(&PL_sv_undef);
   773			          PUSHs(&PL_sv_yes);
   774			          break; */
   775			        default:
   776			          sv = sv_2mortal(newSVpvf(
   777				    "Unexpected return type %d while processing Time::HiRes macro %s, used",
   778			               type, s));
   779			          PUSHs(sv);
   780			        }
   781			#line 782 "HiRes.c"
   782	           1    	PUTBACK;
   783				return;
   784			    }
   785			}
   786			
   787			
   788			/* INCLUDE: Returning to 'HiRes.xs' from 'const-xs.inc' */
   789			
   790			#if defined(HAS_USLEEP) && defined(HAS_GETTIMEOFDAY)
   791			#define XSubPPtmpAAAB 1
   792			
   793			
   794			XS(XS_Time__HiRes_usleep); /* prototype to pass -Wmissing-prototypes */
   795			XS(XS_Time__HiRes_usleep)
   796	           5    {
   797	           5        dXSARGS;
   798	           5        if (items != 1)
   799	      ######    	Perl_croak(aTHX_ "Usage: Time::HiRes::usleep(useconds)");
   800	           5        PERL_UNUSED_VAR(cv); /* -W */
   801			    {
   802	           5    	NV	useconds = (NV)SvNV(ST(0));
   803			#line 687 "HiRes.xs"
   804				struct timeval Ta, Tb;
   805			#line 806 "HiRes.c"
   806	           5    	NV	RETVAL;
   807	           5    	dXSTARG;
   808			#line 689 "HiRes.xs"
   809				gettimeofday(&Ta, NULL);
   810				if (items > 0) {
   811				    if (useconds > 1E6) {
   812					IV seconds = (IV) (useconds / 1E6);
   813					/* If usleep() has been implemented using setitimer()
   814					 * then this contortion is unnecessary-- but usleep()
   815					 * may be implemented in some other way, so let's contort. */
   816					if (seconds) {
   817					    sleep(seconds);
   818					    useconds -= 1E6 * seconds;
   819					}
   820				    } else if (useconds < 0.0)
   821				        croak("Time::HiRes::usleep(%"NVgf"): negative time not invented yet", useconds);
   822				    usleep((U32)useconds);
   823				} else
   824				    PerlProc_pause();
   825				gettimeofday(&Tb, NULL);
   826			#if 0
   827				printf("[%ld %ld] [%ld %ld]\n", Tb.tv_sec, Tb.tv_usec, Ta.tv_sec, Ta.tv_usec);
   828			#endif
   829				RETVAL = 1E6*(Tb.tv_sec-Ta.tv_sec)+(NV)((IV)Tb.tv_usec-(IV)Ta.tv_usec);
   830			
   831			#line 832 "HiRes.c"
   832	           4    	XSprePUSH; PUSHn((NV)RETVAL);
   833			    }
   834	           4        XSRETURN(1);
   835			}
   836			
   837			#if defined(TIME_HIRES_NANOSLEEP)
   838			#define XSubPPtmpAAAC 1
   839			
   840			
   841			XS(XS_Time__HiRes_nanosleep); /* prototype to pass -Wmissing-prototypes */
   842			XS(XS_Time__HiRes_nanosleep)
   843	           4    {
   844	           4        dXSARGS;
   845	           4        if (items != 1)
   846	      ######    	Perl_croak(aTHX_ "Usage: Time::HiRes::nanosleep(nseconds)");
   847	           4        PERL_UNUSED_VAR(cv); /* -W */
   848			    {
   849	           4    	NV	nseconds = (NV)SvNV(ST(0));
   850			#line 720 "HiRes.xs"
   851				struct timeval Ta, Tb;
   852			#line 853 "HiRes.c"
   853	           4    	NV	RETVAL;
   854	           4    	dXSTARG;
   855			#line 722 "HiRes.xs"
   856				gettimeofday(&Ta, NULL);
   857				if (items > 0) {
   858				    struct timespec tsa;
   859				    if (nseconds > 1E9) {
   860					IV seconds = (IV) (nseconds / 1E9);
   861					if (seconds) {
   862					    sleep(seconds);
   863					    nseconds -= 1E9 * seconds;
   864					}
   865				    } else if (nseconds < 0.0)
   866				        croak("Time::HiRes::nanosleep(%"NVgf"): negative time not invented yet", nseconds);
   867				    tsa.tv_sec  = (IV) (nseconds / 1E9);
   868				    tsa.tv_nsec = (IV) nseconds - tsa.tv_sec * 1E9;
   869				    nanosleep(&tsa, NULL);
   870				} else
   871				    PerlProc_pause();
   872				gettimeofday(&Tb, NULL);
   873				RETVAL = 1E3*(1E6*(Tb.tv_sec-Ta.tv_sec)+(NV)((IV)Tb.tv_usec-(IV)Ta.tv_usec));
   874			
   875			#line 876 "HiRes.c"
   876	           3    	XSprePUSH; PUSHn((NV)RETVAL);
   877			    }
   878	           3        XSRETURN(1);
   879			}
   880			
   881			#endif /* #if defined(TIME_HIRES_NANOSLEEP) */
   882			
   883			XS(XS_Time__HiRes_sleep); /* prototype to pass -Wmissing-prototypes */
   884			XS(XS_Time__HiRes_sleep)
   885	           4    {
   886	           4        dXSARGS;
   887	           4        PERL_UNUSED_VAR(cv); /* -W */
   888			    {
   889			#line 749 "HiRes.xs"
   890				struct timeval Ta, Tb;
   891			#line 892 "HiRes.c"
   892	           4    	NV	RETVAL;
   893	           4    	dXSTARG;
   894			#line 751 "HiRes.xs"
   895				gettimeofday(&Ta, NULL);
   896				if (items > 0) {
   897				    NV seconds  = SvNV(ST(0));
   898				    if (seconds >= 0.0) {
   899				         UV useconds = (UV)(1E6 * (seconds - (UV)seconds));
   900					 if (seconds >= 1.0)
   901					     sleep((U32)seconds);
   902					 if ((IV)useconds < 0) {
   903			#if defined(__sparc64__) && defined(__GNUC__)
   904					   /* Sparc64 gcc 2.95.3 (e.g. on NetBSD) has a bug
   905					    * where (0.5 - (UV)(0.5)) will under certain
   906					    * circumstances (if the double is cast to UV more
   907					    * than once?) evaluate to -0.5, instead of 0.5. */
   908					   useconds = -(IV)useconds;
   909			#endif /* #if defined(__sparc64__) && defined(__GNUC__) */
   910					   if ((IV)useconds < 0)
   911					     croak("Time::HiRes::sleep(%"NVgf"): internal error: useconds < 0 (unsigned %"UVuf" signed %"IVdf")", seconds, useconds, (IV)useconds);
   912					 }
   913					 usleep(useconds);
   914				    } else
   915				        croak("Time::HiRes::sleep(%"NVgf"): negative time not invented yet", seconds);
   916				} else
   917				    PerlProc_pause();
   918				gettimeofday(&Tb, NULL);
   919			#if 0
   920				printf("[%ld %ld] [%ld %ld]\n", Tb.tv_sec, Tb.tv_usec, Ta.tv_sec, Ta.tv_usec);
   921			#endif
   922				RETVAL = (NV)(Tb.tv_sec-Ta.tv_sec)+0.000001*(NV)(Tb.tv_usec-Ta.tv_usec);
   923			
   924			#line 925 "HiRes.c"
   925	           3    	XSprePUSH; PUSHn((NV)RETVAL);
   926			    }
   927	           3        XSRETURN(1);
   928			}
   929			
   930			#endif /* #if defined(HAS_USLEEP) && defined(HAS_GETTIMEOFDAY) */
   931			#ifdef HAS_UALARM
   932			#define XSubPPtmpAAAD 1
   933			
   934			
   935			XS(XS_Time__HiRes_ualarm); /* prototype to pass -Wmissing-prototypes */
   936			XS(XS_Time__HiRes_ualarm)
   937	           5    {
   938	           5        dXSARGS;
   939	           5        if (items < 1 || items > 2)
   940	      ######    	Perl_croak(aTHX_ "Usage: Time::HiRes::ualarm(useconds, interval=0)");
   941	           5        PERL_UNUSED_VAR(cv); /* -W */
   942			    {
   943	           5    	int	useconds = (int)SvIV(ST(0));
   944	           5    	int	interval;
   945	           5    	int	RETVAL;
   946	           5    	dXSTARG;
   947			
   948	           5    	if (items < 2)
   949	           4    	    interval = 0;
   950				else {
   951	           1    	    interval = (int)SvIV(ST(1));
   952				}
   953			#line 792 "HiRes.xs"
   954				if (useconds < 0 || interval < 0)
   955				    croak("Time::HiRes::ualarm(%d, %d): negative time not invented yet", useconds, interval);
   956				RETVAL = ualarm(useconds, interval);
   957			
   958			#line 959 "HiRes.c"
   959	           4    	XSprePUSH; PUSHi((IV)RETVAL);
   960			    }
   961	           4        XSRETURN(1);
   962			}
   963			
   964			
   965			XS(XS_Time__HiRes_alarm); /* prototype to pass -Wmissing-prototypes */
   966			XS(XS_Time__HiRes_alarm)
   967	           3    {
   968	           3        dXSARGS;
   969	           3        if (items < 1 || items > 2)
   970	      ######    	Perl_croak(aTHX_ "Usage: Time::HiRes::alarm(seconds, interval=0)");
   971	           3        PERL_UNUSED_VAR(cv); /* -W */
   972			    {
   973	           3    	NV	seconds = (NV)SvNV(ST(0));
   974	           3    	NV	interval;
   975	           3    	NV	RETVAL;
   976	           3    	dXSTARG;
   977			
   978	           3    	if (items < 2)
   979	           3    	    interval = 0;
   980				else {
   981	      ######    	    interval = (NV)SvNV(ST(1));
   982				}
   983			#line 804 "HiRes.xs"
   984				if (seconds < 0.0 || interval < 0.0)
   985				    croak("Time::HiRes::alarm(%"NVgf", %"NVgf"): negative time not invented yet", seconds, interval);
   986				RETVAL = (NV)ualarm(seconds  * 1000000,
   987						    interval * 1000000) / 1E6;
   988			
   989			#line 990 "HiRes.c"
   990	           2    	XSprePUSH; PUSHn((NV)RETVAL);
   991			    }
   992	           2        XSRETURN(1);
   993			}
   994			
   995			#endif /* #ifdef HAS_UALARM */
   996			#ifdef HAS_GETTIMEOFDAY
   997			#    ifdef MACOS_TRADITIONAL	/* fix epoch TZ and use unsigned time_t */
   998			#define XSubPPtmpAAAE 1
   999			
  1000			
  1001			XS(XS_Time__HiRes_gettimeofday); /* prototype to pass -Wmissing-prototypes */
  1002			XS(XS_Time__HiRes_gettimeofday)
  1003			{
  1004			    dXSARGS;
  1005			    if (items != 0)
  1006				Perl_croak(aTHX_ "Usage: Time::HiRes::gettimeofday()");
  1007			    PERL_UNUSED_VAR(cv); /* -W */
  1008			    PERL_UNUSED_VAR(ax); /* -Wall */
  1009			    SP -= items;
  1010			    {
  1011			#line 819 "HiRes.xs"
  1012			        struct timeval Tp;
  1013			        struct timezone Tz;
  1014			#line 1015 "HiRes.c"
  1015			#line 822 "HiRes.xs"
  1016			        int status;
  1017			        status = gettimeofday (&Tp, &Tz);
  1018			
  1019				if (status == 0) {
  1020				     Tp.tv_sec += Tz.tz_minuteswest * 60;	/* adjust for TZ */
  1021			             if (GIMME == G_ARRAY) {
  1022			                 EXTEND(sp, 2);
  1023			                 /* Mac OS (Classic) has unsigned time_t */
  1024			                 PUSHs(sv_2mortal(newSVuv(Tp.tv_sec)));
  1025			                 PUSHs(sv_2mortal(newSViv(Tp.tv_usec)));
  1026			             } else {
  1027			                 EXTEND(sp, 1);
  1028			                 PUSHs(sv_2mortal(newSVnv(Tp.tv_sec + (Tp.tv_usec / 1000000.0))));
  1029				     }
  1030			        }
  1031			#line 1032 "HiRes.c"
  1032				PUTBACK;
  1033				return;
  1034			    }
  1035			}
  1036			
  1037			
  1038			XS(XS_Time__HiRes_time); /* prototype to pass -Wmissing-prototypes */
  1039			XS(XS_Time__HiRes_time)
  1040			{
  1041			    dXSARGS;
  1042			    if (items != 0)
  1043				Perl_croak(aTHX_ "Usage: Time::HiRes::time()");
  1044			    PERL_UNUSED_VAR(cv); /* -W */
  1045			    {
  1046			#line 841 "HiRes.xs"
  1047			        struct timeval Tp;
  1048			        struct timezone Tz;
  1049			#line 1050 "HiRes.c"
  1050				NV	RETVAL;
  1051				dXSTARG;
  1052			#line 844 "HiRes.xs"
  1053			        int status;
  1054			        status = gettimeofday (&Tp, &Tz);
  1055				if (status == 0) {
  1056			            Tp.tv_sec += Tz.tz_minuteswest * 60;	/* adjust for TZ */
  1057				    RETVAL = Tp.tv_sec + (Tp.tv_usec / 1000000.0);
  1058			        } else {
  1059				    RETVAL = -1.0;
  1060				}
  1061			#line 1062 "HiRes.c"
  1062				XSprePUSH; PUSHn((NV)RETVAL);
  1063			    }
  1064			    XSRETURN(1);
  1065			}
  1066			
  1067			#    else	/* MACOS_TRADITIONAL */
  1068			#define XSubPPtmpAAAF 1
  1069			
  1070			
  1071			XS(XS_Time__HiRes_gettimeofday); /* prototype to pass -Wmissing-prototypes */
  1072			XS(XS_Time__HiRes_gettimeofday)
  1073	          20    {
  1074	          20        dXSARGS;
  1075	          20        if (items != 0)
  1076	      ######    	Perl_croak(aTHX_ "Usage: Time::HiRes::gettimeofday()");
  1077	          20        PERL_UNUSED_VAR(cv); /* -W */
  1078	          20        PERL_UNUSED_VAR(ax); /* -Wall */
  1079	          20        SP -= items;
  1080			    {
  1081			#line 859 "HiRes.xs"
  1082			        struct timeval Tp;
  1083			#line 1084 "HiRes.c"
  1084			#line 861 "HiRes.xs"
  1085				int status;
  1086			        status = gettimeofday (&Tp, NULL);
  1087				if (status == 0) {
  1088				     if (GIMME == G_ARRAY) {
  1089				         EXTEND(sp, 2);
  1090			                 PUSHs(sv_2mortal(newSViv(Tp.tv_sec)));
  1091			                 PUSHs(sv_2mortal(newSViv(Tp.tv_usec)));
  1092			             } else {
  1093			                 EXTEND(sp, 1);
  1094			                 PUSHs(sv_2mortal(newSVnv(Tp.tv_sec + (Tp.tv_usec / 1000000.0))));
  1095			             }
  1096			        }
  1097			#line 1098 "HiRes.c"
  1098	          20    	PUTBACK;
  1099				return;
  1100			    }
  1101			}
  1102			
  1103			
  1104			XS(XS_Time__HiRes_time); /* prototype to pass -Wmissing-prototypes */
  1105			XS(XS_Time__HiRes_time)
  1106	         184    {
  1107	         184        dXSARGS;
  1108	         184        if (items != 0)
  1109	      ######    	Perl_croak(aTHX_ "Usage: Time::HiRes::time()");
  1110	         184        PERL_UNUSED_VAR(cv); /* -W */
  1111			    {
  1112			#line 877 "HiRes.xs"
  1113			        struct timeval Tp;
  1114			#line 1115 "HiRes.c"
  1115	         184    	NV	RETVAL;
  1116	         184    	dXSTARG;
  1117			#line 879 "HiRes.xs"
  1118				int status;
  1119			        status = gettimeofday (&Tp, NULL);
  1120				if (status == 0) {
  1121			            RETVAL = Tp.tv_sec + (Tp.tv_usec / 1000000.);
  1122				} else {
  1123				    RETVAL = -1.0;
  1124				}
  1125			#line 1126 "HiRes.c"
  1126	         184    	XSprePUSH; PUSHn((NV)RETVAL);
  1127			    }
  1128	         184        XSRETURN(1);
  1129			}
  1130			
  1131			#    endif	/* MACOS_TRADITIONAL */
  1132			#endif /* #ifdef HAS_GETTIMEOFDAY */
  1133			#if defined(HAS_GETITIMER) && defined(HAS_SETITIMER)
  1134			#define TV2NV(tv) ((NV)((tv).tv_sec) + 0.000001 * (NV)((tv).tv_usec))
  1135			#define XSubPPtmpAAAG 1
  1136			
  1137			
  1138			XS(XS_Time__HiRes_setitimer); /* prototype to pass -Wmissing-prototypes */
  1139			XS(XS_Time__HiRes_setitimer)
  1140	           2    {
  1141	           2        dXSARGS;
  1142	           2        if (items < 2 || items > 3)
  1143	      ######    	Perl_croak(aTHX_ "Usage: Time::HiRes::setitimer(which, seconds, interval = 0)");
  1144	           2        PERL_UNUSED_VAR(cv); /* -W */
  1145	           2        PERL_UNUSED_VAR(ax); /* -Wall */
  1146	           2        SP -= items;
  1147			    {
  1148	           2    	int	which = (int)SvIV(ST(0));
  1149	           2    	NV	seconds = (NV)SvNV(ST(1));
  1150	           2    	NV	interval;
  1151			#line 902 "HiRes.xs"
  1152				struct itimerval newit;
  1153				struct itimerval oldit;
  1154			#line 1155 "HiRes.c"
  1155			
  1156	           2    	if (items < 3)
  1157	           1    	    interval = 0;
  1158				else {
  1159	           1    	    interval = (NV)SvNV(ST(2));
  1160				}
  1161			#line 905 "HiRes.xs"
  1162				if (seconds < 0.0 || interval < 0.0)
  1163				    croak("Time::HiRes::setitimer(%"IVdf", %"NVgf", %"NVgf"): negative time not invented yet", (IV)which, seconds, interval);
  1164				newit.it_value.tv_sec  = seconds;
  1165				newit.it_value.tv_usec =
  1166				  (seconds  - (NV)newit.it_value.tv_sec)    * 1000000.0;
  1167				newit.it_interval.tv_sec  = interval;
  1168				newit.it_interval.tv_usec =
  1169				  (interval - (NV)newit.it_interval.tv_sec) * 1000000.0;
  1170				if (setitimer(which, &newit, &oldit) == 0) {
  1171				  EXTEND(sp, 1);
  1172				  PUSHs(sv_2mortal(newSVnv(TV2NV(oldit.it_value))));
  1173				  if (GIMME == G_ARRAY) {
  1174				    EXTEND(sp, 1);
  1175				    PUSHs(sv_2mortal(newSVnv(TV2NV(oldit.it_interval))));
  1176				  }
  1177				}
  1178			#line 1179 "HiRes.c"
  1179	           2    	PUTBACK;
  1180				return;
  1181			    }
  1182			}
  1183			
  1184			
  1185			XS(XS_Time__HiRes_getitimer); /* prototype to pass -Wmissing-prototypes */
  1186			XS(XS_Time__HiRes_getitimer)
  1187	        3999    {
  1188	        3999        dXSARGS;
  1189	        3999        if (items != 1)
  1190	      ######    	Perl_croak(aTHX_ "Usage: Time::HiRes::getitimer(which)");
  1191	        3999        PERL_UNUSED_VAR(cv); /* -W */
  1192	        3999        PERL_UNUSED_VAR(ax); /* -Wall */
  1193	        3999        SP -= items;
  1194			    {
  1195	        3999    	int	which = (int)SvIV(ST(0));
  1196			#line 926 "HiRes.xs"
  1197				struct itimerval nowit;
  1198			#line 1199 "HiRes.c"
  1199			#line 928 "HiRes.xs"
  1200				if (getitimer(which, &nowit) == 0) {
  1201				  EXTEND(sp, 1);
  1202				  PUSHs(sv_2mortal(newSVnv(TV2NV(nowit.it_value))));
  1203				  if (GIMME == G_ARRAY) {
  1204				    EXTEND(sp, 1);
  1205				    PUSHs(sv_2mortal(newSVnv(TV2NV(nowit.it_interval))));
  1206				  }
  1207				}
  1208			#line 1209 "HiRes.c"
  1209	        3999    	PUTBACK;
  1210				return;
  1211			    }
  1212			}
  1213			
  1214			#endif /* #if defined(HAS_GETITIMER) && defined(HAS_SETITIMER) */
  1215			#ifdef __cplusplus
  1216			extern "C"
  1217			#endif
  1218			XS(boot_Time__HiRes); /* prototype to pass -Wmissing-prototypes */
  1219			XS(boot_Time__HiRes)
  1220	          24    {
  1221	          24        dXSARGS;
  1222	          24        char* file = __FILE__;
  1223			
  1224	          24        PERL_UNUSED_VAR(cv); /* -W */
  1225	          24        PERL_UNUSED_VAR(items); /* -W */
  1226	          24        XS_VERSION_BOOTCHECK ;
  1227			
  1228			#if XSubPPtmpAAAA
  1229			        newXSproto("Time::HiRes::CLONE", XS_Time__HiRes_CLONE, file, ";@");
  1230			#endif
  1231	          24            newXSproto("Time::HiRes::constant", XS_Time__HiRes_constant, file, "$");
  1232			#if XSubPPtmpAAAB
  1233	          24            newXSproto("Time::HiRes::usleep", XS_Time__HiRes_usleep, file, "$");
  1234			#if XSubPPtmpAAAC
  1235	          24            newXSproto("Time::HiRes::nanosleep", XS_Time__HiRes_nanosleep, file, "$");
  1236			#endif
  1237	          24            newXSproto("Time::HiRes::sleep", XS_Time__HiRes_sleep, file, ";@");
  1238			#endif
  1239			#if XSubPPtmpAAAD
  1240	          24            newXSproto("Time::HiRes::ualarm", XS_Time__HiRes_ualarm, file, "$;$");
  1241	          24            newXSproto("Time::HiRes::alarm", XS_Time__HiRes_alarm, file, "$;$");
  1242			#endif
  1243			#if XSubPPtmpAAAE
  1244			        newXSproto("Time::HiRes::gettimeofday", XS_Time__HiRes_gettimeofday, file, "");
  1245			        newXSproto("Time::HiRes::time", XS_Time__HiRes_time, file, "");
  1246			#endif
  1247			#if XSubPPtmpAAAF
  1248	          24            newXSproto("Time::HiRes::gettimeofday", XS_Time__HiRes_gettimeofday, file, "");
  1249	          24            newXSproto("Time::HiRes::time", XS_Time__HiRes_time, file, "");
  1250			#endif
  1251			#if XSubPPtmpAAAG
  1252	          24            newXSproto("Time::HiRes::setitimer", XS_Time__HiRes_setitimer, file, "$$;$");
  1253	          24            newXSproto("Time::HiRes::getitimer", XS_Time__HiRes_getitimer, file, "$");
  1254			#endif
  1255			
  1256			    /* Initialisation Section */
  1257			
  1258			#line 654 "HiRes.xs"
  1259			{
  1260			#ifdef MY_CXT_KEY
  1261			  MY_CXT_INIT;
  1262			#endif
  1263			#ifdef ATLEASTFIVEOHOHFIVE
  1264			#ifdef HAS_GETTIMEOFDAY
  1265			  {
  1266			    UV auv[2];
  1267			    hv_store(PL_modglobal, "Time::NVtime", 12, newSViv(PTR2IV(myNVtime)), 0);
  1268			    if (myU2time(aTHX_ auv) == 0)
  1269			      hv_store(PL_modglobal, "Time::U2time", 12, newSViv((IV) auv[0]), 0);
  1270			  }
  1271			#endif
  1272			#endif
  1273			}
  1274			
  1275			#if XSubPPtmpAAAA
  1276			#endif
  1277			#if XSubPPtmpAAAB
  1278			#if XSubPPtmpAAAC
  1279			#endif
  1280			#endif
  1281			#if XSubPPtmpAAAD
  1282			#endif
  1283			#if XSubPPtmpAAAE
  1284			#endif
  1285			#if XSubPPtmpAAAF
  1286			#endif
  1287			#if XSubPPtmpAAAG
  1288			#endif
  1289			#line 1290 "HiRes.c"
  1290			
  1291			    /* End of Initialisation Section */
  1292			
  1293	          24        XSRETURN_YES;
  1294			}
  1295			
