/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2001,2008 Oracle. All rights reserved. * * $Id: os_clock.c,v 12.18 2008/05/07 12:27:35 bschmeck Exp $ */ #include "db_config.h" #include "db_int.h" /* * __os_gettime -- * Return the current time-of-day clock in seconds and nanoseconds. */ void __os_gettime(env, tp, monotonic) ENV *env; db_timespec *tp; int monotonic; { if (monotonic) { /* * The elapsed time is stored as a DWORD value, so time wraps * around to zero if the system runs for 49.7 days. Initialize * a base value with 50 days worth of seconds, and add 50 more * days every time the counter wraps. That ensures we always * move forward. * * It's possible this code could race, but the danger is we * would increment base_seconds more than once per wrap and * eventually overflow, which is a pretty remote possibility. */ #define TIMER_WRAP_SECONDS (50 * 24 * 60 * 60) static DWORD last_ticks; static time_t base_seconds; DWORD ticks; ticks = GetTickCount(); if (ticks < last_ticks) base_seconds += TIMER_WRAP_SECONDS; last_ticks = ticks; tp->tv_sec = base_seconds + (u_int32_t)(ticks / 1000); tp->tv_nsec = (u_int32_t)((ticks % 1000) * NS_PER_MS); } else { #ifdef DB_WINCE FILETIME ft; LARGE_INTEGER large_int; LONGLONG ns_since_epoch, utc1970; SYSTEMTIME st; (void)GetSystemTime(&st); (void)SystemTimeToFileTime(&st, &ft); /* * A FILETIME expresses time as 100 nanosecond chunks from * Jan 1, 1601; convert to a timespec where the time is * is expressed in seconds and nanoseconds from Jan 1, 1970. * * UTC_1970 is the number of 100-nano-second chunks from * 1601 to 1970. */ #define NS100_PER_SEC (NS_PER_SEC / 100) #define UTC_1970 (((LONGLONG)27111902 << 32) + (LONGLONG)3577643008) memcpy(&large_int, &ft, sizeof(large_int)); utc1970 = UTC_1970; ns_since_epoch = (large_int.QuadPart - utc1970); tp->tv_sec = (time_t)(ns_since_epoch / NS100_PER_SEC); tp->tv_nsec = (long)(ns_since_epoch % NS100_PER_SEC); #else struct _timeb now; _ftime(&now); tp->tv_sec = now.time; tp->tv_nsec = now.millitm * NS_PER_MS; #endif } }