Craig Tiller | 504ed59 | 2015-10-08 07:38:43 -0700 | [diff] [blame] | 1 | /* |
| 2 | * |
Craig Tiller | 6169d5f | 2016-03-31 07:46:18 -0700 | [diff] [blame^] | 3 | * Copyright 2015, Google Inc. |
Craig Tiller | 504ed59 | 2015-10-08 07:38:43 -0700 | [diff] [blame] | 4 | * All rights reserved. |
| 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions are |
| 8 | * met: |
| 9 | * |
| 10 | * * Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * * Redistributions in binary form must reproduce the above |
| 13 | * copyright notice, this list of conditions and the following disclaimer |
| 14 | * in the documentation and/or other materials provided with the |
| 15 | * distribution. |
| 16 | * * Neither the name of Google Inc. nor the names of its |
| 17 | * contributors may be used to endorse or promote products derived from |
| 18 | * this software without specific prior written permission. |
| 19 | * |
| 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 | * |
| 32 | */ |
| 33 | |
| 34 | #include <grpc/support/log.h> |
| 35 | #include <grpc/support/time.h> |
| 36 | #include <stdio.h> |
| 37 | |
| 38 | #ifdef GRPC_TIMERS_RDTSC |
| 39 | #if defined(__i386__) |
| 40 | static void gpr_get_cycle_counter(long long int *clk) { |
| 41 | long long int ret; |
| 42 | __asm__ volatile("rdtsc" : "=A"(ret)); |
| 43 | *clk = ret; |
| 44 | } |
| 45 | |
| 46 | // ---------------------------------------------------------------- |
| 47 | #elif defined(__x86_64__) || defined(__amd64__) |
| 48 | static void gpr_get_cycle_counter(long long int *clk) { |
| 49 | unsigned long long low, high; |
| 50 | __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); |
| 51 | *clk = (long long)(high << 32) | (long long)low; |
| 52 | } |
| 53 | #endif |
| 54 | |
| 55 | static double cycles_per_second = 0; |
| 56 | static long long int start_cycle; |
| 57 | void gpr_precise_clock_init(void) { |
| 58 | time_t start; |
| 59 | long long end_cycle; |
| 60 | gpr_log(GPR_DEBUG, "Calibrating timers"); |
| 61 | start = time(NULL); |
| 62 | while (time(NULL) == start) |
| 63 | ; |
| 64 | gpr_get_cycle_counter(&start_cycle); |
| 65 | while (time(NULL) <= start + 10) |
| 66 | ; |
| 67 | gpr_get_cycle_counter(&end_cycle); |
| 68 | cycles_per_second = (double)(end_cycle - start_cycle) / 10.0; |
| 69 | gpr_log(GPR_DEBUG, "... cycles_per_second = %f\n", cycles_per_second); |
| 70 | } |
| 71 | |
| 72 | void gpr_precise_clock_now(gpr_timespec *clk) { |
| 73 | long long int counter; |
| 74 | double secs; |
| 75 | gpr_get_cycle_counter(&counter); |
| 76 | secs = (double)(counter - start_cycle) / cycles_per_second; |
| 77 | clk->clock_type = GPR_CLOCK_PRECISE; |
Craig Tiller | 7536af0 | 2015-12-22 13:49:30 -0800 | [diff] [blame] | 78 | clk->tv_sec = (int64_t)secs; |
| 79 | clk->tv_nsec = (int32_t)(1e9 * (secs - (double)clk->tv_sec)); |
Craig Tiller | 504ed59 | 2015-10-08 07:38:43 -0700 | [diff] [blame] | 80 | } |
| 81 | |
| 82 | #else /* GRPC_TIMERS_RDTSC */ |
| 83 | void gpr_precise_clock_init(void) {} |
| 84 | |
| 85 | void gpr_precise_clock_now(gpr_timespec *clk) { |
| 86 | *clk = gpr_now(GPR_CLOCK_REALTIME); |
| 87 | clk->clock_type = GPR_CLOCK_PRECISE; |
| 88 | } |
| 89 | #endif /* GRPC_TIMERS_RDTSC */ |