Home | History | Annotate | Download | only in gpr
      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 
     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 
     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 
     73 gpr_timespec gpr_now(gpr_clock_type clock_type) {
     74   return gpr_now_impl(clock_type);
     75 }
     76 
     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