src/core/lib/gpr/time.cc
Go to the documentation of this file.
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 /* Generic implementation of time calls. */
20 
22 
23 #include <limits.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include <grpc/support/log.h>
28 #include <grpc/support/time.h>
29 
31  int cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec);
32  GPR_ASSERT(a.clock_type == b.clock_type);
33  if (cmp == 0 && a.tv_sec != INT64_MAX && a.tv_sec != INT64_MIN) {
34  cmp = (a.tv_nsec > b.tv_nsec) - (a.tv_nsec < b.tv_nsec);
35  }
36  return cmp;
37 }
38 
40  return gpr_time_cmp(a, b) < 0 ? a : b;
41 }
42 
44  return gpr_time_cmp(a, b) > 0 ? a : b;
45 }
46 
49  out.tv_sec = 0;
50  out.tv_nsec = 0;
51  out.clock_type = type;
52  return out;
53 }
54 
57  out.tv_sec = INT64_MAX;
58  out.tv_nsec = 0;
59  out.clock_type = type;
60  return out;
61 }
62 
65  out.tv_sec = INT64_MIN;
66  out.tv_nsec = 0;
67  out.clock_type = type;
68  return out;
69 }
70 
72  int64_t units_per_sec,
75  if (time_in_units == INT64_MAX) {
77  } else if (time_in_units == INT64_MIN) {
79  } else {
80  if (time_in_units >= 0) {
81  out.tv_sec = time_in_units / units_per_sec;
82  } else {
83  out.tv_sec = (-((units_per_sec - 1) - (time_in_units + units_per_sec)) /
84  units_per_sec) -
85  1;
86  }
87  out.tv_nsec =
88  static_cast<int32_t>((time_in_units - out.tv_sec * units_per_sec) *
89  GPR_NS_PER_SEC / units_per_sec);
90  out.clock_type = type;
91  }
92  return out;
93 }
94 
96  int64_t secs_per_unit,
99  if (time_in_units >= INT64_MAX / secs_per_unit) {
101  } else if (time_in_units <= INT64_MIN / secs_per_unit) {
102  out = gpr_inf_past(type);
103  } else {
104  out.tv_sec = time_in_units * secs_per_unit;
105  out.tv_nsec = 0;
106  out.clock_type = type;
107  }
108  return out;
109 }
110 
113 }
114 
116  return to_seconds_from_sub_second_time(us, GPR_US_PER_SEC, clock_type);
117 }
118 
120  return to_seconds_from_sub_second_time(ms, GPR_MS_PER_SEC, clock_type);
121 }
122 
124  return to_seconds_from_sub_second_time(s, 1, clock_type);
125 }
126 
128  return to_seconds_from_above_second_time(m, 60, clock_type);
129 }
130 
132  return to_seconds_from_above_second_time(h, 3600, clock_type);
133 }
134 
137  int64_t inc = 0;
138  GPR_ASSERT(b.clock_type == GPR_TIMESPAN);
139  // tv_nsec in a timespan is always +ve. -ve timespan is represented as (-ve
140  // tv_sec, +ve tv_nsec). For example, timespan = -2.5 seconds is represented
141  // as {-3, 5e8, GPR_TIMESPAN}
142  GPR_ASSERT(b.tv_nsec >= 0);
143  sum.clock_type = a.clock_type;
144  sum.tv_nsec = a.tv_nsec + b.tv_nsec;
145  if (sum.tv_nsec >= GPR_NS_PER_SEC) {
146  sum.tv_nsec -= GPR_NS_PER_SEC;
147  inc++;
148  }
149  if (a.tv_sec == INT64_MAX || a.tv_sec == INT64_MIN) {
150  sum = a;
151  } else if (b.tv_sec == INT64_MAX ||
152  (b.tv_sec >= 0 && a.tv_sec >= INT64_MAX - b.tv_sec)) {
153  sum = gpr_inf_future(sum.clock_type);
154  } else if (b.tv_sec == INT64_MIN ||
155  (b.tv_sec <= 0 && a.tv_sec <= INT64_MIN - b.tv_sec)) {
156  sum = gpr_inf_past(sum.clock_type);
157  } else {
158  sum.tv_sec = a.tv_sec + b.tv_sec;
159  if (inc != 0 && sum.tv_sec == INT64_MAX - 1) {
160  sum = gpr_inf_future(sum.clock_type);
161  } else {
162  sum.tv_sec += inc;
163  }
164  }
165  return sum;
166 }
167 
170  int64_t dec = 0;
171  if (b.clock_type == GPR_TIMESPAN) {
172  diff.clock_type = a.clock_type;
173  // tv_nsec in a timespan is always +ve. -ve timespan is represented as (-ve
174  // tv_sec, +ve tv_nsec). For example, timespan = -2.5 seconds is represented
175  // as {-3, 5e8, GPR_TIMESPAN}
176  GPR_ASSERT(b.tv_nsec >= 0);
177  } else {
178  GPR_ASSERT(a.clock_type == b.clock_type);
179  diff.clock_type = GPR_TIMESPAN;
180  }
181  diff.tv_nsec = a.tv_nsec - b.tv_nsec;
182  if (diff.tv_nsec < 0) {
183  diff.tv_nsec += GPR_NS_PER_SEC;
184  dec++;
185  }
186  if (a.tv_sec == INT64_MAX || a.tv_sec == INT64_MIN) {
187  diff.tv_sec = a.tv_sec;
188  diff.tv_nsec = a.tv_nsec;
189  } else if (b.tv_sec == INT64_MIN ||
190  (b.tv_sec <= 0 && a.tv_sec >= INT64_MAX + b.tv_sec)) {
192  } else if (b.tv_sec == INT64_MAX ||
193  (b.tv_sec >= 0 && a.tv_sec <= INT64_MIN + b.tv_sec)) {
195  } else {
196  diff.tv_sec = a.tv_sec - b.tv_sec;
197  if (dec != 0 && diff.tv_sec == INT64_MIN + 1) {
199  } else {
200  diff.tv_sec -= dec;
201  }
202  }
203  return diff;
204 }
205 
207  int cmp_ab;
208 
209  GPR_ASSERT(a.clock_type == b.clock_type);
210  GPR_ASSERT(threshold.clock_type == GPR_TIMESPAN);
211 
212  cmp_ab = gpr_time_cmp(a, b);
213  if (cmp_ab == 0) return 1;
214  if (cmp_ab < 0) {
215  return gpr_time_cmp(gpr_time_sub(b, a), threshold) <= 0;
216  } else {
217  return gpr_time_cmp(gpr_time_sub(a, b), threshold) <= 0;
218  }
219 }
220 
222  if (t.tv_sec >= 2147483) {
223  if (t.tv_sec == 2147483 && t.tv_nsec < 648 * GPR_NS_PER_MS) {
224  return 2147483 * GPR_MS_PER_SEC + t.tv_nsec / GPR_NS_PER_MS;
225  }
226  return 2147483647;
227  } else if (t.tv_sec <= -2147483) {
228  /* TODO(ctiller): correct handling here (it's so far in the past do we
229  care?) */
230  return -2147483647;
231  } else {
232  return static_cast<int32_t>(t.tv_sec * GPR_MS_PER_SEC +
233  t.tv_nsec / GPR_NS_PER_MS);
234  }
235 }
236 
238  return static_cast<double>(t.tv_sec) * GPR_US_PER_SEC + t.tv_nsec * 1e-3;
239 }
240 
242  if (t.clock_type == clock_type) {
243  return t;
244  }
245 
246  if (t.tv_sec == INT64_MAX || t.tv_sec == INT64_MIN) {
247  t.clock_type = clock_type;
248  return t;
249  }
250 
251  if (clock_type == GPR_TIMESPAN) {
252  return gpr_time_sub(t, gpr_now(t.clock_type));
253  }
254 
255  if (t.clock_type == GPR_TIMESPAN) {
256  return gpr_time_add(gpr_now(clock_type), t);
257  }
258 
259  // If the given input hits this code, the same result is not guaranteed for
260  // the same input because it relies on `gpr_now` to calculate the difference
261  // between two different clocks. Please be careful when you want to use this
262  // function in unit tests. (e.g. https://github.com/grpc/grpc/pull/22655)
263  return gpr_time_add(gpr_now(clock_type),
264  gpr_time_sub(t, gpr_now(t.clock_type)));
265 }
GPR_TIMESPAN
@ GPR_TIMESPAN
Definition: gpr_types.h:45
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
log.h
gpr_time_add
gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:135
to_seconds_from_sub_second_time
static gpr_timespec to_seconds_from_sub_second_time(int64_t time_in_units, int64_t units_per_sec, gpr_clock_type type)
Definition: src/core/lib/gpr/time.cc:71
gpr_convert_clock_type
gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:241
inc
static void inc(void *v)
Definition: spinlock_test.cc:125
gpr_time_similar
int gpr_time_similar(gpr_timespec a, gpr_timespec b, gpr_timespec threshold)
Definition: src/core/lib/gpr/time.cc:206
grpc::testing::sum
double sum(const T &container, F functor)
Definition: test/cpp/qps/stats.h:30
INT64_MAX
#define INT64_MAX
Definition: stdint-msvc2008.h:139
to_seconds_from_above_second_time
static gpr_timespec to_seconds_from_above_second_time(int64_t time_in_units, int64_t secs_per_unit, gpr_clock_type type)
Definition: src/core/lib/gpr/time.cc:95
string.h
gpr_time_from_minutes
gpr_timespec gpr_time_from_minutes(int64_t m, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:127
gpr_time_from_seconds
gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:123
gpr_time_from_micros
gpr_timespec gpr_time_from_micros(int64_t us, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:115
GPR_US_PER_SEC
#define GPR_US_PER_SEC
Definition: include/grpc/support/time.h:40
gpr_time_from_hours
gpr_timespec gpr_time_from_hours(int64_t h, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:131
time.h
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
gpr_inf_future
gpr_timespec gpr_inf_future(gpr_clock_type type)
Definition: src/core/lib/gpr/time.cc:55
GPR_NS_PER_SEC
#define GPR_NS_PER_SEC
Definition: include/grpc/support/time.h:41
gpr_time_cmp
int gpr_time_cmp(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:30
gpr_time_min
gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:39
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
gpr_time_from_nanos
gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:111
bm_diff.diff
diff
Definition: bm_diff.py:274
gpr_time_0
gpr_timespec gpr_time_0(gpr_clock_type type)
Definition: src/core/lib/gpr/time.cc:47
gpr_timespec_to_micros
double gpr_timespec_to_micros(gpr_timespec t)
Definition: src/core/lib/gpr/time.cc:237
tests.google.protobuf.internal.message_test.cmp
cmp
Definition: bloaty/third_party/protobuf/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/message_test.py:61
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
gpr_now
GPRAPI gpr_timespec gpr_now(gpr_clock_type clock)
GPR_NS_PER_MS
#define GPR_NS_PER_MS
Definition: include/grpc/support/time.h:42
gpr_timespec::clock_type
gpr_clock_type clock_type
Definition: gpr_types.h:55
gpr_time_max
gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:43
INT64_MIN
#define INT64_MIN
Definition: stdint-msvc2008.h:138
gpr_inf_past
gpr_timespec gpr_inf_past(gpr_clock_type type)
Definition: src/core/lib/gpr/time.cc:63
gpr_time_to_millis
int32_t gpr_time_to_millis(gpr_timespec t)
Definition: src/core/lib/gpr/time.cc:221
GPR_MS_PER_SEC
#define GPR_MS_PER_SEC
Definition: include/grpc/support/time.h:39
ns
static int64_t ns
Definition: bloaty/third_party/re2/util/benchmark.cc:43
gpr_time_sub
gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:168
gpr_time_from_millis
gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:119
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
gpr_timespec
Definition: gpr_types.h:50
GPR_CLOCK_REALTIME
@ GPR_CLOCK_REALTIME
Definition: gpr_types.h:39
regress.m
m
Definition: regress/regress.py:25
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
gpr_clock_type
gpr_clock_type
Definition: gpr_types.h:34
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:36