VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win/time-win.cpp@ 8256

Last change on this file since 8256 was 8245, checked in by vboxsync, 17 years ago

rebranding: IPRT files again.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.7 KB
Line 
1/* $Id: time-win.cpp 8245 2008-04-21 17:24:28Z vboxsync $ */
2/** @file
3 * IPRT - Time, win32.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
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 (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#define LOG_GROUP RTLOGGROUP_TIME
36#include <Windows.h>
37
38#include <iprt/time.h>
39#include <iprt/asm.h>
40#include <iprt/assert.h>
41#include "internal/time.h"
42
43#define USE_TICK_COUNT
44//#define USE_PERFORMANCE_COUNTER
45#if 0//defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
46# define USE_INTERRUPT_TIME
47#else
48//# define USE_FILE_TIME
49#endif
50
51
52#ifdef USE_INTERRUPT_TIME
53
54typedef struct _MY_KSYSTEM_TIME
55{
56 ULONG LowPart;
57 LONG High1Time;
58 LONG High2Time;
59} MY_KSYSTEM_TIME;
60
61typedef struct _MY_KUSER_SHARED_DATA
62{
63 ULONG TickCountLowDeprecated;
64 ULONG TickCountMultiplier;
65 volatile MY_KSYSTEM_TIME InterruptTime;
66 /* The rest is not relevant. */
67} MY_KUSER_SHARED_DATA, *PMY_KUSER_SHARED_DATA;
68
69#endif /* USE_INTERRUPT_TIME */
70
71
72DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
73{
74#if defined USE_TICK_COUNT
75 /*
76 * This would work if it didn't flip over every 49 (or so) days.
77 */
78 return (uint64_t)GetTickCount() * (uint64_t)1000000;
79
80#elif defined USE_PERFORMANCE_COUNTER
81 /*
82 * Slow and no derived from InterruptTime.
83 */
84 static LARGE_INTEGER llFreq;
85 static unsigned uMult;
86 if (!llFreq.QuadPart)
87 {
88 if (!QueryPerformanceFrequency(&llFreq))
89 return (uint64_t)GetTickCount() * (uint64_t)1000000;
90 llFreq.QuadPart /= 1000;
91 uMult = 1000000; /* no math genius, but this seemed to help avoiding floating point. */
92 }
93
94 LARGE_INTEGER ll;
95 if (QueryPerformanceCounter(&ll))
96 return (ll.QuadPart * uMult) / llFreq.QuadPart;
97 else
98 return (uint64_t)GetTickCount() * (uint64_t)1000000;
99
100#elif defined USE_FILE_TIME
101 /*
102 * This is SystemTime not InterruptTime.
103 */
104 uint64_t u64; /* manual say larger integer, should be safe to assume it's the same. */
105 GetSystemTimeAsFileTime((LPFILETIME)&u64);
106 return u64 * 100;
107
108#elif defined USE_INTERRUPT_TIME
109 /*
110 * This is exactly what we want, but we have to obtain it by non-official
111 * means.
112 */
113 static MY_KUSER_SHARED_DATA *s_pUserSharedData = NULL;
114 if (!s_pUserSharedData)
115 {
116 /** @todo find official way of getting this or some more clever
117 * detection algorithm if necessary. The com debugger class
118 * exports this too, windbg knows it too... */
119 s_pUserSharedData = (MY_ KUSER_SHARED_DATA *)(uintptr_t)0x7ffe0000;
120 }
121
122 /* use interrupt time */
123 LARGE_INTEGER Time;
124 do
125 {
126 Time.HighPart = s_pUserSharedData->InterruptTime.High1Time;
127 Time.LowPart = s_pUserSharedData->InterruptTime.LowPart;
128 } while (s_pUserSharedData->InterruptTime.High2Time != Time.HighPart);
129
130 return (uint64_t)Time.QuadPart * 100;
131
132#else
133# error "Must select a method bright guy!"
134#endif
135}
136
137
138/**
139 * Gets the current nanosecond timestamp.
140 *
141 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
142 * resolution or performance optimizations.
143 *
144 * @returns nanosecond timestamp.
145 */
146RTDECL(uint64_t) RTTimeSystemNanoTS(void)
147{
148 return rtTimeGetSystemNanoTS();
149}
150
151
152/**
153 * Gets the current millisecond timestamp.
154 *
155 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
156 * resolution or performance optimizations.
157 *
158 * @returns millisecond timestamp.
159 */
160RTDECL(uint64_t) RTTimeSystemMilliTS(void)
161{
162 return rtTimeGetSystemNanoTS();
163}
164
165
166/**
167 * Gets the current system time.
168 *
169 * @returns pTime.
170 * @param pTime Where to store the time.
171 */
172RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
173{
174 uint64_t u64;
175 AssertCompile(sizeof(u64) == sizeof(FILETIME));
176 GetSystemTimeAsFileTime((LPFILETIME)&u64);
177 return RTTimeSpecSetNtTime(pTime, u64);
178}
179
180
181/**
182 * Gets the current local system time.
183 *
184 * @returns pTime.
185 * @param pTime Where to store the local time.
186 */
187RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime)
188{
189 uint64_t u64;
190 AssertCompile(sizeof(u64) == sizeof(FILETIME));
191 GetSystemTimeAsFileTime((LPFILETIME)&u64);
192 uint64_t u64Local;
193 if (!FileTimeToLocalFileTime((FILETIME const *)&u64, (LPFILETIME)&u64Local))
194 u64Local = u64;
195 return RTTimeSpecSetNtTime(pTime, u64Local);
196}
197
198
199/**
200 * Gets the delta between UTC and local time.
201 *
202 * @code
203 * RTTIMESPEC LocalTime;
204 * RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
205 * @endcode
206 *
207 * @returns Returns the nanosecond delta between UTC and local time.
208 */
209RTDECL(int64_t) RTTimeLocalDeltaNano(void)
210{
211 /*
212 * UTC = local + Tzi.Bias;
213 * The bias is given in minutes.
214 */
215 TIME_ZONE_INFORMATION Tzi;
216 Tzi.Bias = 0;
217 if (GetTimeZoneInformation(&Tzi) != TIME_ZONE_ID_INVALID)
218 return -(int64_t)Tzi.Bias * 60*1000*1000*1000;
219 return 0;
220}
221
222
223/**
224 * Explodes a time spec to the localized timezone.
225 *
226 * @returns pTime.
227 * @param pTime Where to store the exploded time.
228 * @param pTimeSpec The time spec to exploded. (UTC)
229 */
230RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec)
231{
232 /*
233 * FileTimeToLocalFileTime does not do the right thing, so we'll have
234 * to convert to system time and SystemTimeToTzSpecificLocalTime instead.
235 */
236 RTTIMESPEC LocalTime;
237 SYSTEMTIME SystemTimeIn;
238 FILETIME FileTime;
239 if (FileTimeToSystemTime(RTTimeSpecGetNtFileTime(pTimeSpec, &FileTime), &SystemTimeIn))
240 {
241 SYSTEMTIME SystemTimeOut;
242 if (SystemTimeToTzSpecificLocalTime(NULL /* use current TZI */,
243 &SystemTimeIn,
244 &SystemTimeOut))
245 {
246 if (SystemTimeToFileTime(&SystemTimeOut, &FileTime))
247 {
248 RTTimeSpecSetNtFileTime(&LocalTime, &FileTime);
249 pTime = RTTimeExplode(pTime, &LocalTime);
250 if (pTime)
251 pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL;
252 return pTime;
253 }
254 }
255 }
256
257 /*
258 * The fallback is to use the current offset.
259 * (A better fallback would be to use the offset of the same time of the year.)
260 */
261 LocalTime = *pTimeSpec;
262 RTTimeSpecAddNano(&LocalTime, RTTimeLocalDeltaNano());
263 pTime = RTTimeExplode(pTime, &LocalTime);
264 if (pTime)
265 pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL;
266 return pTime;
267}
268
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette