1
/* $Id: time-win32.cpp 4071 2007-08-07 17:07:59Z vboxsync $ */
3
* innotek Portable Runtime - Time, win32.
7
* Copyright (C) 2006-2007 innotek GmbH
9
* This file is part of VirtualBox Open Source Edition (OSE), as
10
* available from http://www.virtualbox.org. This file is free software;
11
* you can redistribute it and/or modify it under the terms of the GNU
12
* General Public License as published by the Free Software Foundation,
13
* in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14
* distribution. VirtualBox OSE is distributed in the hope that it will
15
* be useful, but WITHOUT ANY WARRANTY of any kind.
19
/*******************************************************************************
21
*******************************************************************************/
22
#define LOG_GROUP RTLOGGROUP_TIME
23
//#define USE_TICK_COUNT
24
//#define USE_PERFORMANCE_COUNTER
26
//#define USE_INTERRUPT_TIME
27
#ifndef USE_INTERRUPT_TIME
38
#include <iprt/time.h>
40
#include <iprt/assert.h>
41
#include "internal/time.h"
44
DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
46
#if defined USE_TICK_COUNT
47
return (uint64_t)GetTickCount() * (uint64_t)1000000;
49
#elif defined USE_PERFORMANCE_COUNTER
50
static LARGE_INTEGER llFreq;
51
static unsigned uMult;
54
if (!QueryPerformanceFrequency(&llFreq))
55
return (uint64_t)GetTickCount() * (uint64_t)1000000;
56
llFreq.QuadPart /= 1000;
57
uMult = 1000000; /* no math genious, but this seemed to help avoiding floating point. */
61
if (QueryPerformanceCounter(&ll))
62
return (ll.QuadPart * uMult) / llFreq.QuadPart;
64
return (uint64_t)GetTickCount() * (uint64_t)1000000;
66
#elif defined USE_FILE_TIME
67
uint64_t u64; /* manual say larger integer, should be safe to assume it's the same. */
68
GetSystemTimeAsFileTime((LPFILETIME)&u64);
71
#elif defined USE_INTERRUPT_TIME
73
/* HACK! HACK! HACK! HACK! HACK! HACK! */
74
/* HACK! HACK! HACK! HACK! HACK! HACK! */
75
/* HACK! HACK! HACK! HACK! HACK! HACK! */
76
# error "don't use this in production"
78
static const KUSER_SHARED_DATA *s_pUserSharedData = NULL;
79
if (!s_pUserSharedData)
81
/** @todo clever detection algorithm.
82
* The com debugger class exports this too, windbg knows it too... */
83
s_pUserSharedData = (const KUSER_SHARED_DATA *)0x7ffe0000;
86
/* use interrupt time */
90
Time.HighPart = s_pUserSharedData->InterruptTime.High1Time;
91
Time.LowPart = s_pUserSharedData->InterruptTime.LowPart;
92
} while (s_pUserSharedData->InterruptTime.High2Time != Time.HighPart);
94
return (uint64_t)Time.QuadPart * 100;
97
# error "Must select a method bright guy!"
103
* Gets the current nanosecond timestamp.
105
* This differs from RTTimeNanoTS in that it will use system APIs and not do any
106
* resolution or performance optimizations.
108
* @returns nanosecond timestamp.
110
RTDECL(uint64_t) RTTimeSystemNanoTS(void)
112
return rtTimeGetSystemNanoTS();
117
* Gets the current millisecond timestamp.
119
* This differs from RTTimeNanoTS in that it will use system APIs and not do any
120
* resolution or performance optimizations.
122
* @returns millisecond timestamp.
124
RTDECL(uint64_t) RTTimeSystemMilliTS(void)
126
return rtTimeGetSystemNanoTS();
131
* Gets the current system time.
134
* @param pTime Where to store the time.
136
RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
139
AssertCompile(sizeof(u64) == sizeof(FILETIME));
140
GetSystemTimeAsFileTime((LPFILETIME)&u64);
141
return RTTimeSpecSetNtTime(pTime, u64);
146
* Gets the current local system time.
149
* @param pTime Where to store the local time.
151
RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime)
154
AssertCompile(sizeof(u64) == sizeof(FILETIME));
155
GetSystemTimeAsFileTime((LPFILETIME)&u64);
157
if (!FileTimeToLocalFileTime((FILETIME const *)&u64, (LPFILETIME)&u64Local))
159
return RTTimeSpecSetNtTime(pTime, u64Local);
164
* Gets the delta between UTC and local time.
167
* RTTIMESPEC LocalTime;
168
* RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
171
* @returns Returns the nanosecond delta between UTC and local time.
173
RTDECL(int64_t) RTTimeLocalDeltaNano(void)
176
* UTC = local + Tzi.Bias;
177
* The bias is given in minutes.
179
TIME_ZONE_INFORMATION Tzi;
181
if (GetTimeZoneInformation(&Tzi) != TIME_ZONE_ID_INVALID)
182
return -(int64_t)Tzi.Bias * 60*1000*1000*1000;
188
* Explodes a time spec to the localized timezone.
191
* @param pTime Where to store the exploded time.
192
* @param pTimeSpec The time spec to exploded. (UTC)
194
RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec)
197
* FileTimeToLocalFileTime does not do the right thing, so we'll have
198
* to convert to system time and SystemTimeToTzSpecificLocalTime instead.
200
RTTIMESPEC LocalTime;
201
SYSTEMTIME SystemTimeIn;
203
if (FileTimeToSystemTime(RTTimeSpecGetNtFileTime(pTimeSpec, &FileTime), &SystemTimeIn))
205
SYSTEMTIME SystemTimeOut;
206
if (SystemTimeToTzSpecificLocalTime(NULL /* use current TZI */,
210
if (SystemTimeToFileTime(&SystemTimeOut, &FileTime))
212
RTTimeSpecSetNtFileTime(&LocalTime, &FileTime);
213
pTime = RTTimeExplode(pTime, &LocalTime);
215
pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL;
222
* The fallback is to use the current offset.
223
* (A better fallback would be to use the offset of the same time of the year.)
225
LocalTime = *pTimeSpec;
226
RTTimeSpecAddNano(&LocalTime, RTTimeLocalDeltaNano());
227
pTime = RTTimeExplode(pTime, &LocalTime);
229
pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL;