@@ -142,39 +142,35 @@ private static unsafe bool GetSystemSupportsLeapSeconds()
142
142
143
143
private static unsafe delegate * unmanaged[ SuppressGCTransition ] < ulong * , void > GetGetSystemTimeAsFileTimeFnPtr ( )
144
144
{
145
- IntPtr kernel32Lib = Interop . Kernel32 . LoadLibraryEx ( Interop . Libraries . Kernel32 , IntPtr . Zero , Interop . Kernel32 . LOAD_LIBRARY_SEARCH_SYSTEM32 ) ;
146
- Debug . Assert ( kernel32Lib != IntPtr . Zero ) ;
147
-
148
- IntPtr pfnGetSystemTime = NativeLibrary . GetExport ( kernel32Lib , "GetSystemTimeAsFileTime" ) ;
149
-
150
- if ( NativeLibrary . TryGetExport ( kernel32Lib , "GetSystemTimePreciseAsFileTime" , out IntPtr pfnGetSystemTimePrecise ) )
145
+ const long TargetAccuracy = 100 * TicksPerMillisecond ;
146
+
147
+ delegate * unmanaged[ SuppressGCTransition ] < ulong * , void > pfnGetSystemTime , pfnGetSystemTimePrecise ;
148
+ pfnGetSystemTime = & Interop . Kernel32 . GetSystemTimeAsFileTime ;
149
+ pfnGetSystemTimePrecise = & Interop . Kernel32 . GetSystemTimePreciseAsFileTime ;
150
+
151
+ // We would like to use GetSystemTimePreciseAsFileTime.
152
+ // However, on misconfigured systems, it's possible for the "precise" time to be inaccurate:
153
+ // https://github.com/dotnet/runtime/issues/9014
154
+ // If it's inaccurate, though, we expect it to be wildly inaccurate, so as a workaround/heuristic,
155
+ // we get both the "normal" and "precise" times, and as long as they're close, we use the precise one.
156
+ // This workaround can be removed when we better understand what's causing the drift
157
+ // and the issue is no longer a problem or can be better worked around on all targeted OSes.
158
+
159
+ // Retry this check several times to reduce chance of false negatives due to thread being rescheduled
160
+ // at wrong time.
161
+ for ( int i = 10 ; -- i >= 0 ; )
151
162
{
152
- // GetSystemTimePreciseAsFileTime exists and we'd like to use it. However, on
153
- // misconfigured systems, it's possible for the "precise" time to be inaccurate:
154
- // https://github.com/dotnet/runtime/issues/9014
155
- // If it's inaccurate, though, we expect it to be wildly inaccurate, so as a
156
- // workaround/heuristic, we get both the "normal" and "precise" times, and as
157
- // long as they're close, we use the precise one. This workaround can be removed
158
- // when we better understand what's causing the drift and the issue is no longer
159
- // a problem or can be better worked around on all targeted OSes.
160
-
161
- // Retry this check several times to reduce chance of false negatives due to thread being rescheduled
162
- // at wrong time.
163
- for ( int i = 0 ; i < 10 ; i ++ )
164
- {
165
- long systemTimeResult , preciseSystemTimeResult ;
166
- ( ( delegate * unmanaged[ SuppressGCTransition ] < long * , void > ) pfnGetSystemTime ) ( & systemTimeResult ) ;
167
- ( ( delegate * unmanaged[ SuppressGCTransition ] < long * , void > ) pfnGetSystemTimePrecise ) ( & preciseSystemTimeResult ) ;
163
+ ulong systemTimeResult , preciseSystemTimeResult ;
164
+ pfnGetSystemTime ( & systemTimeResult ) ;
165
+ pfnGetSystemTimePrecise ( & preciseSystemTimeResult ) ;
168
166
169
- if ( Math . Abs ( preciseSystemTimeResult - systemTimeResult ) <= 100 * TicksPerMillisecond )
170
- {
171
- pfnGetSystemTime = pfnGetSystemTimePrecise ; // use the precise version
172
- break ;
173
- }
167
+ if ( preciseSystemTimeResult - systemTimeResult + TargetAccuracy <= 2 * TargetAccuracy )
168
+ {
169
+ return pfnGetSystemTimePrecise ;
174
170
}
175
171
}
176
172
177
- return ( delegate * unmanaged [ SuppressGCTransition ] < ulong * , void > ) pfnGetSystemTime ;
173
+ return pfnGetSystemTime ;
178
174
}
179
175
180
176
private static unsafe DateTime UpdateLeapSecondCacheAndReturnUtcNow ( )
0 commit comments