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 <limits.h> 26 #include <process.h> 27 #include <sys/timeb.h> 28 29 #include <grpc/support/log.h> 30 #include <grpc/support/time.h> 31 32 #include "src/core/lib/gpr/time_precise.h" 33 #include "src/core/lib/gprpp/crash.h" 34 __anond61a5d7d0102() 35static LARGE_INTEGER g_start_time = []() { 36 LARGE_INTEGER x; 37 QueryPerformanceCounter(&x); 38 return x; 39 }(); __anond61a5d7d0202() 40static double g_time_scale = []() { 41 LARGE_INTEGER frequency; 42 QueryPerformanceFrequency(&frequency); 43 return 1.0 / (double)frequency.QuadPart; 44 }(); 45 gpr_time_init(void)46void gpr_time_init(void) {} 47 now_impl(gpr_clock_type clock)48static gpr_timespec now_impl(gpr_clock_type clock) { 49 gpr_timespec now_tv; 50 LONGLONG diff; 51 struct _timeb now_tb; 52 LARGE_INTEGER timestamp; 53 double now_dbl; 54 now_tv.clock_type = clock; 55 switch (clock) { 56 case GPR_CLOCK_REALTIME: 57 _ftime_s(&now_tb); 58 now_tv.tv_sec = (int64_t)now_tb.time; 59 now_tv.tv_nsec = now_tb.millitm * 1000000; 60 break; 61 case GPR_CLOCK_MONOTONIC: 62 case GPR_CLOCK_PRECISE: 63 QueryPerformanceCounter(×tamp); 64 diff = timestamp.QuadPart - g_start_time.QuadPart; 65 // Add an arbitrary 5 seconds to the monotonic clock so we don't 66 // immediately return close to zero. 67 now_dbl = 5.0 + (double)diff * g_time_scale; 68 now_tv.tv_sec = (int64_t)now_dbl; 69 now_tv.tv_nsec = (int32_t)((now_dbl - (double)now_tv.tv_sec) * 1e9); 70 break; 71 case GPR_TIMESPAN: 72 abort(); 73 break; 74 } 75 return now_tv; 76 } 77 78 gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type) = now_impl; 79 gpr_now(gpr_clock_type clock_type)80gpr_timespec gpr_now(gpr_clock_type clock_type) { 81 return gpr_now_impl(clock_type); 82 } 83 gpr_sleep_until(gpr_timespec until)84void gpr_sleep_until(gpr_timespec until) { 85 gpr_timespec now; 86 gpr_timespec delta; 87 int64_t sleep_millis; 88 89 for (;;) { 90 // We could simplify by using clock_nanosleep instead, but it might be 91 // slightly less portable. 92 now = gpr_now(until.clock_type); 93 if (gpr_time_cmp(until, now) <= 0) { 94 return; 95 } 96 97 delta = gpr_time_sub(until, now); 98 sleep_millis = 99 delta.tv_sec * GPR_MS_PER_SEC + delta.tv_nsec / GPR_NS_PER_MS; 100 GPR_ASSERT((sleep_millis >= 0) && (sleep_millis <= INT_MAX)); 101 Sleep((DWORD)sleep_millis); 102 } 103 } 104 105 #endif // GPR_WINDOWS_TIME 106