VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win32/time-win32.cpp@ 4014

Last change on this file since 4014 was 2981, checked in by vboxsync, 17 years ago

InnoTek -> innotek: all the headers and comments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.7 KB
Line 
1/* $Id: time-win32.cpp 2981 2007-06-01 16:01:28Z vboxsync $ */
2/** @file
3 * innotek Portable Runtime - Time, win32.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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 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.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP RTLOGGROUP_TIME
27//#define USE_TICK_COUNT
28//#define USE_PERFORMANCE_COUNTER
29#define USE_FILE_TIME
30//#define USE_INTERRUPT_TIME
31#ifndef USE_INTERRUPT_TIME
32# include <Windows.h>
33#else
34# define _X86_
35 extern "C" {
36# include <ntddk.h>
37 }
38# undef PAGE_SIZE
39# undef PAGE_SHIFT
40#endif
41
42#include <iprt/time.h>
43#include <iprt/asm.h>
44#include <iprt/assert.h>
45#include "internal/time.h"
46
47
48DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
49{
50#if defined USE_TICK_COUNT
51 return (uint64_t)GetTickCount() * (uint64_t)1000000;
52
53#elif defined USE_PERFORMANCE_COUNTER
54 static LARGE_INTEGER llFreq;
55 static unsigned uMult;
56 if (!llFreq.QuadPart)
57 {
58 if (!QueryPerformanceFrequency(&llFreq))
59 return (uint64_t)GetTickCount() * (uint64_t)1000000;
60 llFreq.QuadPart /= 1000;
61 uMult = 1000000; /* no math genious, but this seemed to help avoiding floating point. */
62 }
63
64 LARGE_INTEGER ll;
65 if (QueryPerformanceCounter(&ll))
66 return (ll.QuadPart * uMult) / llFreq.QuadPart;
67 else
68 return (uint64_t)GetTickCount() * (uint64_t)1000000;
69
70#elif defined USE_FILE_TIME
71 uint64_t u64; /* manual say larger integer, should be safe to assume it's the same. */
72 GetSystemTimeAsFileTime((LPFILETIME)&u64);
73 return u64 * 100;
74
75#elif defined USE_INTERRUPT_TIME
76
77 /* HACK! HACK! HACK! HACK! HACK! HACK! */
78 /* HACK! HACK! HACK! HACK! HACK! HACK! */
79 /* HACK! HACK! HACK! HACK! HACK! HACK! */
80# error "don't use this in production"
81
82 static const KUSER_SHARED_DATA *s_pUserSharedData = NULL;
83 if (!s_pUserSharedData)
84 {
85 /** @todo clever detection algorithm.
86 * The com debugger class exports this too, windbg knows it too... */
87 s_pUserSharedData = (const KUSER_SHARED_DATA *)0x7ffe0000;
88 }
89
90 /* use interrupt time */
91 LARGE_INTEGER Time;
92 do
93 {
94 Time.HighPart = s_pUserSharedData->InterruptTime.High1Time;
95 Time.LowPart = s_pUserSharedData->InterruptTime.LowPart;
96 } while (s_pUserSharedData->InterruptTime.High2Time != Time.HighPart);
97
98 return (uint64_t)Time.QuadPart * 100;
99
100#else
101# error "Must select a method bright guy!"
102#endif
103}
104
105
106/**
107 * Gets the current nanosecond timestamp.
108 *
109 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
110 * resolution or performance optimizations.
111 *
112 * @returns nanosecond timestamp.
113 */
114RTDECL(uint64_t) RTTimeSystemNanoTS(void)
115{
116 return rtTimeGetSystemNanoTS();
117}
118
119
120/**
121 * Gets the current millisecond timestamp.
122 *
123 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
124 * resolution or performance optimizations.
125 *
126 * @returns millisecond timestamp.
127 */
128RTDECL(uint64_t) RTTimeSystemMilliTS(void)
129{
130 return rtTimeGetSystemNanoTS();
131}
132
133
134/**
135 * Gets the current system time.
136 *
137 * @returns pTime.
138 * @param pTime Where to store the time.
139 */
140RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
141{
142 uint64_t u64;
143 AssertCompile(sizeof(u64) == sizeof(FILETIME));
144 GetSystemTimeAsFileTime((LPFILETIME)&u64);
145 return RTTimeSpecSetNtTime(pTime, u64);
146}
147
148
149/**
150 * Gets the current local system time.
151 *
152 * @returns pTime.
153 * @param pTime Where to store the local time.
154 */
155RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime)
156{
157 uint64_t u64;
158 AssertCompile(sizeof(u64) == sizeof(FILETIME));
159 GetSystemTimeAsFileTime((LPFILETIME)&u64);
160 uint64_t u64Local;
161 if (!FileTimeToLocalFileTime((FILETIME const *)&u64, (LPFILETIME)&u64Local))
162 u64Local = u64;
163 return RTTimeSpecSetNtTime(pTime, u64Local);
164}
165
166
167/**
168 * Gets the delta between UTC and local time.
169 *
170 * @code
171 * RTTIMESPEC LocalTime;
172 * RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
173 * @endcode
174 *
175 * @returns Returns the nanosecond delta between UTC and local time.
176 */
177RTDECL(int64_t) RTTimeLocalDeltaNano(void)
178{
179 /*
180 * UTC = local + Tzi.Bias;
181 * The bias is given in minutes.
182 */
183 TIME_ZONE_INFORMATION Tzi;
184 Tzi.Bias = 0;
185 if (GetTimeZoneInformation(&Tzi) != TIME_ZONE_ID_INVALID)
186 return -(int64_t)Tzi.Bias * 60*1000*1000*1000;
187 return 0;
188}
189
190
191/**
192 * Explodes a time spec to the localized timezone.
193 *
194 * @returns pTime.
195 * @param pTime Where to store the exploded time.
196 * @param pTimeSpec The time spec to exploded. (UTC)
197 */
198RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec)
199{
200 /*
201 * FileTimeToLocalFileTime does not do the right thing, so we'll have
202 * to convert to system time and SystemTimeToTzSpecificLocalTime instead.
203 */
204 RTTIMESPEC LocalTime;
205 SYSTEMTIME SystemTimeIn;
206 FILETIME FileTime;
207 if (FileTimeToSystemTime(RTTimeSpecGetNtFileTime(pTimeSpec, &FileTime), &SystemTimeIn))
208 {
209 SYSTEMTIME SystemTimeOut;
210 if (SystemTimeToTzSpecificLocalTime(NULL /* use current TZI */,
211 &SystemTimeIn,
212 &SystemTimeOut))
213 {
214 if (SystemTimeToFileTime(&SystemTimeOut, &FileTime))
215 {
216 RTTimeSpecSetNtFileTime(&LocalTime, &FileTime);
217 pTime = RTTimeExplode(pTime, &LocalTime);
218 if (pTime)
219 pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL;
220 return pTime;
221 }
222 }
223 }
224
225 /*
226 * The fallback is to use the current offset.
227 * (A better fallback would be to use the offset of the same time of the year.)
228 */
229 LocalTime = *pTimeSpec;
230 RTTimeSpecAddNano(&LocalTime, RTTimeLocalDeltaNano());
231 pTime = RTTimeExplode(pTime, &LocalTime);
232 if (pTime)
233 pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL;
234 return pTime;
235}
236
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