⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hires.xs

📁 source of perl for linux application,
💻 XS
📖 第 1 页 / 共 3 页
字号:
/* *  * Copyright (c) 1996-2002 Douglas E. Wegscheid.  All rights reserved. *  * Copyright (c) 2002,2003,2004,2005,2006,2007 Jarkko Hietaniemi.  All rights reserved. *  * This program is free software; you can redistribute it and/or modify * it under the same terms as Perl itself. */#ifdef __cplusplusextern "C" {#endif#define PERL_NO_GET_CONTEXT#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#include "ppport.h"#if defined(__CYGWIN__) && defined(HAS_W32API_WINDOWS_H)# include <w32api/windows.h># define CYGWIN_WITH_W32API#endif#ifdef WIN32# include <time.h>#else# include <sys/time.h>#endif#ifdef HAS_SELECT# ifdef I_SYS_SELECT#  include <sys/select.h># endif#endif#if defined(TIME_HIRES_CLOCK_GETTIME_SYSCALL) || defined(TIME_HIRES_CLOCK_GETRES_SYSCALL)#include <syscall.h>#endif#ifdef __cplusplus}#endif#define IV_1E6 1000000#define IV_1E7 10000000#define IV_1E9 1000000000#define NV_1E6 1000000.0#define NV_1E7 10000000.0#define NV_1E9 1000000000.0#ifndef PerlProc_pause#   define PerlProc_pause() Pause()#endif#ifdef HAS_PAUSE#   define Pause   pause#else#   undef Pause /* In case perl.h did it already. */#   define Pause() sleep(~0) /* Zzz for a long time. */#endif/* Though the cpp define ITIMER_VIRTUAL is available the functionality * is not supported in Cygwin as of August 2004, ditto for Win32. * Neither are ITIMER_PROF or ITIMER_REALPROF implemented.  --jhi */#if defined(__CYGWIN__) || defined(WIN32)#   undef ITIMER_VIRTUAL#   undef ITIMER_PROF#   undef ITIMER_REALPROF#endif#if defined(TIME_HIRES_CLOCK_GETTIME) && defined(_STRUCT_ITIMERSPEC)/* HP-UX has CLOCK_XXX values but as enums, not as defines. * The only way to detect these would be to test compile for each. */# ifdef __hpux#  define CLOCK_REALTIME CLOCK_REALTIME#  define CLOCK_VIRTUAL  CLOCK_VIRTUAL#  define CLOCK_PROFILE  CLOCK_PROFILE# endif /* # ifdef __hpux */#endif /* #if defined(TIME_HIRES_CLOCK_GETTIME) && defined(_STRUCT_ITIMERSPEC) */#if defined(WIN32) || defined(CYGWIN_WITH_W32API)#ifndef HAS_GETTIMEOFDAY#   define HAS_GETTIMEOFDAY#endif/* shows up in winsock.h?struct timeval { long tv_sec; long tv_usec;}*/typedef union {    unsigned __int64	ft_i64;    FILETIME		ft_val;} FT_t;#define MY_CXT_KEY "Time::HiRes_" XS_VERSIONtypedef struct {    unsigned long run_count;    unsigned __int64 base_ticks;    unsigned __int64 tick_frequency;    FT_t base_systime_as_filetime;    unsigned __int64 reset_time;} my_cxt_t;START_MY_CXT/* Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 */#ifdef __GNUC__# define Const64(x) x##LL#else# define Const64(x) x##i64#endif#define EPOCH_BIAS  Const64(116444736000000000)#ifdef Const64# ifdef __GNUC__#  define IV_1E6LL  1000000LL /* Needed because of Const64() ##-appends LL (or i64). */#  define IV_1E7LL  10000000LL#  define IV_1E9LL  1000000000LL# else#  define IV_1E6i64 1000000i64#  define IV_1E7i64 10000000i64#  define IV_1E9i64 1000000000i64# endif#endif/* NOTE: This does not compute the timezone info (doing so can be expensive, * and appears to be unsupported even by glibc) *//* dMY_CXT needs a Perl context and we don't want to call PERL_GET_CONTEXT   for performance reasons */#undef gettimeofday#define gettimeofday(tp, not_used) _gettimeofday(aTHX_ tp, not_used)/* If the performance counter delta drifts more than 0.5 seconds from the * system time then we recalibrate to the system time.  This means we may * move *backwards* in time! */#define MAX_PERF_COUNTER_SKEW Const64(5000000) /* 0.5 seconds *//* Reset reading from the performance counter every five minutes. * Many PC clocks just seem to be so bad. */#define MAX_PERF_COUNTER_TICKS Const64(300000000) /* 300 seconds */static int_gettimeofday(pTHX_ struct timeval *tp, void *not_used){    dMY_CXT;    unsigned __int64 ticks;    FT_t ft;    if (MY_CXT.run_count++ == 0 ||	MY_CXT.base_systime_as_filetime.ft_i64 > MY_CXT.reset_time) {        QueryPerformanceFrequency((LARGE_INTEGER*)&MY_CXT.tick_frequency);        QueryPerformanceCounter((LARGE_INTEGER*)&MY_CXT.base_ticks);        GetSystemTimeAsFileTime(&MY_CXT.base_systime_as_filetime.ft_val);        ft.ft_i64 = MY_CXT.base_systime_as_filetime.ft_i64;	MY_CXT.reset_time = ft.ft_i64 + MAX_PERF_COUNTER_TICKS;    }    else {	__int64 diff;        QueryPerformanceCounter((LARGE_INTEGER*)&ticks);        ticks -= MY_CXT.base_ticks;        ft.ft_i64 = MY_CXT.base_systime_as_filetime.ft_i64                    + Const64(IV_1E7) * (ticks / MY_CXT.tick_frequency)                    +(Const64(IV_1E7) * (ticks % MY_CXT.tick_frequency)) / MY_CXT.tick_frequency;	diff = ft.ft_i64 - MY_CXT.base_systime_as_filetime.ft_i64;	if (diff < -MAX_PERF_COUNTER_SKEW || diff > MAX_PERF_COUNTER_SKEW) {	    MY_CXT.base_ticks += ticks;            GetSystemTimeAsFileTime(&MY_CXT.base_systime_as_filetime.ft_val);            ft.ft_i64 = MY_CXT.base_systime_as_filetime.ft_i64;	}    }    /* seconds since epoch */    tp->tv_sec = (long)((ft.ft_i64 - EPOCH_BIAS) / Const64(IV_1E7));    /* microseconds remaining */    tp->tv_usec = (long)((ft.ft_i64 / Const64(10)) % Const64(IV_1E6));    return 0;}#endif#if defined(WIN32) && !defined(ATLEASTFIVEOHOHFIVE)static unsigned intsleep(unsigned int t){    Sleep(t*1000);    return 0;}#endif#if !defined(HAS_GETTIMEOFDAY) && defined(VMS)#define HAS_GETTIMEOFDAY#include <lnmdef.h>#include <time.h> /* gettimeofday */#include <stdlib.h> /* qdiv */#include <starlet.h> /* sys$gettim */#include <descrip.h>#ifdef __VAX#include <lib$routines.h> /* lib$ediv() */#endif/*        VMS binary time is expressed in 100 nano-seconds since        system base time which is 17-NOV-1858 00:00:00.00*/#define DIV_100NS_TO_SECS  10000000L#define DIV_100NS_TO_USECS 10L/*         gettimeofday is supposed to return times since the epoch        so need to determine this in terms of VMS base time*/static $DESCRIPTOR(dscepoch,"01-JAN-1970 00:00:00.00");#ifdef __VAXstatic long base_adjust[2]={0L,0L};#elsestatic __int64 base_adjust=0;#endif/*    If we don't have gettimeofday, then likely we are on a VMS machine that   operates on local time rather than UTC...so we have to zone-adjust.   This code gleefully swiped from VMS.C *//* method used to handle UTC conversions: *   1 == CRTL gmtime();  2 == SYS$TIMEZONE_DIFFERENTIAL;  3 == no correction */static int gmtime_emulation_type;/* number of secs to add to UTC POSIX-style time to get local time */static long int utc_offset_secs;static struct dsc$descriptor_s fildevdsc =   { 12, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$FILE_DEV" };static struct dsc$descriptor_s *fildev[] = { &fildevdsc, NULL };static time_t toutc_dst(time_t loc) {  struct tm *rsltmp;  if ((rsltmp = localtime(&loc)) == NULL) return -1;  loc -= utc_offset_secs;  if (rsltmp->tm_isdst) loc -= 3600;  return loc;}static time_t toloc_dst(time_t utc) {  struct tm *rsltmp;  utc += utc_offset_secs;  if ((rsltmp = localtime(&utc)) == NULL) return -1;  if (rsltmp->tm_isdst) utc += 3600;  return utc;}#define _toutc(secs)  ((secs) == (time_t) -1 ? (time_t) -1 : \       ((gmtime_emulation_type || timezone_setup()), \       (gmtime_emulation_type == 1 ? toutc_dst(secs) : \       ((secs) - utc_offset_secs))))#define _toloc(secs)  ((secs) == (time_t) -1 ? (time_t) -1 : \       ((gmtime_emulation_type || timezone_setup()), \       (gmtime_emulation_type == 1 ? toloc_dst(secs) : \       ((secs) + utc_offset_secs))))static inttimezone_setup(void) {  struct tm *tm_p;  if (gmtime_emulation_type == 0) {    int dstnow;    time_t base = 15 * 86400; /* 15jan71; to avoid month/year ends between    */                              /* results of calls to gmtime() and localtime() */                              /* for same &base */    gmtime_emulation_type++;    if ((tm_p = gmtime(&base)) == NULL) { /* CRTL gmtime() is a fake */      char off[LNM$C_NAMLENGTH+1];;      gmtime_emulation_type++;      if (!Perl_vmstrnenv("SYS$TIMEZONE_DIFFERENTIAL",off,0,fildev,0)) {        gmtime_emulation_type++;        utc_offset_secs = 0;        Perl_warn(aTHX_ "no UTC offset information; assuming local time is UTC");      }      else { utc_offset_secs = atol(off); }    }    else { /* We've got a working gmtime() */      struct tm gmt, local;      gmt = *tm_p;      tm_p = localtime(&base);      local = *tm_p;      utc_offset_secs  = (local.tm_mday - gmt.tm_mday) * 86400;      utc_offset_secs += (local.tm_hour - gmt.tm_hour) * 3600;      utc_offset_secs += (local.tm_min  - gmt.tm_min)  * 60;      utc_offset_secs += (local.tm_sec  - gmt.tm_sec);    }  }  return 1;}intgettimeofday (struct timeval *tp, void *tpz){ long ret;#ifdef __VAX long quad[2]; long quad1[2]; long div_100ns_to_secs; long div_100ns_to_usecs; long quo,rem; long quo1,rem1;#else __int64 quad; __qdiv_t ans1,ans2;#endif/*        In case of error, tv_usec = 0 and tv_sec = VMS condition code.        The return from function is also set to -1.        This is not exactly as per the manual page.*/ tp->tv_usec = 0;#ifdef __VAX if (base_adjust[0]==0 && base_adjust[1]==0) {#else if (base_adjust==0) { /* Need to determine epoch adjustment */#endif        ret=sys$bintim(&dscepoch,&base_adjust);        if (1 != (ret &&1)) {                tp->tv_sec = ret;                return -1;        } } ret=sys$gettim(&quad); /* Get VMS system time */ if ((1 && ret) == 1) {#ifdef __VAX        quad[0] -= base_adjust[0]; /* convert to epoch offset */        quad[1] -= base_adjust[1]; /* convert 2nd half of quadword */        div_100ns_to_secs = DIV_100NS_TO_SECS;        div_100ns_to_usecs = DIV_100NS_TO_USECS;        lib$ediv(&div_100ns_to_secs,&quad,&quo,&rem);        quad1[0] = rem;        quad1[1] = 0L;        lib$ediv(&div_100ns_to_usecs,&quad1,&quo1,&rem1);        tp->tv_sec = quo; /* Whole seconds */        tp->tv_usec = quo1; /* Micro-seconds */#else        quad -= base_adjust; /* convert to epoch offset */        ans1=qdiv(quad,DIV_100NS_TO_SECS);        ans2=qdiv(ans1.rem,DIV_100NS_TO_USECS);        tp->tv_sec = ans1.quot; /* Whole seconds */        tp->tv_usec = ans2.quot; /* Micro-seconds */#endif } else {        tp->tv_sec = ret;        return -1; }# ifdef VMSISH_TIME# ifdef RTL_USES_UTC  if (VMSISH_TIME) tp->tv_sec = _toloc(tp->tv_sec);# else  if (!VMSISH_TIME) tp->tv_sec = _toutc(tp->tv_sec);# endif# endif return 0;}#endif /* Do not use H A S _ N A N O S L E E P  * so that Perl Configure doesn't scan for it (and pull in -lrt and  * the like which are not usually good ideas for the default Perl).  * (We are part of the core perl now.)  * 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 */voidhrt_nanosleep(unsigned long usec) /* This is used to emulate usleep. */{    struct timespec res;    res.tv_sec = usec / IV_1E6;    res.tv_nsec = ( usec - res.tv_sec * IV_1E6 ) * 1000;    nanosleep(&res, NULL);}#endif /* #if !defined(HAS_USLEEP) && defined(TIME_HIRES_NANOSLEEP) */#if !defined(HAS_USLEEP) && defined(HAS_SELECT)#ifndef SELECT_IS_BROKEN#define HAS_USLEEP#define usleep hrt_usleep  /* could conflict with ncurses for static build */void

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -