1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2001-2009 Oracle. All rights reserved. 5 * 6 * $Id$ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12 13/* 14 * __os_gettime -- 15 * Return the current time-of-day clock in seconds and nanoseconds. 16 */ 17void 18__os_gettime(env, tp, monotonic) 19 ENV *env; 20 db_timespec *tp; 21 int monotonic; 22{ 23 if (monotonic) { 24 /* 25 * The elapsed time is stored as a DWORD value, so time wraps 26 * around to zero if the system runs for 49.7 days. Initialize 27 * a base value with 50 days worth of seconds, and add 50 more 28 * days every time the counter wraps. That ensures we always 29 * move forward. 30 * 31 * It's possible this code could race, but the danger is we 32 * would increment base_seconds more than once per wrap and 33 * eventually overflow, which is a pretty remote possibility. 34 */ 35#define TIMER_WRAP_SECONDS (50 * 24 * 60 * 60) 36 static DWORD last_ticks; 37 static time_t base_seconds; 38 DWORD ticks; 39 40 ticks = GetTickCount(); 41 if (ticks < last_ticks) 42 base_seconds += TIMER_WRAP_SECONDS; 43 last_ticks = ticks; 44 tp->tv_sec = base_seconds + (u_int32_t)(ticks / 1000); 45 tp->tv_nsec = (u_int32_t)((ticks % 1000) * NS_PER_MS); 46 } else { 47#ifdef DB_WINCE 48 FILETIME ft; 49 LARGE_INTEGER large_int; 50 LONGLONG ns_since_epoch, utc1970; 51 SYSTEMTIME st; 52 53 (void)GetSystemTime(&st); 54 (void)SystemTimeToFileTime(&st, &ft); 55 56 /* 57 * A FILETIME expresses time as 100 nanosecond chunks from 58 * Jan 1, 1601; convert to a timespec where the time is 59 * is expressed in seconds and nanoseconds from Jan 1, 1970. 60 * 61 * UTC_1970 is the number of 100-nano-second chunks from 62 * 1601 to 1970. 63 */ 64#define NS100_PER_SEC (NS_PER_SEC / 100) 65#define UTC_1970 (((LONGLONG)27111902 << 32) + (LONGLONG)3577643008) 66 memcpy(&large_int, &ft, sizeof(large_int)); 67 utc1970 = UTC_1970; 68 ns_since_epoch = (large_int.QuadPart - utc1970); 69 tp->tv_sec = (time_t)(ns_since_epoch / NS100_PER_SEC); 70 tp->tv_nsec = (long)(ns_since_epoch % NS100_PER_SEC); 71#else 72 struct _timeb now; 73 74 _ftime(&now); 75 tp->tv_sec = now.time; 76 tp->tv_nsec = now.millitm * NS_PER_MS; 77#endif 78 } 79} 80