📄 rvtime.c
字号:
SystemTimeToFileTime(&systime, &filetime);
uint_time = (ULARGE_INTEGER *)&filetime;
uint_time->QuadPart = uint_time->QuadPart - EPOCHDELTA;
tp->tv_sec = (time_t)(uint_time->QuadPart / 10000000Ui64);
tp->tv_nsec = (long)((uint_time->QuadPart % 10000000Ui64) * 100Ui64);
#endif
#if defined(RV_OS_PSOS)
tm_get(&datefield, &timefield, &ticks);
epochtm.tm_sec = (int)(timefield & 0xFFUL);
epochtm.tm_min = (int)((timefield >> 8) & 0xFFUL);
epochtm.tm_hour = (int)((timefield >> 16) & 0xFFFFUL);
epochtm.tm_mday = (int)(datefield & 0xFFUL);
epochtm.tm_mon = (int)((datefield >> 8) & 0xFFUL) - 1;
epochtm.tm_year = (int)((datefield >> 16) & 0xFFFFUL) - 1900;
epochtm.tm_isdst = -1;
tp->tv_sec = mktime(&epochtm);
tp->tv_nsec = (long)(((long long)ticks * 1000000000LL) / tick_hz);
#endif
#if defined(RV_OS_OSE)
get_time(&tvp);
tp->tv_sec = (RvTime)tvp.seconds;
tp->tv_nsec = (long)(tvp.micros * 1000UL);
#endif
#if defined(RV_OS_NUCLEUS)
/* Nucleus doesn't have a wall clock so we have to keep one */
curticks = (long long )NU_Retrieve_Clock();
tp->tv_sec = (long)(curticks / tick_hz) + timezero;
tp->tv_nsec = (long) (((curticks % tick_hz) * 1000000000LL) / tick_hz);
#endif
return tp->tv_sec;
}
/* Returns resolution of wall time in seconds and nanoseconds. */
RvTimespec *rvTimeGetTimeRes(RvTimespec *result)
{
if(result == NULL) return NULL;
#if defined(RV_OS_SOLARIS) || defined(RV_OS_TRU64) || defined(RV_OS_HPUX) || defined(RV_OS_VXWORKS)
clock_getres(CLOCK_REALTIME, result);
#endif
#if defined(RV_OS_REDHAT) || defined(RV_OS_WIN32)
if(CLOCKS_PER_SEC > 1) {
result->tv_sec = 0L;
result->tv_nsec = (long)(1000000000 / CLOCKS_PER_SEC);
} else {
result->tv_sec = 1L;
result->tv_nsec = 0L;
}
#endif
#if defined(RV_OS_PSOS) || defined(RV_OS_NUCLEUS)
if(tick_hz > 1LL) {
result->tv_sec = 0L;
result->tv_nsec = (long)(1000000000LL / tick_hz);
} else {
result->tv_sec = 1L;
result->tv_nsec = 0L;
}
#endif
#if defined(RV_OS_OSE)
result->tv_sec = (long)(tick_period / 1000000000LL);
result->tv_nsec = (long)(tick_period % 1000000000LL);
#endif
return result;
}
/* Set time since epoch (January 1, 1970) -- on most systems just */
/* makes call to OS. On those systems with no wall clock, calculate */
/* wall time based on clock tick. Returns RvTrue if clock it set */
/* properly. Remember that certain systems require special privileges */
/* to change the system clock. */
RvBool rvTimeSetEpochTime(RvTimespec *curtime)
{
#if defined(RV_OS_REDHAT)
struct timeval tv;
#endif
#if defined(RV_OS_WIN32)
SYSTEMTIME systime;
FILETIME filetime;
ULARGE_INTEGER *uint_time;
#endif
#if defined(RV_OS_PSOS)
RvTm epochtm;
unsigned long datefield, timefield, ticks;
#endif
#if defined(RV_OS_OSE)
struct TimePair tvp;
#endif
#if defined(RV_OS_NUCLEUS)
long long curticks;
long cursecs;
#endif
if(curtime == NULL) return rvFalse;
#if defined(RV_OS_SOLARIS) || defined(RV_OS_TRU64) || defined(RV_OS_HPUX) || defined(RV_OS_VXWORKS)
if(clock_settime(CLOCK_REALTIME, curtime) != 0) return rvFalse;
#endif
#if defined(RV_OS_REDHAT)
TIMESPEC_TO_TIMEVAL(&tv, curtime);
if(settimeofday(&tv, NULL)!= 0) return rvFalse;
#endif
#if defined(RV_OS_WIN32)
uint_time = (ULARGE_INTEGER *)&filetime;
uint_time->QuadPart = (ULONGLONG)curtime->tv_sec * 10000000Ui64 +
(ULONGLONG)curtime->tv_nsec / 100Ui64 +
EPOCHDELTA;
if(FileTimeToSystemTime(&filetime, &systime) == 0) return rvFalse;
if(SetSystemTime(&systime) == 0) return rvFalse;
#endif
#if defined(RV_OS_PSOS)
if(rvTimeUTC(curtime->tv_sec, &epochtm) == NULL) return rvFalse;
ticks = (unsigned long)(((long long)curtime->tv_nsec * tick_hz) / 1000000000LL);
timefield = ((unsigned long)epochtm.tm_hour << 16) |
((unsigned long)epochtm.tm_min << 8) |
(unsigned long)epochtm.tm_sec;
datefield = ((unsigned long)(epochtm.tm_year + 1900) << 16) |
((unsigned long)(epochtm.tm_mon + 1) << 8) |
(unsigned long)epochtm.tm_mday;
if(tm_set(datefield, timefield, ticks) != 0) return rvFalse;
#endif
#if defined(RV_OS_OSE)
tvp.seconds = (unsigned long)curtime->tv_sec;
tvp.micros = (unsigned long)curtime->tv_nsec / 1000UL;
set_time(&tvp);
#endif
#if defined(RV_OS_NUCLEUS)
/* Nucleus doesn't have a wall clock so we have to keep one. */
/* Only set seconds so we don't have to do locking. */
curticks = (long long )NU_Retrieve_Clock();
cursecs = (long)(curticks / tick_hz);
cursecs = curtime->tv_sec - cursecs;
if(cursecs < 0) return rvFalse;
timezero = cursecs;
#endif
return rvTrue;
}
/* Get a high resolution relative relative time stamp. This value */
/* will never go backwards and will not wrap until about 68 years */
/* from power-up (seconds will wrap) */
RvTimespec *rvTimeGetHires(RvTimespec *result)
{
#if defined(RV_OS_SOLARIS) && !defined(CLOCK_HIGHRES)
RvHrtime nanosecs; /* only needed for Solaris before version 8 */
#endif
#if defined(RV_OS_REDHAT)
unsigned long eax,edx;
long long tickcount;
#endif
#if defined(RV_OS_TRU64)
struct timeval tv;
#endif
#if defined(RV_OS_WIN32)
LARGE_INTEGER PerformanceCount;
#endif
#if defined(RV_OS_VXWORKS)
long long tickcount;
#if defined(RV_VXWORKS_USETIMESTAMP)
long long lastcount_copy1, lastcount_copy2;
ULONG laststamp_copy;
#else
long wrapcount_copy;
ULONG cur_tick, lasttick_copy1, lasttick_copy2;
#endif
#endif
#if defined(RV_OS_PSOS)
long long tickcount;
unsigned long tickshi, tickslo;
#endif
#if defined(RV_OS_OSE)
RvHrtime hrtime;
#endif
#if defined(RV_OS_NUCLEUS)
long long tickcount;
long wrapcount_copy;
UNSIGNED cur_tick, lasttick_copy1, lasttick_copy2;
#endif
if (result == NULL) return NULL;
#if defined(RV_OS_SOLARIS)
#if defined(CLOCK_HIGHRES) /* If CLOCK_HIGHRES isn't defined, then it is pre Solaris 8 */
clock_gettime(CLOCK_HIGHRES, result);
#else
/* Solaris 2.6 and 7 don't have the posix call, so convert it */
nanosecs = rvTimeGetHrtime();
result->tv_sec = (time_t)(nanosecs / 1000000000LL);
result->tv_nsec = (long)(nanosecs % 1000000000LL);
#endif
#endif
#if defined(RV_OS_REDHAT)
rdtsc(eax,edx);
tickcount = (long long)edx * (long long)ULONG_MAX + (long long)edx + (long long)eax;
result->tv_sec = (time_t)(tickcount / tick_hz);
result->tv_nsec = (long) (((tickcount % tick_hz) * 1000000000LL) / tick_hz);
#endif
#if defined(RV_OS_TRU64)
tv = rvTimestampClock.info->tv;
result->tv_sec = tv.tv_sec;
result->tv_nsec = tv.tv_usec * 1000;
#endif
#if defined(RV_OS_HPUX)
/* This is not absolutely correct, since this clock is wall clock
and could "go backwards", but there is no other alternative */
clock_gettime(CLOCK_REALTIME, result);
#endif
#if defined(RV_OS_WIN32)
QueryPerformanceCounter(&PerformanceCount);
result->tv_sec = (time_t)(PerformanceCount.QuadPart / tick_hz);
result->tv_nsec = (long)(((PerformanceCount.QuadPart % tick_hz) * 1000000000i64) / tick_hz);
#endif
#if defined(RV_OS_VXWORKS)
#if defined(RV_VXWORKS_USETIMESTAMP)
/* Get hires count and timestamp without locking */
do {
lastcount_copy1 = hires_count;
laststamp_copy = sysTimestampLock();
lastcount_copy2= hires_count;
} while(lastcount_copy1 != lastcount_copy2);
tickcount = lastcount_copy1 + (long long)laststamp_copy;
#else
/* Clock tick is only 32 bits, check for wrap without locking */
do {
lasttick_copy1 = last_tick;
wrapcount_copy = wrap_count;
lasttick_copy2 = last_tick;
} while (lasttick_copy1 != lasttick_copy2); /* max 2 loops */
cur_tick = tickGet();
if(cur_tick < lasttick_copy1)
wrapcount_copy += 1;
tickcount = (long long)cur_tick + (long long)wrapcount_copy * (long long)WRAP_TICKS;
#endif
result->tv_sec = (time_t)(tickcount / tick_hz);
result->tv_nsec = (long) (((tickcount % tick_hz) * 1000000000LL) / tick_hz);
#endif
#if defined(RV_OS_PSOS)
tm_getticks(&tickshi, &tickslo);
tickcount = (long long)tickshi * (long long)ULONG_MAX + (long long)tickshi + (long long)tickslo;
result->tv_sec = (time_t)(tickcount / tick_hz);
result->tv_nsec = (long) (((tickcount % tick_hz) * 1000000000LL) / tick_hz);
#endif
#if defined(RV_OS_OSE)
hrtime = rvTimeGetHrtime(); /* keep logic in one place */
result->tv_sec = (long)(hrtime / 1000000000LL);
result->tv_nsec = (long)(hrtime % 1000000000LL);
#endif
#if defined(RV_OS_NUCLEUS)
/* Clock tick is only 32 bits, check for wrap without locking */
do {
lasttick_copy1 = last_tick;
wrapcount_copy = wrap_count;
lasttick_copy2 = last_tick;
} while (lasttick_copy1 != lasttick_copy2); /* max 2 loops */
cur_tick = NU_Retrieve_Clock();
if(cur_tick < lasttick_copy1)
wrapcount_copy += 1;
tickcount = (long long)cur_tick + (long long)wrapcount_copy * (long long)WRAP_TICKS;
result->tv_sec = (time_t)(tickcount / tick_hz);
result->tv_nsec = (long) (((tickcount % tick_hz) * 1000000000LL) / tick_hz);
#endif
return result;
}
/* Create a timespec from base information */
RvTimespec *rvTimespecCreate(RvTimespec *t, RvTime secs, long nanosecs)
{
if(t == NULL) return NULL;
t->tv_sec = secs;
t->tv_nsec = nanosecs;
return t;
}
/* Get a high resolution relative time stamp. This value will never */
/* go backwards. This value will is in nanoseconds and will never wrap */
/* (at least for about 290 years). */
RvHrtime rvTimeGetHrtime(void)
{
#if defined(RV_OS_SOLARIS)
return gethrtime();
#endif
#if defined(RV_OS_REDHAT) || defined(RV_OS_TRU64) || defined(RV_OS_HPUX) || defined(RV_OS_WIN32) || defined(RV_OS_VXWORKS) || defined(RV_OS_PSOS) || defined(RV_OS_NUCLEUS)
RvHrtime nanosecs;
RvTimespec hrtimer;
/* Not real efficient, but there's no easy way to retain resolution */
rvTimeGetHires(&hrtimer);
nanosecs = rvTimeConvertHrtime(&hrtimer);
return nanosecs;
#endif
#if defined(RV_OS_OSE)
long wrapcount_copy;
long long hrtime, tickcount;
OSTICK micro, cur_tick, lasttick_copy1, lasttick_copy2;
/* Clock tick is only 32 bits, check for wrap without locking */
do {
lasttick_copy1 = last_tick;
wrapcount_copy = wrap_count;
lasttick_copy2 = last_tick;
} while (lasttick_copy1 != lasttick_copy2); /* max 2 loops */
cur_tick = get_systime(µ);
if(cur_tick < lasttick_copy1)
wrapcount_copy += 1;
tickcount = (long long)cur_tick + (long long)wrapcount_copy * (long long)WRAP_TICKS;
hrtime = tickcount * tick_period + ((long long)micro * 1000LL);
return hrtime;
#endif
}
/* Returns resolution of high resolution time in seconds and nanoseconds. */
RvTimespec *rvTimeGetHrtimeRes(RvTimespec *result)
{
if(result == NULL) return NULL;
#if defined(RV_OS_SOLARIS)
#if defined(CLOCK_HIGHRES) /* If CLOCK_HIGHRES isn't defined, then it is pre Solaris 8 */
clock_getres(CLOCK_HIGHRES, result);
#else
/* Solaris 2.6 and 7 don't have a way to find the resolution of the
* hires timer. The wall clock resolution will be no worse, so its
* the best we can do. */
clock_getres(CLOCK_REALTIME, result);
#endif
#endif
#if defined(RV_OS_TRU64) || defined(RV_OS_HPUX)
clock_getres(CLOCK_REALTIME, result);
#endif
#if defined(RV_OS_REDHAT) || defined(RV_OS_VXWORKS) || defined(RV_OS_PSOS) || defined(RV_OS_NUCLEUS)
if(tick_hz > 1LL) {
result->tv_sec = 0L;
result->tv_nsec = (long)(1000000000LL / tick_hz);
} else {
result->tv_sec = 1L;
result->tv_nsec = 0L;
}
#endif
#if defined(RV_OS_WIN32)
if(tick_hz > 1i64) {
result->tv_sec = 0L;
result->tv_nsec = (long)(1000000000i64 / tick_hz);
} else {
result->tv_sec = 1L;
result->tv_nsec = 0L;
}
#endif
#if defined(RV_OS_OSE)
/* OSE never tells us the sub-tick resolution so return ticks */
result->tv_sec = (long)(tick_period / 1000000000LL);
result->tv_nsec = (long)(tick_period % 1000000000LL);
#endif
return result;
}
/* Create NTP time from base information */
RvNtpTime *rvNtpTimeCreate(RvNtpTime *ntime, unsigned long secs, unsigned long fraction)
{
if(ntime == NULL) return NULL;
ntime->secs = secs;
ntime->fraction = fraction;
return ntime;
}
/* Convert a rvTimespec time to a Rvtime time. Basically it just */
/* drops the nanoseconds information. */
#if !defined(rvTimeConvertsecs) /* only use if no macro version */
RvTime rvTimeConvertsecs(RvTimespec *t)
{
return t->tv_sec;
}
#endif
/* Convert a rvTimespec time to a rvHrtime time. If called with */
/* wall clock time information, the result will be total number */
/* of nanoseconds since epoch. */
RvHrtime rvTimeConvertHrtime(const RvTimespec *t)
{
return (RvHrtime)(((RvHrtime)t->tv_sec * (RvHrtime)1000000000) + (RvHrtime)t->tv_nsec);
}
/* Convert rvTimespec to NTP time. The two formats do not have */
/* the exact same resolution so there can be some round-off error. */
/* Absolute times are calander times that need to have the difference */
/* in epochs dealt with. Note that timespec time can end up negative */
/* since NTP time epoch is earlier. */
RvNtpTime *rvTimeConvertNTP(const RvTimespec *tp, RvNtpTime *ntime, RvBool relative)
{
if((ntime == NULL) || (tp == NULL)) return NULL;
ntime->secs = (unsigned long)rvTimespecSecs(tp);
if(relative == RV_NTP_TIME_ABSOLUTE)
ntime->secs += NTPDELTA;
/* Convert nanosecs to NTP fraction. Uses 64 bit math to maintain */
/* resolution but Windows has to be special. */
#if defined(RV_OS_WIN32)
ntime->fraction = (unsigned long)(((ULONGLONG)tp->tv_nsec * 0x100000000Ui64) / 1000000000Ui64);
#else
ntime->fraction = (unsigned long)(((unsigned long long)tp->tv_nsec * 0x100000000ULL) / 1000000000ULL);
#endif
return ntime;
}
/* Covert NTP time back to standard timespec. The two formats do */
/* not have the exact same resolution so there can be some round-off */
/* error. Absolute times are calander times that need to have the */
/* difference in epochs dealt with. */
RvTimespec *rvNtpTimeConvert(const RvNtpTime *ntime, RvTimespec *tp, RvBool relative)
{
if((ntime == NULL) || (tp == NULL)) return NULL;
if(relative == RV_NTP_TIME_ABSOLUTE) {
tp->tv_sec = (long)(ntime->secs - NTPDELTA);
} else tp->tv_sec = (long)(ntime->secs);
/* Convert NTP fraction back to nanosecs. Uses 64 bit math to */
/* maintain resolution but Windows has to be special. */
#if defined(RV_OS_WIN32)
tp->tv_nsec = (long)(((ULONGLONG)ntime->fraction * 1000000000Ui64) / 0x100000000Ui64);
#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -