VirtualBox

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

Last change on this file since 4729 was 4071, checked in by vboxsync, 18 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.5 KB
Line 
1/* $Id: time-win32.cpp 4071 2007-08-07 17:07:59Z 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
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP RTLOGGROUP_TIME
23//#define USE_TICK_COUNT
24//#define USE_PERFORMANCE_COUNTER
25#define USE_FILE_TIME
26//#define USE_INTERRUPT_TIME
27#ifndef USE_INTERRUPT_TIME
28# include <Windows.h>
29#else
30# define _X86_
31 extern "C" {
32# include <ntddk.h>
33 }
34# undef PAGE_SIZE
35# undef PAGE_SHIFT
36#endif
37
38#include <iprt/time.h>
39#include <iprt/asm.h>
40#include <iprt/assert.h>
41#include "internal/time.h"
42
43
44DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
45{
46#if defined USE_TICK_COUNT
47 return (uint64_t)GetTickCount() * (uint64_t)1000000;
48
49#elif defined USE_PERFORMANCE_COUNTER
50 static LARGE_INTEGER llFreq;
51 static unsigned uMult;
52 if (!llFreq.QuadPart)
53 {
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. */
58 }
59
60 LARGE_INTEGER ll;
61 if (QueryPerformanceCounter(&ll))
62 return (ll.QuadPart * uMult) / llFreq.QuadPart;
63 else
64 return (uint64_t)GetTickCount() * (uint64_t)1000000;
65
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);
69 return u64 * 100;
70
71#elif defined USE_INTERRUPT_TIME
72
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"
77
78 static const KUSER_SHARED_DATA *s_pUserSharedData = NULL;
79 if (!s_pUserSharedData)
80 {
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;
84 }
85
86 /* use interrupt time */
87 LARGE_INTEGER Time;
88 do
89 {
90 Time.HighPart = s_pUserSharedData->InterruptTime.High1Time;
91 Time.LowPart = s_pUserSharedData->InterruptTime.LowPart;
92 } while (s_pUserSharedData->InterruptTime.High2Time != Time.HighPart);
93
94 return (uint64_t)Time.QuadPart * 100;
95
96#else
97# error "Must select a method bright guy!"
98#endif
99}
100
101
102/**
103 * Gets the current nanosecond timestamp.
104 *
105 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
106 * resolution or performance optimizations.
107 *
108 * @returns nanosecond timestamp.
109 */
110RTDECL(uint64_t) RTTimeSystemNanoTS(void)
111{
112 return rtTimeGetSystemNanoTS();
113}
114
115
116/**
117 * Gets the current millisecond timestamp.
118 *
119 * This differs from RTTimeNanoTS in that it will use system APIs and not do any
120 * resolution or performance optimizations.
121 *
122 * @returns millisecond timestamp.
123 */
124RTDECL(uint64_t) RTTimeSystemMilliTS(void)
125{
126 return rtTimeGetSystemNanoTS();
127}
128
129
130/**
131 * Gets the current system time.
132 *
133 * @returns pTime.
134 * @param pTime Where to store the time.
135 */
136RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
137{
138 uint64_t u64;
139 AssertCompile(sizeof(u64) == sizeof(FILETIME));
140 GetSystemTimeAsFileTime((LPFILETIME)&u64);
141 return RTTimeSpecSetNtTime(pTime, u64);
142}
143
144
145/**
146 * Gets the current local system time.
147 *
148 * @returns pTime.
149 * @param pTime Where to store the local time.
150 */
151RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime)
152{
153 uint64_t u64;
154 AssertCompile(sizeof(u64) == sizeof(FILETIME));
155 GetSystemTimeAsFileTime((LPFILETIME)&u64);
156 uint64_t u64Local;
157 if (!FileTimeToLocalFileTime((FILETIME const *)&u64, (LPFILETIME)&u64Local))
158 u64Local = u64;
159 return RTTimeSpecSetNtTime(pTime, u64Local);
160}
161
162
163/**
164 * Gets the delta between UTC and local time.
165 *
166 * @code
167 * RTTIMESPEC LocalTime;
168 * RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
169 * @endcode
170 *
171 * @returns Returns the nanosecond delta between UTC and local time.
172 */
173RTDECL(int64_t) RTTimeLocalDeltaNano(void)
174{
175 /*
176 * UTC = local + Tzi.Bias;
177 * The bias is given in minutes.
178 */
179 TIME_ZONE_INFORMATION Tzi;
180 Tzi.Bias = 0;
181 if (GetTimeZoneInformation(&Tzi) != TIME_ZONE_ID_INVALID)
182 return -(int64_t)Tzi.Bias * 60*1000*1000*1000;
183 return 0;
184}
185
186
187/**
188 * Explodes a time spec to the localized timezone.
189 *
190 * @returns pTime.
191 * @param pTime Where to store the exploded time.
192 * @param pTimeSpec The time spec to exploded. (UTC)
193 */
194RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec)
195{
196 /*
197 * FileTimeToLocalFileTime does not do the right thing, so we'll have
198 * to convert to system time and SystemTimeToTzSpecificLocalTime instead.
199 */
200 RTTIMESPEC LocalTime;
201 SYSTEMTIME SystemTimeIn;
202 FILETIME FileTime;
203 if (FileTimeToSystemTime(RTTimeSpecGetNtFileTime(pTimeSpec, &FileTime), &SystemTimeIn))
204 {
205 SYSTEMTIME SystemTimeOut;
206 if (SystemTimeToTzSpecificLocalTime(NULL /* use current TZI */,
207 &SystemTimeIn,
208 &SystemTimeOut))
209 {
210 if (SystemTimeToFileTime(&SystemTimeOut, &FileTime))
211 {
212 RTTimeSpecSetNtFileTime(&LocalTime, &FileTime);
213 pTime = RTTimeExplode(pTime, &LocalTime);
214 if (pTime)
215 pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL;
216 return pTime;
217 }
218 }
219 }
220
221 /*
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.)
224 */
225 LocalTime = *pTimeSpec;
226 RTTimeSpecAddNano(&LocalTime, RTTimeLocalDeltaNano());
227 pTime = RTTimeExplode(pTime, &LocalTime);
228 if (pTime)
229 pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL;
230 return pTime;
231}
232
Note: See TracBrowser for help on using the repository browser.

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