VirtualBox

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

Last change on this file since 69111 was 69111, checked in by vboxsync, 7 years ago

(C) year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.4 KB
Line 
1/* $Id: time-win.cpp 69111 2017-10-17 14:26:02Z 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.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
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
42/*
43 * Note! The selected time source be the exact same one as we use in kernel land!
44 */
45//#define USE_TICK_COUNT
46//#define USE_PERFORMANCE_COUNTER
47//# define USE_FILE_TIME
48//#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
49# define USE_INTERRUPT_TIME
50//#else
51//# define USE_TICK_COUNT
52//#endif
53
54
55#ifdef USE_INTERRUPT_TIME
56
57typedef struct _MY_KSYSTEM_TIME
58{
59 ULONG LowPart;
60 LONG High1Time;
61 LONG High2Time;
62} MY_KSYSTEM_TIME;
63
64typedef struct _MY_KUSER_SHARED_DATA
65{
66 ULONG TickCountLowDeprecated;
67 ULONG TickCountMultiplier;
68 volatile MY_KSYSTEM_TIME InterruptTime;
69 /* The rest is not relevant. */
70} MY_KUSER_SHARED_DATA, *PMY_KUSER_SHARED_DATA;
71
72#endif /* USE_INTERRUPT_TIME */
73
74
75DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
76{
77#if defined USE_TICK_COUNT
78 /*
79 * This would work if it didn't flip over every 49 (or so) days.
80 */
81 return (uint64_t)GetTickCount() * RT_NS_1MS_64;
82
83#elif defined USE_PERFORMANCE_COUNTER
84 /*
85 * Slow and not derived from InterruptTime.
86 */
87 static LARGE_INTEGER llFreq;
88 static unsigned uMult;
89 if (!llFreq.QuadPart)
90 {
91 if (!QueryPerformanceFrequency(&llFreq))
92 return (uint64_t)GetTickCount() * RT_NS_1MS_64;
93 llFreq.QuadPart /= 1000;
94 uMult = 1000000; /* no math genius, but this seemed to help avoiding floating point. */
95 }
96
97 LARGE_INTEGER ll;
98 if (QueryPerformanceCounter(&ll))
99 return (ll.QuadPart * uMult) / llFreq.QuadPart;
100 return (uint64_t)GetTickCount() * RT_NS_1MS_64;
101
102#elif defined USE_FILE_TIME
103 /*
104 * This is SystemTime not InterruptTime.
105 */
106 uint64_t u64; /* manual say larger integer, should be safe to assume it's the same. */
107 GetSystemTimeAsFileTime((LPFILETIME)&u64);
108 return u64 * 100;
109
110#elif defined USE_INTERRUPT_TIME
111# if 0 /* ASSUME 0x7ffe0000 is set in stone */
112 /*
113 * This is exactly what we want, but we have to obtain it by non-official
114 * means.
115 */
116 static MY_KUSER_SHARED_DATA *s_pUserSharedData = NULL;
117 if (!s_pUserSharedData)
118 {
119 /** @todo find official way of getting this or some more clever
120 * detection algorithm if necessary. The com debugger class
121 * exports this too, windbg knows it too... */
122 s_pUserSharedData = (PMY_KUSER_SHARED_DATA)(uintptr_t)0x7ffe0000;
123 }
124# endif
125 PMY_KUSER_SHARED_DATA pUserSharedData = (PMY_KUSER_SHARED_DATA)(uintptr_t)0x7ffe0000;
126
127 /* use interrupt time */
128 LARGE_INTEGER Time;
129 do
130 {
131 Time.HighPart = pUserSharedData->InterruptTime.High1Time;
132 Time.LowPart = pUserSharedData->InterruptTime.LowPart;
133 } while (pUserSharedData->InterruptTime.High2Time != Time.HighPart);
134
135 return (uint64_t)Time.QuadPart * 100;
136
137#else
138# error "Must select a method bright guy!"
139#endif
140}
141
142
143RTDECL(uint64_t) RTTimeSystemNanoTS(void)
144{
145 return rtTimeGetSystemNanoTS();
146}
147
148
149RTDECL(uint64_t) RTTimeSystemMilliTS(void)
150{
151 return rtTimeGetSystemNanoTS() / RT_NS_1MS;
152}
153
154
155RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
156{
157 uint64_t u64;
158 AssertCompile(sizeof(u64) == sizeof(FILETIME));
159 GetSystemTimeAsFileTime((LPFILETIME)&u64);
160 return RTTimeSpecSetNtTime(pTime, u64);
161}
162
163
164RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime)
165{
166 uint64_t u64;
167 AssertCompile(sizeof(u64) == sizeof(FILETIME));
168 GetSystemTimeAsFileTime((LPFILETIME)&u64);
169 uint64_t u64Local;
170 if (!FileTimeToLocalFileTime((FILETIME const *)&u64, (LPFILETIME)&u64Local))
171 u64Local = u64;
172 return RTTimeSpecSetNtTime(pTime, u64Local);
173}
174
175
176RTDECL(int64_t) RTTimeLocalDeltaNano(void)
177{
178 /*
179 * UTC = local + Tzi.Bias;
180 * The bias is given in minutes.
181 */
182 TIME_ZONE_INFORMATION Tzi;
183 Tzi.Bias = 0;
184 if (GetTimeZoneInformation(&Tzi) != TIME_ZONE_ID_INVALID)
185 return -(int64_t)Tzi.Bias * 60 * RT_NS_1SEC_64;
186 return 0;
187}
188
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