VirtualBox

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

最後變更 在這個檔案從70402是 70402,由 vboxsync 提交於 7 年 前

iprt/time-win.cpp: There is no KUSER_SHARED_DATA on NT 3.1, so use GetTickCount as fallback. Kernel side does that too.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id Revision
檔案大小: 5.8 KB
 
1/* $Id: time-win.cpp 70402 2018-01-01 15:27:56Z vboxsync $ */
2/** @file
3 * IPRT - Time, Windows.
4 */
5
6/*
7 * Copyright (C) 2006-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.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
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_TIME
32#include <iprt/win/windows.h>
33
34#include <iprt/time.h>
35#include "internal/iprt.h"
36
37#include <iprt/asm.h>
38#include <iprt/assert.h>
39#include <iprt/err.h>
40#include "internal/time.h"
41#include "internal-r3-win.h"
42
43/*
44 * Note! The selected time source be the exact same one as we use in kernel land!
45 */
46//#define USE_TICK_COUNT
47//#define USE_PERFORMANCE_COUNTER
48//# define USE_FILE_TIME
49//#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
50# define USE_INTERRUPT_TIME
51//#else
52//# define USE_TICK_COUNT
53//#endif
54
55
56#ifdef USE_INTERRUPT_TIME
57
58typedef struct _MY_KSYSTEM_TIME
59{
60 ULONG LowPart;
61 LONG High1Time;
62 LONG High2Time;
63} MY_KSYSTEM_TIME;
64
65typedef struct _MY_KUSER_SHARED_DATA
66{
67 ULONG TickCountLowDeprecated;
68 ULONG TickCountMultiplier;
69 volatile MY_KSYSTEM_TIME InterruptTime;
70 /* The rest is not relevant. */
71} MY_KUSER_SHARED_DATA, *PMY_KUSER_SHARED_DATA;
72
73#endif /* USE_INTERRUPT_TIME */
74
75
76DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
77{
78#if defined USE_TICK_COUNT
79 /*
80 * This would work if it didn't flip over every 49 (or so) days.
81 */
82 return (uint64_t)GetTickCount() * RT_NS_1MS_64;
83
84#elif defined USE_PERFORMANCE_COUNTER
85 /*
86 * Slow and not derived from InterruptTime.
87 */
88 static LARGE_INTEGER llFreq;
89 static unsigned uMult;
90 if (!llFreq.QuadPart)
91 {
92 if (!QueryPerformanceFrequency(&llFreq))
93 return (uint64_t)GetTickCount() * RT_NS_1MS_64;
94 llFreq.QuadPart /= 1000;
95 uMult = 1000000; /* no math genius, but this seemed to help avoiding floating point. */
96 }
97
98 LARGE_INTEGER ll;
99 if (QueryPerformanceCounter(&ll))
100 return (ll.QuadPart * uMult) / llFreq.QuadPart;
101 return (uint64_t)GetTickCount() * RT_NS_1MS_64;
102
103#elif defined USE_FILE_TIME
104 /*
105 * This is SystemTime not InterruptTime.
106 */
107 uint64_t u64; /* manual say larger integer, should be safe to assume it's the same. */
108 GetSystemTimeAsFileTime((LPFILETIME)&u64);
109 return u64 * 100;
110
111#elif defined USE_INTERRUPT_TIME
112 /*
113 * Use interrupt time if we can (not possible on NT 3.1).
114 */
115 /** @todo use RtlGetInterruptTimePrecise if available (W10+). */
116
117 static int volatile g_fCanUseUserSharedData = -1;
118 int fCanUseUserSharedData = g_fCanUseUserSharedData;
119 if (fCanUseUserSharedData != -1)
120 { /* likely */ }
121 else
122 {
123 /* We may be called before g_enmWinVer has been initialized. */
124 if (g_enmWinVer != kRTWinOSType_UNKNOWN)
125 fCanUseUserSharedData = g_enmWinVer > kRTWinOSType_NT310;
126 else
127 {
128 DWORD dwVer = GetVersion();
129 fCanUseUserSharedData = (dwVer & 0xff) != 3 || ((dwVer >> 8) & 0xff) >= 50;
130 }
131 g_fCanUseUserSharedData = fCanUseUserSharedData;
132 }
133
134 if (fCanUseUserSharedData != 0)
135 {
136 PMY_KUSER_SHARED_DATA pUserSharedData = (PMY_KUSER_SHARED_DATA)(uintptr_t)0x7ffe0000;
137 LARGE_INTEGER Time;
138 do
139 {
140 Time.HighPart = pUserSharedData->InterruptTime.High1Time;
141 Time.LowPart = pUserSharedData->InterruptTime.LowPart;
142 } while (pUserSharedData->InterruptTime.High2Time != Time.HighPart);
143
144 return (uint64_t)Time.QuadPart * 100;
145 }
146
147 return (uint64_t)GetTickCount() * RT_NS_1MS_64;
148
149#else
150# error "Must select a method bright guy!"
151#endif
152}
153
154
155RTDECL(uint64_t) RTTimeSystemNanoTS(void)
156{
157 return rtTimeGetSystemNanoTS();
158}
159
160
161RTDECL(uint64_t) RTTimeSystemMilliTS(void)
162{
163 return rtTimeGetSystemNanoTS() / RT_NS_1MS;
164}
165
166
167RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
168{
169 uint64_t u64;
170 AssertCompile(sizeof(u64) == sizeof(FILETIME));
171 GetSystemTimeAsFileTime((LPFILETIME)&u64);
172 return RTTimeSpecSetNtTime(pTime, u64);
173}
174
175
176RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime)
177{
178 uint64_t u64;
179 AssertCompile(sizeof(u64) == sizeof(FILETIME));
180 GetSystemTimeAsFileTime((LPFILETIME)&u64);
181 uint64_t u64Local;
182 if (!FileTimeToLocalFileTime((FILETIME const *)&u64, (LPFILETIME)&u64Local))
183 u64Local = u64;
184 return RTTimeSpecSetNtTime(pTime, u64Local);
185}
186
187
188RTDECL(int64_t) RTTimeLocalDeltaNano(void)
189{
190 /*
191 * UTC = local + Tzi.Bias;
192 * The bias is given in minutes.
193 */
194 TIME_ZONE_INFORMATION Tzi;
195 Tzi.Bias = 0;
196 if (GetTimeZoneInformation(&Tzi) != TIME_ZONE_ID_INVALID)
197 return -(int64_t)Tzi.Bias * 60 * RT_NS_1SEC_64;
198 return 0;
199}
200
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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