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