自主协议库编译通过
This commit is contained in:
479
mmslib/util/stime.c
Normal file
479
mmslib/util/stime.c
Normal file
@@ -0,0 +1,479 @@
|
||||
/************************************************************************/
|
||||
/* SISCO SOFTWARE MODULE HEADER *****************************************/
|
||||
/************************************************************************/
|
||||
/* (c) Copyright Systems Integration Specialists Company, Inc., */
|
||||
/* 1993 - 2007, All Rights Reserved */
|
||||
/* */
|
||||
/* MODULE NAME : stime.c */
|
||||
/* PRODUCT(S) : */
|
||||
/* */
|
||||
/* MODULE DESCRIPTION : */
|
||||
/* This module implements functions that can be used in */
|
||||
/* differencial timimg. */
|
||||
/* */
|
||||
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
|
||||
/* */
|
||||
/* MODIFICATION LOG : */
|
||||
/* Date Who Rev Comments */
|
||||
/* -------- --- ------ ------------------------------------------- */
|
||||
/* 01/15/07 EJV 30 Chg S_LOCK_RESOURCES to S_LOCK_UTIL_RESOURCES*/
|
||||
/* 10/26/06 EJV 29 HP-UX: changed from gettimeofday() to times()*/
|
||||
/* 07/13/06 EJV 28 Sun: changed from gettimeofday() to times(). */
|
||||
/* 06/20/06 RKR 27 removed a piece of code from _sGetSysMsTime */
|
||||
/* 05/31/06 GLB 26 Integrated porting changes for VMS */
|
||||
/* 03/23/06 EJV 25 Corrected VMS chg to _sGetSysMsTime. */
|
||||
/* Rearranged includes, del windows.h. */
|
||||
/* 01/30/06 GLB 24 Integrated porting changes for VMS */
|
||||
/* 01/30/06 EJV 23 _WIN32 _sGetSysMsTime: added (ST_INT64) cast */
|
||||
/* before (ST_DOUBLE) to eliminate VS6 compiler*/
|
||||
/* error after changing ST_UINT64 define to */
|
||||
/* unsigned __int64. */
|
||||
/* 06/10/05 EJV 22 Revised the repeating code. */
|
||||
/* Linux, QNX: rpl gettimeofday() with times(). */
|
||||
/* Del MSDOS and __OS2__ code. */
|
||||
/* Del sGetMsStartTime, sSetMsStartTime */
|
||||
/* Renamed lastTime to initTime. */
|
||||
/* 03/11/04 GLB 21 Remove "thisFileName" */
|
||||
/* 12/09/03 JRB 20 Add LYNX support. */
|
||||
/* 11/04/03 JRB 19 Add sMsSleep (replaces gs_sleep). */
|
||||
/* 10/13/03 EJV 18 Chg defined(vms) to defined(__VMS) */
|
||||
/* 04/08/03 EJV 17 Use S_LOCK_RESOURCES (better for non-MT apps)*/
|
||||
/* 03/21/03 EJV 16 _WIN32: sGetMsTime, sGetSysMsTime must be */
|
||||
/* protected by mutex,prevent incorect wrapCount*/
|
||||
/* 03/18/03 EJV 15 Corrected __QNX4__ to __QNX__ (per JRB). */
|
||||
/* 03/18/03 EJV 14 sGetMsTime: fixed lastTime casting problem */
|
||||
/* (made lastTime ST_UINT on _WIN32). */
|
||||
/* 02/17/03 CRM 13 Added "defined(linux)" code. */
|
||||
/* 02/17/03 JRB 12 Add "sysincs.h" & del other includes. */
|
||||
/* Del obsolete _WINDOWS, MSOS2 code. */
|
||||
/* 02/17/03 EJV 11 sGetMsTime, sGetSysMsTime: fixed wrap counter*/
|
||||
/* Auto-initialize funs with call to stimeInit()*/
|
||||
/* Chg S_LOCK_RESOURCES to gs_get_sem,avoid loop*/
|
||||
/* 06/05/02 MDE,EJV 10 sGetMsTime: workaround some math problem */
|
||||
/* 11/29/01 EJV 09 Del code for old LATT, XENIX, ultrix, RMX86. */
|
||||
/* 06/19/01 JRB 08 Chg S_LOCK_COMMON.. to S_LOCK_RESOURCES so */
|
||||
/* glbsem doesn't log (caused infinite loop). */
|
||||
/* 04/19/00 JRB 07 Lint cleanup. */
|
||||
/* 11/18/99 EJV 06 Added code to capture wrapping of ms counter */
|
||||
/* for _WIN32 and PHARLAP_ETS. */
|
||||
/* 09/13/99 MDE 05 Added SD_CONST modifiers */
|
||||
/* 11/05/97 DSF 04 Added sGetSysMsTime () */
|
||||
/* 09/22/97 JRB 03 Fixed some #if's. */
|
||||
/* 09/09/97 JRB 02 Use GetTickCount for PHARLAP_ETS. */
|
||||
/* 09/08/97 EJV 01 Added code for QNX. */
|
||||
/* 04/02/97 DTL 7.00 MMSEASE 7.0 release. See MODL70.DOC for */
|
||||
/* history. */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
#include "glbtypes.h"
|
||||
#include "sysincs.h"
|
||||
#include "glbsem.h"
|
||||
|
||||
#if defined (_WIN32)
|
||||
#include <mmsystem.h>
|
||||
#if defined (PHARLAP_ETS)
|
||||
#define timeGetTime GetTickCount /* timeGetTime not supported */
|
||||
#endif /* PHARLAP_ETS */
|
||||
#endif
|
||||
|
||||
#if defined(__VMS)
|
||||
#include <starlet.h>
|
||||
#endif
|
||||
|
||||
#if defined(linux) || defined(sun) || defined(__hpux) || \
|
||||
defined(__QNX__) || defined(__LYNX)
|
||||
#include <sys/times.h> /* for struct tms */
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
/* NOTE: Users porting this code to new platform should not use the */
|
||||
/* gettimeofday() or similar functions. When the system time */
|
||||
/* is changed, for example during clock synchronization, the */
|
||||
/* gettimeofday() would also reflect this change. */
|
||||
/* Application should use times() function if available. */
|
||||
/* */
|
||||
/* DEBUG: On UNIX systems we should implement the sTime functions */
|
||||
/* the same way as on LINUX. */
|
||||
/************************************************************************/
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* stime module variables */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
#if defined(linux) || defined(sun) || defined(__hpux)
|
||||
static ST_UINT64 wrapCount; /* ms, cumulative wrapped time ticks elapsed since program start*/
|
||||
|
||||
#elif (defined (__QNX__) || defined(__LYNX))
|
||||
static ST_DOUBLE wrapCount; /* ms, cumulative wrapped time ticks elapsed since program start*/
|
||||
|
||||
#elif defined (_WIN32)
|
||||
static ST_UINT64 wrapCount; /* wrap count (see timeGetTime or GetTickTime) */
|
||||
#endif
|
||||
|
||||
#if defined (__ECOS)
|
||||
#define ST_UINT64 unsigned long long
|
||||
static unsigned long long wrapCount;
|
||||
#endif
|
||||
|
||||
static ST_ULONG ticksPerSec; /* system dependent value, returned by sysconf(_SC_CLK_TCK) */
|
||||
static ST_ULONG lastCheckTime; /* last time checked, used to detect clock_t overflow */
|
||||
static ST_DOUBLE initMsTime; /* in ms, store initialization time */
|
||||
static ST_INT initialized; /* SD_TRUE if stimeInit func successful */
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* _sGetSysMsTime */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Combined code from sGetMsTime and sGetSysMsTime, now also called by */
|
||||
/* stimeInit. */
|
||||
/* */
|
||||
/* NOTE: this new implementation on LINUX uses the times() function */
|
||||
/* to obtain the "number of clock ticks that have elapsed since */
|
||||
/* an arbitrary point in the past. For Linux this point is the */
|
||||
/* moment the system was booted. The return from times() may */
|
||||
/* overflow the possible range of clock_t." */
|
||||
/* The revision of the IEEE Std 1003.1, 2004 allows the that */
|
||||
/* reference point can be the start-up time of the process */
|
||||
/* rather than system start-up time. */
|
||||
/* IMPORTANT: */
|
||||
/* This implementation is assuming that POSIX compliant clock_t */
|
||||
/* type is defined as long (4 bytes integer). If this is not the */
|
||||
/* case then the code needs to be revised! */
|
||||
/* */
|
||||
/* DEBUG: In the future LINUX implementation should be used for all */
|
||||
/* UNIX systems. */
|
||||
/************************************************************************/
|
||||
|
||||
static ST_DOUBLE _sGetSysMsTime (ST_VOID)
|
||||
{
|
||||
ST_DOUBLE sysMsTime = (ST_DOUBLE) 0.0; /* system time to be returned */
|
||||
|
||||
#if defined(linux) || defined(sun) || defined(__hpux)
|
||||
{
|
||||
struct tms tmsTime; /* must be passed to times() but we do not use it */
|
||||
ST_ULONG sysTime;
|
||||
|
||||
sysTime = (ST_ULONG) times (&tmsTime);
|
||||
if (sysTime != (ST_ULONG) -1)
|
||||
{
|
||||
/* NOTE: The value returned from the times() function (number of ticks */
|
||||
/* from some fixed point in time) will wrap. */
|
||||
/* Wrapping depends on the frequency (ticksPerSec) and can be as */
|
||||
/* often as every 39 minutes. This function needs to be called */
|
||||
/* frequently enough to detect when the value wraps. */
|
||||
#if 0 /* DEBUG: code to test wrapping, */
|
||||
/* trigger the wrapping every 60 seconds if this funct is called */
|
||||
if ( (sysTime > ticksPerSec) && /* don't wrap before 1-st second elapses*/
|
||||
((sysTime / ticksPerSec) % 60 == 0) )
|
||||
lastCheckTime=sysTime+1; /* tweek the lastCheckTime */
|
||||
#endif
|
||||
if (sysTime < lastCheckTime)
|
||||
/* the ticks counter wrapped to 0 */
|
||||
wrapCount += ((ST_UINT64) 1 << 32); /* increment the high part of ST_UINT64 */
|
||||
/* convert the sys time to ms accounting for possible wrap */
|
||||
/* (switch math operations order / with * for better precission, avoid floating point math) */
|
||||
sysMsTime = (ST_DOUBLE)((wrapCount + (ST_UINT64) sysTime) * 1000 / (ST_UINT64) ticksPerSec);
|
||||
lastCheckTime = sysTime; /* save for next check */
|
||||
}
|
||||
else
|
||||
{
|
||||
ST_INT err;
|
||||
err = errno; /* can't log this error but we could see it in debugger */
|
||||
}
|
||||
}
|
||||
#elif defined(__ECOS)
|
||||
{
|
||||
struct timeval tp;
|
||||
struct timezone tzp;
|
||||
gettimeofday (&tp, &tzp); /* avoid floating math */
|
||||
sysMsTime = (ST_DOUBLE) ( (ST_UINT64) ((ST_ULONG) tp.tv_sec) * (ST_UINT64) 1000 +
|
||||
(ST_UINT64) ((ST_ULONG) tp.tv_usec) / (ST_UINT64) 1000 );
|
||||
#if 0
|
||||
cyg_tick_count_t sysTime; /* in ecos, cyg_tick_count_t is defined by cyg_uint64 */
|
||||
|
||||
sysTime = cyg_current_time();
|
||||
sysMsTime = (ST_DOUBLE)((wrapCount + (ST_UINT64) sysTime) * 1000 / (ST_UINT64) ticksPerSec);
|
||||
#endif
|
||||
}
|
||||
#elif defined(_AIX) || (defined(__alpha) && !defined(__VMS)) /* Tru64 alpha */
|
||||
{
|
||||
struct timeval tp;
|
||||
struct timezone tzp;
|
||||
gettimeofday (&tp, &tzp); /* avoid floating math */
|
||||
sysMsTime = (ST_DOUBLE) ( (ST_UINT64) ((ST_ULONG) tp.tv_sec) * (ST_UINT64) 1000 +
|
||||
(ST_UINT64) ((ST_ULONG) tp.tv_usec) / (ST_UINT64) 1000 );
|
||||
}
|
||||
#elif defined(__VMS) /* OpenVMS non-specific */
|
||||
{
|
||||
struct timeval tp;
|
||||
ST_LONG tzp;
|
||||
gettimeofday (&tp, &tzp); /* avoid floating math */
|
||||
sysMsTime = (ST_DOUBLE)
|
||||
(
|
||||
/*(ST_UINT64)*/ ((ST_ULONG) tp.tv_sec) * /*(ST_UINT64)*/ 1000 +
|
||||
/*(ST_UINT64)*/ ((ST_ULONG) tp.tv_usec) / /*(ST_UINT64)*/ 1000
|
||||
);
|
||||
}
|
||||
#elif defined (VXWORKS)
|
||||
{
|
||||
/*renxiaobao add*/
|
||||
struct timeval tp;
|
||||
vx_gettimeofday (&tp,0);
|
||||
sysMsTime = ((ST_DOUBLE)tp.tv_sec)*1000 + ((ST_DOUBLE)tp.tv_usec)/1000;
|
||||
/*sysMsTime = (ST_DOUBLE) time (NULL) * 1000;*/
|
||||
}
|
||||
#elif (defined (__QNX__) || defined(__LYNX))
|
||||
{
|
||||
struct tms tmsTime; /* must be passed to times() but we do not use it */
|
||||
ST_ULONG sysTime;
|
||||
|
||||
sysTime = (ST_ULONG) times (&tmsTime);
|
||||
if (sysTime != (ST_ULONG) -1)
|
||||
{
|
||||
/* NOTE: The value returned from the times() function (number of ticks */
|
||||
/* from some fixed point in time) will wrap. */
|
||||
/* Wrapping depends on the frequency (ticksPerSec) and can be as */
|
||||
/* often as every 39 minutes. This function needs to be called */
|
||||
/* frequently enough to detect when the value wraps. */
|
||||
if (sysTime < lastCheckTime)
|
||||
/* the ticks counter wrapped to 0 */
|
||||
wrapCount += (ST_DOUBLE) (ULONG_MAX);
|
||||
/* convert the sys time to ms accounting for possible wrap, */
|
||||
/* note that we do not have ST_INT64 support on QNX or LYNX systems */
|
||||
sysMsTime = (ST_DOUBLE)((wrapCount + (ST_DOUBLE) sysTime) * 1000.0 / (ST_DOUBLE) ticksPerSec);
|
||||
lastCheckTime = sysTime; /* save for next check */
|
||||
}
|
||||
}
|
||||
#elif defined (_WIN32)
|
||||
{
|
||||
ST_ULONG msTime;
|
||||
|
||||
/* the timeGetTime function retrieves the system time, in milliseconds.*/
|
||||
/* The system time is the time elapsed since Windows was started. */
|
||||
|
||||
/* NOTE: The timeGetTime and GetTickCount (used for PHARLAP_ETS) */
|
||||
/* return DWORD value that wraps to 0 every 49 days. */
|
||||
/* We need to detect the wrap up moment and save it. */
|
||||
msTime = (ST_ULONG) timeGetTime ();
|
||||
if ( msTime < lastCheckTime )
|
||||
/* the ms counter wrapped to 0 */
|
||||
wrapCount += ( (ST_UINT64) 1 << 32 ); /* increment the high part of ST_UINT64 */
|
||||
sysMsTime = (ST_DOUBLE) (ST_INT64) (wrapCount + (ST_UINT64) msTime);
|
||||
/* NOTE VC V6.0 compiler: the compiler generates error for the */
|
||||
/* conversion of unsigned __int64 to double. We will cast to */
|
||||
/* ST_INT64 before the ST_DOUBLE cast. This should work */
|
||||
/* because the sum of both numbers will 'never' be negative. */
|
||||
|
||||
lastCheckTime = msTime; /* save for next check */
|
||||
}
|
||||
#else
|
||||
#error Missing stime module implementation for this platform
|
||||
#endif
|
||||
|
||||
return (sysMsTime);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* _stimeReset */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Resets stime module variables. */
|
||||
/************************************************************************/
|
||||
|
||||
static ST_RET _stimeReset (ST_VOID)
|
||||
{
|
||||
ST_RET rtn = SD_SUCCESS;
|
||||
|
||||
#if (defined(linux) || defined(sun) || defined(__hpux) || defined(_WIN32))
|
||||
wrapCount = 0;
|
||||
lastCheckTime = 0;
|
||||
#elif (defined(__QNX__) || defined(__LYNX))
|
||||
wrapCount = 0.0;
|
||||
lastCheckTime = 0;
|
||||
#endif
|
||||
|
||||
initMsTime = _sGetSysMsTime ();
|
||||
|
||||
return (rtn);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* stimeInit */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Initialize stime module variables. */
|
||||
/************************************************************************/
|
||||
|
||||
ST_RET stimeInit (ST_VOID)
|
||||
{
|
||||
ST_RET rtn = SD_SUCCESS;
|
||||
|
||||
/* Allow multiple calls */
|
||||
if (initialized)
|
||||
return (rtn);
|
||||
|
||||
S_LOCK_UTIL_RESOURCES (); /* NOTE: this macro is now using non-logging gs_get_sem() */
|
||||
|
||||
#if defined(linux) || defined(sun) || defined(__hpux) || defined(__QNX__) || defined(__LYNX)
|
||||
{
|
||||
ticksPerSec = 0;
|
||||
|
||||
ticksPerSec = (ST_ULONG) sysconf(_SC_CLK_TCK);
|
||||
if (ticksPerSec == (ST_ULONG) -1L || ticksPerSec == 0)
|
||||
rtn = SD_FAILURE; /* some error getting the number of clock ticks per second */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rtn == SD_SUCCESS)
|
||||
{
|
||||
rtn = _stimeReset ();
|
||||
if (rtn == SD_SUCCESS)
|
||||
initialized = SD_TRUE;
|
||||
}
|
||||
|
||||
S_UNLOCK_UTIL_RESOURCES ();
|
||||
|
||||
return (rtn);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* sGetMsTime */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Returns time in milliseconds form the start of the program. */
|
||||
/************************************************************************/
|
||||
|
||||
ST_DOUBLE sGetMsTime (ST_VOID)
|
||||
{
|
||||
ST_DOUBLE sysMsTime, retMsTime;
|
||||
|
||||
if (!initialized)
|
||||
if (stimeInit () != SD_SUCCESS)
|
||||
return ((ST_DOUBLE)0.0);
|
||||
|
||||
S_LOCK_UTIL_RESOURCES ();
|
||||
|
||||
sysMsTime = _sGetSysMsTime();
|
||||
retMsTime = sysMsTime - initMsTime;
|
||||
|
||||
S_UNLOCK_UTIL_RESOURCES ();
|
||||
|
||||
return (retMsTime);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* sGetSysMsTime */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Returns system time in milliseconds (time from an arbitrary point */
|
||||
/* like system start or program start). */
|
||||
/************************************************************************/
|
||||
|
||||
ST_DOUBLE sGetSysMsTime (ST_VOID)
|
||||
{
|
||||
ST_DOUBLE sysMsTime;
|
||||
|
||||
if (!initialized)
|
||||
if (stimeInit () != SD_SUCCESS)
|
||||
return ((ST_DOUBLE)0.0);
|
||||
|
||||
S_LOCK_UTIL_RESOURCES ();
|
||||
|
||||
sysMsTime = _sGetSysMsTime();
|
||||
|
||||
S_UNLOCK_UTIL_RESOURCES ();
|
||||
|
||||
return (sysMsTime);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* sResetMsTime */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Reset stime module variables. */
|
||||
/************************************************************************/
|
||||
|
||||
ST_VOID sResetMsTime (ST_VOID)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
stimeInit (); /* calls the _stimeReset() */
|
||||
return;
|
||||
}
|
||||
|
||||
S_LOCK_UTIL_RESOURCES ();
|
||||
|
||||
_stimeReset ();
|
||||
|
||||
S_UNLOCK_UTIL_RESOURCES ();
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* stimeExit */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Terminate timer use. */
|
||||
/************************************************************************/
|
||||
|
||||
ST_VOID stimeExit (ST_VOID)
|
||||
{
|
||||
if (!initialized)
|
||||
return;
|
||||
|
||||
S_LOCK_UTIL_RESOURCES ();
|
||||
|
||||
initialized = SD_FALSE;
|
||||
|
||||
S_UNLOCK_UTIL_RESOURCES ();
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* sMsSleep */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Calls system function to suspend current task or thread for */
|
||||
/* specified amount of time. */
|
||||
/* Parameters: */
|
||||
/* ST_LONG ms Number of milliseconds to sleep */
|
||||
/* Return values: */
|
||||
/* none */
|
||||
/************************************************************************/
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
ST_VOID sMsSleep (ST_LONG ms)
|
||||
{
|
||||
Sleep (ms);
|
||||
}
|
||||
|
||||
#elif defined(__VMS)
|
||||
|
||||
ST_VOID sMsSleep (ST_LONG ms)
|
||||
{
|
||||
ST_ULONG msec = (ST_ULONG) ms;
|
||||
unsigned int us;
|
||||
|
||||
while (msec > 0)
|
||||
{
|
||||
if (msec >= 1000)
|
||||
{
|
||||
us = 999999; /* microseconds, it must be less than 1000000 for usleep */
|
||||
msec -= 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
us = msec * 1000;
|
||||
msec = 0;
|
||||
}
|
||||
usleep (us); /* unistd.h */
|
||||
}
|
||||
}
|
||||
|
||||
#else /* all other systems */
|
||||
|
||||
/* This version of the function uses the POSIX nanosleep function. */
|
||||
ST_VOID sMsSleep (ST_LONG ms)
|
||||
{
|
||||
struct timespec rqtp;
|
||||
|
||||
rqtp.tv_sec = ms / 1000;
|
||||
rqtp.tv_nsec = (ms % 1000) * 1000000; /* 1000 ms/us, 1000 us/ns ... */
|
||||
|
||||
nanosleep (&rqtp, NULL); /* should be available on AIX v5.x */
|
||||
}
|
||||
|
||||
#endif /* all other systems */
|
||||
Reference in New Issue
Block a user