1 // 2 // 3 // Copyright 2015 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 // Win32 code for gpr time support. 20 21 #include <grpc/support/port_platform.h> 22 23 #ifdef GPR_WINDOWS_TIME 24 25 #include <grpc/support/time.h> 26 #include <limits.h> 27 #include <process.h> 28 #include <sys/timeb.h> 29 30 #include "absl/log/check.h" 31 #include "src/core/util/crash.h" 32 #include "src/core/util/time_precise.h" 33 __anon6c5ce4180102() 34static LARGE_INTEGER g_start_time = []() { 35 LARGE_INTEGER x; 36 QueryPerformanceCounter(&x); 37 return x; 38 }(); __anon6c5ce4180202() 39static double g_time_scale = []() { 40 LARGE_INTEGER frequency; 41 QueryPerformanceFrequency(&frequency); 42 return 1.0 / (double)frequency.QuadPart; 43 }(); 44 gpr_time_init(void)45void gpr_time_init(void) {} 46 now_impl(gpr_clock_type clock)47static gpr_timespec now_impl(gpr_clock_type clock) { 48 gpr_timespec now_tv; 49 LONGLONG diff; 50 struct _timeb now_tb; 51 LARGE_INTEGER timestamp; 52 double now_dbl; 53 now_tv.clock_type = clock; 54 switch (clock) { 55 case GPR_CLOCK_REALTIME: 56 _ftime_s(&now_tb); 57 now_tv.tv_sec = (int64_t)now_tb.time; 58 now_tv.tv_nsec = now_tb.millitm * 1000000; 59 break; 60 case GPR_CLOCK_MONOTONIC: 61 case GPR_CLOCK_PRECISE: 62 QueryPerformanceCounter(×tamp); 63 diff = timestamp.QuadPart - g_start_time.QuadPart; 64 // Add an arbitrary 5 seconds to the monotonic clock so we don't 65 // immediately return close to zero. 66 now_dbl = 5.0 + (double)diff * g_time_scale; 67 now_tv.tv_sec = (int64_t)now_dbl; 68 now_tv.tv_nsec = (int32_t)((now_dbl - (double)now_tv.tv_sec) * 1e9); 69 break; 70 case GPR_TIMESPAN: 71 abort(); 72 break; 73 } 74 return now_tv; 75 } 76 77 gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type) = now_impl; 78 gpr_now(gpr_clock_type clock_type)79gpr_timespec gpr_now(gpr_clock_type clock_type) { 80 return gpr_now_impl(clock_type); 81 } 82 gpr_sleep_until(gpr_timespec until)83void gpr_sleep_until(gpr_timespec until) { 84 gpr_timespec now; 85 gpr_timespec delta; 86 int64_t sleep_millis; 87 88 for (;;) { 89 // We could simplify by using clock_nanosleep instead, but it might be 90 // slightly less portable. 91 now = gpr_now(until.clock_type); 92 if (gpr_time_cmp(until, now) <= 0) { 93 return; 94 } 95 96 delta = gpr_time_sub(until, now); 97 sleep_millis = 98 delta.tv_sec * GPR_MS_PER_SEC + delta.tv_nsec / GPR_NS_PER_MS; 99 CHECK_GE(sleep_millis, 0); 100 CHECK_LE(sleep_millis, INT_MAX); 101 Sleep((DWORD)sleep_millis); 102 } 103 } 104 105 #endif // GPR_WINDOWS_TIME 106