make gpr_timespec platform agnostic

pull/4397/head
Jan Tattermusch 9 years ago
parent 07c4b573cf
commit 88086373db
  1. 4
      include/grpc/support/time.h
  2. 4
      src/core/iomgr/timer.c
  3. 7
      src/core/profiling/basic_timers.c
  4. 4
      src/core/security/credentials.c
  5. 2
      src/core/statistics/window_stats.c
  6. 4
      src/core/support/log_linux.c
  7. 4
      src/core/support/log_posix.c
  8. 4
      src/core/support/log_win32.c
  9. 64
      src/core/support/time.c
  10. 17
      src/core/support/time_posix.c
  11. 4
      src/core/support/time_precise.c
  12. 6
      src/core/support/time_win32.c
  13. 8
      src/core/surface/channel.c
  14. 6
      src/core/surface/channel_connectivity.c
  15. 8
      src/core/surface/completion_queue.c
  16. 10
      src/core/transport/chttp2/timeout_encoding.c
  17. 4
      src/core/transport/transport_op_string.c
  18. 8
      src/cpp/util/time.cc
  19. 91
      src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs
  20. 23
      src/csharp/Grpc.Core/Internal/Timespec.cs
  21. 6
      src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd
  22. 4
      src/ruby/ext/grpc/rb_grpc.c
  23. 5
      test/core/iomgr/tcp_client_posix_test.c
  24. 2
      test/core/support/sync_test.c
  25. 4
      test/core/support/time_test.c

@ -61,8 +61,8 @@ typedef enum {
} gpr_clock_type;
typedef struct gpr_timespec {
time_t tv_sec;
int tv_nsec;
gpr_int64 tv_sec;
gpr_int32 tv_nsec;
/** Against which clock was this time measured? (or GPR_TIMESPAN if
this is a relative time meaure) */
gpr_clock_type clock_type;

@ -126,8 +126,8 @@ static double ts_to_dbl(gpr_timespec ts) {
static gpr_timespec dbl_to_ts(double d) {
gpr_timespec ts;
ts.tv_sec = (time_t)d;
ts.tv_nsec = (int)(1e9 * (d - (double)ts.tv_sec));
ts.tv_sec = (gpr_int64)d;
ts.tv_nsec = (gpr_int32)(1e9 * (d - (double)ts.tv_sec));
ts.clock_type = GPR_TIMESPAN;
return ts;
}

@ -141,10 +141,11 @@ static void write_log(gpr_timer_log *log) {
entry->tm = gpr_time_0(entry->tm.clock_type);
}
fprintf(output_file,
"{\"t\": %ld.%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": "
"{\"t\": %lld.%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": "
"\"%s\", \"file\": \"%s\", \"line\": %d, \"imp\": %d}\n",
entry->tm.tv_sec, entry->tm.tv_nsec, entry->thd, entry->type,
entry->tagstr, entry->file, entry->line, entry->important);
(long long)entry->tm.tv_sec, (int)entry->tm.tv_nsec, entry->thd,
entry->type, entry->tagstr, entry->file, entry->line,
entry->important);
}
}

@ -511,9 +511,9 @@ grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
"grpc_service_account_jwt_access_credentials_create("
"json_key=%s, "
"token_lifetime="
"gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, "
"gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
5, (json_key, (long)token_lifetime.tv_sec, token_lifetime.tv_nsec,
5, (json_key, (long long)token_lifetime.tv_sec, (int)token_lifetime.tv_nsec,
(int)token_lifetime.clock_type, reserved));
GPR_ASSERT(reserved == NULL);
return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(

@ -94,7 +94,7 @@ static gpr_int64 timespec_to_ns(const gpr_timespec ts) {
if (ts.tv_sec > max_seconds) {
return GPR_INT64_MAX - 1;
}
return (gpr_int64)ts.tv_sec * GPR_NS_PER_SEC + ts.tv_nsec;
return ts.tv_sec * GPR_NS_PER_SEC + ts.tv_nsec;
}
static void cws_initialize_statistic(void *statistic,

@ -76,16 +76,18 @@ void gpr_default_log(gpr_log_func_args *args) {
char *prefix;
const char *display_file;
char time_buffer[64];
time_t timer;
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
struct tm tm;
timer = (time_t)now.tv_sec;
final_slash = strrchr(args->file, '/');
if (final_slash == NULL)
display_file = args->file;
else
display_file = final_slash + 1;
if (!localtime_r(&now.tv_sec, &tm)) {
if (!localtime_r(&timer, &tm)) {
strcpy(time_buffer, "error:localtime");
} else if (0 ==
strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {

@ -75,16 +75,18 @@ void gpr_default_log(gpr_log_func_args *args) {
char *final_slash;
const char *display_file;
char time_buffer[64];
time_t timer;
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
struct tm tm;
timer = (time_t)now.tv_sec;
final_slash = strrchr(args->file, '/');
if (final_slash == NULL)
display_file = args->file;
else
display_file = final_slash + 1;
if (!localtime_r(&now.tv_sec, &tm)) {
if (!localtime_r(&timer, &tm)) {
strcpy(time_buffer, "error:localtime");
} else if (0 ==
strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {

@ -84,16 +84,18 @@ void gpr_default_log(gpr_log_func_args *args) {
char *final_slash;
const char *display_file;
char time_buffer[64];
time_t timer;
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
struct tm tm;
timer = (time_t)now.tv_sec;
final_slash = strrchr(args->file, '\\');
if (final_slash == NULL)
display_file = args->file;
else
display_file = final_slash + 1;
if (localtime_s(&tm, &now.tv_sec)) {
if (localtime_s(&tm, &timer)) {
strcpy(time_buffer, "error:localtime");
} else if (0 ==
strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {

@ -56,22 +56,6 @@ gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b) {
return gpr_time_cmp(a, b) > 0 ? a : b;
}
/* There's no standard TIME_T_MIN and TIME_T_MAX, so we construct them. The
following assumes that signed types are two's-complement and that bytes are
8 bits. */
/* The top bit of integral type t. */
#define TOP_BIT_OF_TYPE(t) (((gpr_uintmax)1) << ((8 * sizeof(t)) - 1))
/* Return whether integral type t is signed. */
#define TYPE_IS_SIGNED(t) (((t)1) > (t) ~(t)0)
/* The minimum and maximum value of integral type t. */
#define TYPE_MIN(t) ((t)(TYPE_IS_SIGNED(t) ? TOP_BIT_OF_TYPE(t) : 0))
#define TYPE_MAX(t) \
((t)(TYPE_IS_SIGNED(t) ? (TOP_BIT_OF_TYPE(t) - 1) \
: ((TOP_BIT_OF_TYPE(t) - 1) << 1) + 1))
gpr_timespec gpr_time_0(gpr_clock_type type) {
gpr_timespec out;
out.tv_sec = 0;
@ -82,7 +66,7 @@ gpr_timespec gpr_time_0(gpr_clock_type type) {
gpr_timespec gpr_inf_future(gpr_clock_type type) {
gpr_timespec out;
out.tv_sec = TYPE_MAX(time_t);
out.tv_sec = INT64_MAX;
out.tv_nsec = 0;
out.clock_type = type;
return out;
@ -90,7 +74,7 @@ gpr_timespec gpr_inf_future(gpr_clock_type type) {
gpr_timespec gpr_inf_past(gpr_clock_type type) {
gpr_timespec out;
out.tv_sec = TYPE_MIN(time_t);
out.tv_sec = INT64_MIN;
out.tv_nsec = 0;
out.clock_type = type;
return out;
@ -108,11 +92,11 @@ gpr_timespec gpr_time_from_nanos(long ns, gpr_clock_type type) {
result = gpr_inf_past(type);
} else if (ns >= 0) {
result.tv_sec = ns / GPR_NS_PER_SEC;
result.tv_nsec = (int)(ns - result.tv_sec * GPR_NS_PER_SEC);
result.tv_nsec = (gpr_int32)(ns - result.tv_sec * GPR_NS_PER_SEC);
} else {
/* Calculation carefully formulated to avoid any possible under/overflow. */
result.tv_sec = (-(999999999 - (ns + GPR_NS_PER_SEC)) / GPR_NS_PER_SEC) - 1;
result.tv_nsec = (int)(ns - result.tv_sec * GPR_NS_PER_SEC);
result.tv_nsec = (gpr_int32)(ns - result.tv_sec * GPR_NS_PER_SEC);
}
return result;
}
@ -126,11 +110,11 @@ gpr_timespec gpr_time_from_micros(long us, gpr_clock_type type) {
result = gpr_inf_past(type);
} else if (us >= 0) {
result.tv_sec = us / 1000000;
result.tv_nsec = (int)((us - result.tv_sec * 1000000) * 1000);
result.tv_nsec = (gpr_int32)((us - result.tv_sec * 1000000) * 1000);
} else {
/* Calculation carefully formulated to avoid any possible under/overflow. */
result.tv_sec = (-(999999 - (us + 1000000)) / 1000000) - 1;
result.tv_nsec = (int)((us - result.tv_sec * 1000000) * 1000);
result.tv_nsec = (gpr_int32)((us - result.tv_sec * 1000000) * 1000);
}
return result;
}
@ -144,11 +128,11 @@ gpr_timespec gpr_time_from_millis(long ms, gpr_clock_type type) {
result = gpr_inf_past(type);
} else if (ms >= 0) {
result.tv_sec = ms / 1000;
result.tv_nsec = (int)((ms - result.tv_sec * 1000) * 1000000);
result.tv_nsec = (gpr_int32)((ms - result.tv_sec * 1000) * 1000000);
} else {
/* Calculation carefully formulated to avoid any possible under/overflow. */
result.tv_sec = (-(999 - (ms + 1000)) / 1000) - 1;
result.tv_nsec = (int)((ms - result.tv_sec * 1000) * 1000000);
result.tv_nsec = (gpr_int32)((ms - result.tv_sec * 1000) * 1000000);
}
return result;
}
@ -197,7 +181,7 @@ gpr_timespec gpr_time_from_hours(long h, gpr_clock_type type) {
gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) {
gpr_timespec sum;
int inc = 0;
gpr_int64 inc = 0;
GPR_ASSERT(b.clock_type == GPR_TIMESPAN);
sum.clock_type = a.clock_type;
sum.tv_nsec = a.tv_nsec + b.tv_nsec;
@ -205,17 +189,17 @@ gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) {
sum.tv_nsec -= GPR_NS_PER_SEC;
inc++;
}
if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) {
if (a.tv_sec == INT64_MAX || a.tv_sec == INT64_MIN) {
sum = a;
} else if (b.tv_sec == TYPE_MAX(time_t) ||
(b.tv_sec >= 0 && a.tv_sec >= TYPE_MAX(time_t) - b.tv_sec)) {
} else if (b.tv_sec == INT64_MAX ||
(b.tv_sec >= 0 && a.tv_sec >= INT64_MAX - b.tv_sec)) {
sum = gpr_inf_future(sum.clock_type);
} else if (b.tv_sec == TYPE_MIN(time_t) ||
(b.tv_sec <= 0 && a.tv_sec <= TYPE_MIN(time_t) - b.tv_sec)) {
} else if (b.tv_sec == INT64_MIN ||
(b.tv_sec <= 0 && a.tv_sec <= INT64_MIN - b.tv_sec)) {
sum = gpr_inf_past(sum.clock_type);
} else {
sum.tv_sec = a.tv_sec + b.tv_sec;
if (inc != 0 && sum.tv_sec == TYPE_MAX(time_t) - 1) {
if (inc != 0 && sum.tv_sec == INT64_MAX - 1) {
sum = gpr_inf_future(sum.clock_type);
} else {
sum.tv_sec += inc;
@ -226,7 +210,7 @@ gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) {
gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) {
gpr_timespec diff;
int dec = 0;
gpr_int64 dec = 0;
if (b.clock_type == GPR_TIMESPAN) {
diff.clock_type = a.clock_type;
} else {
@ -238,17 +222,17 @@ gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) {
diff.tv_nsec += GPR_NS_PER_SEC;
dec++;
}
if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) {
if (a.tv_sec == INT64_MAX || a.tv_sec == INT64_MIN) {
diff = a;
} else if (b.tv_sec == TYPE_MIN(time_t) ||
(b.tv_sec <= 0 && a.tv_sec >= TYPE_MAX(time_t) + b.tv_sec)) {
} else if (b.tv_sec == INT64_MIN ||
(b.tv_sec <= 0 && a.tv_sec >= INT64_MAX + b.tv_sec)) {
diff = gpr_inf_future(GPR_CLOCK_REALTIME);
} else if (b.tv_sec == TYPE_MAX(time_t) ||
(b.tv_sec >= 0 && a.tv_sec <= TYPE_MIN(time_t) + b.tv_sec)) {
} else if (b.tv_sec == INT64_MAX ||
(b.tv_sec >= 0 && a.tv_sec <= INT64_MIN + b.tv_sec)) {
diff = gpr_inf_past(GPR_CLOCK_REALTIME);
} else {
diff.tv_sec = a.tv_sec - b.tv_sec;
if (dec != 0 && diff.tv_sec == TYPE_MIN(time_t) + 1) {
if (dec != 0 && diff.tv_sec == INT64_MIN + 1) {
diff = gpr_inf_past(GPR_CLOCK_REALTIME);
} else {
diff.tv_sec -= dec;
@ -297,11 +281,11 @@ gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type clock_type) {
}
if (t.tv_nsec == 0) {
if (t.tv_sec == TYPE_MAX(time_t)) {
if (t.tv_sec == INT64_MAX) {
t.clock_type = clock_type;
return t;
}
if (t.tv_sec == TYPE_MIN(time_t)) {
if (t.tv_sec == INT64_MIN) {
t.clock_type = clock_type;
return t;
}

@ -45,7 +45,11 @@
static struct timespec timespec_from_gpr(gpr_timespec gts) {
struct timespec rv;
rv.tv_sec = gts.tv_sec;
if (sizeof(time_t) < sizeof(gpr_int64)) {
/* fine to assert, as this is only used in gpr_sleep_until */
GPR_ASSERT(gts.tv_sec <= INT32_MAX && gts.tv_sec >= INT32_MIN);
}
rv.tv_sec = (time_t)gts.tv_sec;
rv.tv_nsec = gts.tv_nsec;
return rv;
}
@ -53,9 +57,14 @@ static struct timespec timespec_from_gpr(gpr_timespec gts) {
#if _POSIX_TIMERS > 0
static gpr_timespec gpr_from_timespec(struct timespec ts,
gpr_clock_type clock_type) {
/*
* timespec.tv_sec can have smaller size than gpr_timespec.tv_sec,
* but we are only using this function to implement gpr_now
* so there's no need to handle "infinity" values.
*/
gpr_timespec rv;
rv.tv_sec = ts.tv_sec;
rv.tv_nsec = (int)ts.tv_nsec;
rv.tv_nsec = (gpr_int32)ts.tv_nsec;
rv.clock_type = clock_type;
return rv;
}
@ -110,8 +119,8 @@ gpr_timespec gpr_now(gpr_clock_type clock) {
break;
case GPR_CLOCK_MONOTONIC:
now_dbl = (mach_absolute_time() - g_time_start) * g_time_scale;
now.tv_sec = (time_t)(now_dbl * 1e-9);
now.tv_nsec = (int)(now_dbl - ((double)now.tv_sec) * 1e9);
now.tv_sec = (gpr_int64)(now_dbl * 1e-9);
now.tv_nsec = (gpr_int32)(now_dbl - ((double)now.tv_sec) * 1e9);
break;
case GPR_CLOCK_PRECISE:
gpr_precise_clock_now(&now);

@ -75,8 +75,8 @@ void gpr_precise_clock_now(gpr_timespec *clk) {
gpr_get_cycle_counter(&counter);
secs = (double)(counter - start_cycle) / cycles_per_second;
clk->clock_type = GPR_CLOCK_PRECISE;
clk->tv_sec = (time_t)secs;
clk->tv_nsec = (int)(1e9 * (secs - (double)clk->tv_sec));
clk->tv_sec = (gpr_int64)secs;
clk->tv_nsec = (gpr_int32)(1e9 * (secs - (double)clk->tv_sec));
}
#else /* GRPC_TIMERS_RDTSC */

@ -62,15 +62,15 @@ gpr_timespec gpr_now(gpr_clock_type clock) {
switch (clock) {
case GPR_CLOCK_REALTIME:
_ftime_s(&now_tb);
now_tv.tv_sec = now_tb.time;
now_tv.tv_sec = (gpr_int64)now_tb.time;
now_tv.tv_nsec = now_tb.millitm * 1000000;
break;
case GPR_CLOCK_MONOTONIC:
case GPR_CLOCK_PRECISE:
QueryPerformanceCounter(&timestamp);
now_dbl = (timestamp.QuadPart - g_start_time.QuadPart) * g_time_scale;
now_tv.tv_sec = (time_t)now_dbl;
now_tv.tv_nsec = (int)((now_dbl - (double)now_tv.tv_sec) * 1e9);
now_tv.tv_sec = (gpr_int64)now_dbl;
now_tv.tv_nsec = (gpr_int32)((now_dbl - (double)now_tv.tv_sec) * 1e9);
break;
}
return now_tv;

@ -194,10 +194,10 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
"grpc_channel_create_call("
"channel=%p, parent_call=%p, propagation_mask=%x, cq=%p, method=%s, "
"host=%s, "
"deadline=gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, "
"deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
10, (channel, parent_call, (unsigned)propagation_mask, cq, method, host,
(long)deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type,
(long long)deadline.tv_sec, (int)deadline.tv_nsec, (int)deadline.clock_type,
reserved));
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
@ -238,10 +238,10 @@ grpc_call *grpc_channel_create_registered_call(
"grpc_channel_create_registered_call("
"channel=%p, parent_call=%p, propagation_mask=%x, completion_queue=%p, "
"registered_call_handle=%p, "
"deadline=gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, "
"deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
9, (channel, parent_call, (unsigned)propagation_mask, completion_queue,
registered_call_handle, (long)deadline.tv_sec, deadline.tv_nsec,
registered_call_handle, (long long)deadline.tv_sec, (int)deadline.tv_nsec,
(int)deadline.clock_type, reserved));
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(

@ -200,10 +200,10 @@ void grpc_channel_watch_connectivity_state(
GRPC_API_TRACE(
"grpc_channel_watch_connectivity_state("
"channel=%p, last_observed_state=%d, "
"deadline=gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, "
"deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"cq=%p, tag=%p)",
7, (channel, (int)last_observed_state, (long)deadline.tv_sec,
deadline.tv_nsec, (int)deadline.clock_type, cq, tag));
7, (channel, (int)last_observed_state, (long long)deadline.tv_sec,
(int)deadline.tv_nsec, (int)deadline.clock_type, cq, tag));
grpc_cq_begin_op(cq);

@ -247,9 +247,9 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
GRPC_API_TRACE(
"grpc_completion_queue_next("
"cc=%p, "
"deadline=gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, "
"deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
5, (cc, (long)deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type,
5, (cc, (long long)deadline.tv_sec, (int)deadline.tv_nsec, (int)deadline.clock_type,
reserved));
GPR_ASSERT(!reserved);
@ -335,9 +335,9 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
GRPC_API_TRACE(
"grpc_completion_queue_pluck("
"cc=%p, tag=%p, "
"deadline=gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, "
"deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
6, (cc, tag, (long)deadline.tv_sec, deadline.tv_nsec,
6, (cc, tag, (long long)deadline.tv_sec, (int)deadline.tv_nsec,
(int)deadline.clock_type, reserved));
GPR_ASSERT(!reserved);

@ -39,12 +39,12 @@
#include <grpc/support/port_platform.h>
#include "src/core/support/string.h"
static int round_up(int x, int divisor) {
static gpr_int64 round_up(gpr_int64 x, gpr_int64 divisor) {
return (x / divisor + (x % divisor != 0)) * divisor;
}
/* round an integer up to the next value with three significant figures */
static int round_up_to_three_sig_figs(int x) {
static gpr_int64 round_up_to_three_sig_figs(gpr_int64 x) {
if (x < 1000) return x;
if (x < 10000) return round_up(x, 10);
if (x < 100000) return round_up(x, 100);
@ -74,7 +74,7 @@ static void enc_seconds(char *buffer, gpr_int64 sec) {
}
}
static void enc_nanos(char *buffer, int x) {
static void enc_nanos(char *buffer, gpr_int64 x) {
x = round_up_to_three_sig_figs(x);
if (x < 100000) {
if (x % 1000 == 0) {
@ -98,7 +98,7 @@ static void enc_nanos(char *buffer, int x) {
}
}
static void enc_micros(char *buffer, int x) {
static void enc_micros(char *buffer, gpr_int64 x) {
x = round_up_to_three_sig_figs(x);
if (x < 100000) {
if (x % 1000 == 0) {
@ -124,7 +124,7 @@ void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer) {
enc_nanos(buffer, timeout.tv_nsec);
} else if (timeout.tv_sec < 1000 && timeout.tv_nsec != 0) {
enc_micros(buffer,
(int)(timeout.tv_sec * 1000000) +
(gpr_int64)(timeout.tv_sec * 1000000) +
(timeout.tv_nsec / 1000 + (timeout.tv_nsec % 1000 != 0)));
} else {
enc_seconds(buffer, timeout.tv_sec + (timeout.tv_nsec != 0));

@ -63,8 +63,8 @@ static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) {
}
if (gpr_time_cmp(md.deadline, gpr_inf_future(md.deadline.clock_type)) != 0) {
char *tmp;
gpr_asprintf(&tmp, " deadline=%d.%09d", md.deadline.tv_sec,
md.deadline.tv_nsec);
gpr_asprintf(&tmp, " deadline=%lld.%09d", (long long)md.deadline.tv_sec,
(int)md.deadline.tv_nsec);
gpr_strvec_add(b, tmp);
}
}

@ -57,8 +57,8 @@ void Timepoint2Timespec(const system_clock::time_point& from,
return;
}
nanoseconds nsecs = duration_cast<nanoseconds>(deadline - secs);
to->tv_sec = (time_t)secs.count();
to->tv_nsec = (int)nsecs.count();
to->tv_sec = (gpr_int64)secs.count();
to->tv_nsec = (gpr_int32)nsecs.count();
to->clock_type = GPR_CLOCK_REALTIME;
}
@ -73,8 +73,8 @@ void TimepointHR2Timespec(const high_resolution_clock::time_point& from,
return;
}
nanoseconds nsecs = duration_cast<nanoseconds>(deadline - secs);
to->tv_sec = (time_t)secs.count();
to->tv_nsec = (int)nsecs.count();
to->tv_sec = (gpr_int64)secs.count();
to->tv_nsec = (gpr_int32)nsecs.count();
to->clock_type = GPR_CLOCK_REALTIME;
}

@ -82,17 +82,17 @@ namespace Grpc.Core.Internal.Tests
public void ToDateTime()
{
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
new Timespec(IntPtr.Zero, 0).ToDateTime());
new Timespec(0, 0).ToDateTime());
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc).AddTicks(50),
new Timespec(new IntPtr(10), 5000).ToDateTime());
new Timespec(10, 5000).ToDateTime());
Assert.AreEqual(new DateTime(2015, 7, 21, 4, 21, 48, DateTimeKind.Utc),
new Timespec(new IntPtr(1437452508), 0).ToDateTime());
new Timespec(1437452508, 0).ToDateTime());
// before epoch
Assert.AreEqual(new DateTime(1969, 12, 31, 23, 59, 55, DateTimeKind.Utc).AddTicks(10),
new Timespec(new IntPtr(-5), 1000).ToDateTime());
new Timespec(-5, 1000).ToDateTime());
// infinity
Assert.AreEqual(DateTime.MaxValue, Timespec.InfFuture.ToDateTime());
@ -100,80 +100,62 @@ namespace Grpc.Core.Internal.Tests
// nanos are rounded to ticks are rounded up
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks(1),
new Timespec(IntPtr.Zero, 99).ToDateTime());
new Timespec(0, 99).ToDateTime());
// Illegal inputs
Assert.Throws(typeof(InvalidOperationException),
() => new Timespec(new IntPtr(0), -2).ToDateTime());
() => new Timespec(0, -2).ToDateTime());
Assert.Throws(typeof(InvalidOperationException),
() => new Timespec(new IntPtr(0), 1000 * 1000 * 1000).ToDateTime());
() => new Timespec(0, 1000 * 1000 * 1000).ToDateTime());
Assert.Throws(typeof(InvalidOperationException),
() => new Timespec(new IntPtr(0), 0, GPRClockType.Monotonic).ToDateTime());
() => new Timespec(0, 0, GPRClockType.Monotonic).ToDateTime());
}
[Test]
public void ToDateTime_ReturnsUtc()
{
Assert.AreEqual(DateTimeKind.Utc, new Timespec(new IntPtr(1437452508), 0).ToDateTime().Kind);
Assert.AreNotEqual(DateTimeKind.Unspecified, new Timespec(new IntPtr(1437452508), 0).ToDateTime().Kind);
Assert.AreEqual(DateTimeKind.Utc, new Timespec(1437452508, 0).ToDateTime().Kind);
Assert.AreNotEqual(DateTimeKind.Unspecified, new Timespec(1437452508, 0).ToDateTime().Kind);
}
[Test]
public void ToDateTime_Overflow()
{
// we can only get overflow in ticks arithmetic on 64-bit
if (IntPtr.Size == 8)
{
var timespec = new Timespec(new IntPtr(long.MaxValue - 100), 0);
Assert.AreNotEqual(Timespec.InfFuture, timespec);
Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime());
Assert.AreEqual(DateTime.MinValue, new Timespec(new IntPtr(long.MinValue + 100), 0).ToDateTime());
}
else
{
Console.WriteLine("Test cannot be run on this platform, skipping the test.");
}
{
var timespec = new Timespec(long.MaxValue - 100, 0);
Assert.AreNotEqual(Timespec.InfFuture, timespec);
Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime());
Assert.AreEqual(DateTime.MinValue, new Timespec(long.MinValue + 100, 0).ToDateTime());
}
[Test]
public void ToDateTime_OutOfDateTimeRange()
{
// we can only get out of range on 64-bit, on 32 bit the max
// timestamp is ~ Jan 19 2038, which is far within range of DateTime
// same case for min value.
if (IntPtr.Size == 8)
{
// DateTime range goes up to year 9999, 20000 years from now should
// be out of range.
long seconds = 20000L * 365L * 24L * 3600L;
var timespec = new Timespec(new IntPtr(seconds), 0);
Assert.AreNotEqual(Timespec.InfFuture, timespec);
Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime());
Assert.AreEqual(DateTime.MinValue, new Timespec(new IntPtr(-seconds), 0).ToDateTime());
}
else
{
Console.WriteLine("Test cannot be run on this platform, skipping the test");
}
// DateTime range goes up to year 9999, 20000 years from now should
// be out of range.
long seconds = 20000L * 365L * 24L * 3600L;
var timespec = new Timespec(seconds, 0);
Assert.AreNotEqual(Timespec.InfFuture, timespec);
Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime());
Assert.AreEqual(DateTime.MinValue, new Timespec(-seconds, 0).ToDateTime());
}
[Test]
public void FromDateTime()
{
Assert.AreEqual(new Timespec(IntPtr.Zero, 0),
Assert.AreEqual(new Timespec(0, 0),
Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)));
Assert.AreEqual(new Timespec(new IntPtr(10), 5000),
Assert.AreEqual(new Timespec(10, 5000),
Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc).AddTicks(50)));
Assert.AreEqual(new Timespec(new IntPtr(1437452508), 0),
Assert.AreEqual(new Timespec(1437452508, 0),
Timespec.FromDateTime(new DateTime(2015, 7, 21, 4, 21, 48, DateTimeKind.Utc)));
// before epoch
Assert.AreEqual(new Timespec(new IntPtr(-5), 1000),
Assert.AreEqual(new Timespec(-5, 1000),
Timespec.FromDateTime(new DateTime(1969, 12, 31, 23, 59, 55, DateTimeKind.Utc).AddTicks(10)));
// infinity
@ -184,21 +166,6 @@ namespace Grpc.Core.Internal.Tests
Assert.Throws(typeof(ArgumentException),
() => Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Unspecified)));
}
[Test]
public void FromDateTime_OutOfTimespecRange()
{
// we can only get overflow in Timespec on 32-bit
if (IntPtr.Size == 4)
{
Assert.AreEqual(Timespec.InfFuture, Timespec.FromDateTime(new DateTime(2040, 1, 1, 0, 0, 0, DateTimeKind.Utc)));
Assert.AreEqual(Timespec.InfPast, Timespec.FromDateTime(new DateTime(1800, 1, 1, 0, 0, 0, DateTimeKind.Utc)));
}
else
{
Console.WriteLine("Test cannot be run on this platform, skipping the test.");
}
}
// Test attribute commented out to prevent running as part of the default test suite.
// [Test]

@ -63,20 +63,18 @@ namespace Grpc.Core.Internal
[DllImport("grpc_csharp_ext.dll")]
static extern int gprsharp_sizeof_timespec();
public Timespec(IntPtr tv_sec, int tv_nsec) : this(tv_sec, tv_nsec, GPRClockType.Realtime)
public Timespec(long tv_sec, int tv_nsec) : this(tv_sec, tv_nsec, GPRClockType.Realtime)
{
}
public Timespec(IntPtr tv_sec, int tv_nsec, GPRClockType clock_type)
public Timespec(long tv_sec, int tv_nsec, GPRClockType clock_type)
{
this.tv_sec = tv_sec;
this.tv_nsec = tv_nsec;
this.clock_type = clock_type;
}
// NOTE: on linux 64bit sizeof(gpr_timespec) = 16, on windows 32bit sizeof(gpr_timespec) = 8
// so IntPtr seems to have the right size to work on both.
private System.IntPtr tv_sec;
private long tv_sec;
private int tv_nsec;
private GPRClockType clock_type;
@ -116,7 +114,7 @@ namespace Grpc.Core.Internal
/// <summary>
/// Seconds since unix epoch.
/// </summary>
public IntPtr TimevalSeconds
public long TimevalSeconds
{
get
{
@ -176,18 +174,18 @@ namespace Grpc.Core.Internal
{
// convert nanos to ticks, round up to the nearest tick
long ticksFromNanos = tv_nsec / NanosPerTick + ((tv_nsec % NanosPerTick != 0) ? 1 : 0);
long ticksTotal = checked(tv_sec.ToInt64() * TicksPerSecond + ticksFromNanos);
long ticksTotal = checked(tv_sec * TicksPerSecond + ticksFromNanos);
return UnixEpoch.AddTicks(ticksTotal);
}
catch (OverflowException)
{
// ticks out of long range
return tv_sec.ToInt64() > 0 ? DateTime.MaxValue : DateTime.MinValue;
return tv_sec > 0 ? DateTime.MaxValue : DateTime.MinValue;
}
catch (ArgumentOutOfRangeException)
{
// resulting date time would be larger than MaxValue
return tv_sec.ToInt64() > 0 ? DateTime.MaxValue : DateTime.MinValue;
return tv_sec > 0 ? DateTime.MaxValue : DateTime.MinValue;
}
}
@ -226,12 +224,7 @@ namespace Grpc.Core.Internal
seconds--;
nanos += (int)NanosPerSecond;
}
// new IntPtr possibly throws OverflowException
return new Timespec(new IntPtr(seconds), nanos);
}
catch (OverflowException)
{
return dateTime > UnixEpoch ? Timespec.InfFuture : Timespec.InfPast;
return new Timespec(seconds, nanos);
}
catch (ArgumentOutOfRangeException)
{

@ -60,6 +60,8 @@ cdef extern from "grpc/support/port_platform.h":
# type exactly; just close enough that the operations will be supported in the
# underlying C layers.
ctypedef unsigned int gpr_uint32
ctypedef int gpr_int32
ctypedef long int gpr_int64
cdef extern from "grpc/support/time.h":
@ -71,8 +73,8 @@ cdef extern from "grpc/support/time.h":
GPR_TIMESPAN
ctypedef struct gpr_timespec:
libc.time.time_t seconds "tv_sec"
int nanoseconds "tv_nsec"
gpr_int64 seconds "tv_sec"
gpr_int32 nanoseconds "tv_nsec"
gpr_clock_type clock_type
gpr_timespec gpr_time_0(gpr_clock_type type)

@ -91,7 +91,7 @@ static ID id_tv_sec;
static ID id_tv_nsec;
/**
* grpc_rb_time_timeval creates a time_eval from a ruby time object.
* grpc_rb_time_timeval creates a timeval from a ruby time object.
*
* This func is copied from ruby source, MRI/source/time.c, which is published
* under the same license as the ruby.h, on which the entire extensions is
@ -137,7 +137,7 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) {
d += 1;
f -= 1;
}
t.tv_sec = (time_t)f;
t.tv_sec = (gpr_int64)f;
if (f != t.tv_sec) {
rb_raise(rb_eRangeError, "%f out of Time range",
RFLOAT_VALUE(time));

@ -234,8 +234,9 @@ void test_times_out(void) {
if (gpr_time_cmp(now, finish_time) > 0) {
break;
}
gpr_log(GPR_DEBUG, "now=%d.%09d connect_deadline=%d.%09d", now.tv_sec,
now.tv_nsec, connect_deadline.tv_sec, connect_deadline.tv_nsec);
gpr_log(GPR_DEBUG, "now=%lld.%09d connect_deadline=%lld.%09d",
(long long)now.tv_sec, (int)now.tv_nsec,
(long long)connect_deadline.tv_sec, (int)connect_deadline.tv_nsec);
if (is_after_deadline && gpr_time_cmp(now, restart_verifying_time) <= 0) {
/* allow some slack before insisting that things be done */
} else {

@ -272,7 +272,7 @@ static void test(const char *name, void (*body)(void *m),
test_destroy(m);
}
time_taken = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start);
fprintf(stderr, " done %ld.%09d s\n", (long)time_taken.tv_sec,
fprintf(stderr, " done %lld.%09d s\n", (long long)time_taken.tv_sec,
(int)time_taken.tv_nsec);
}

@ -98,7 +98,7 @@ static void test_values(void) {
fprintf(stderr, "far future ");
i_to_s(x.tv_sec, 16, 16, &to_fp, stderr);
fprintf(stderr, "\n");
GPR_ASSERT(x.tv_sec >= INT_MAX);
GPR_ASSERT(x.tv_sec == INT64_MAX);
fprintf(stderr, "far future ");
ts_to_s(x, &to_fp, stderr);
fprintf(stderr, "\n");
@ -107,7 +107,7 @@ static void test_values(void) {
fprintf(stderr, "far past ");
i_to_s(x.tv_sec, 16, 16, &to_fp, stderr);
fprintf(stderr, "\n");
GPR_ASSERT(x.tv_sec <= INT_MIN);
GPR_ASSERT(x.tv_sec == INT64_MIN);
fprintf(stderr, "far past ");
ts_to_s(x, &to_fp, stderr);
fprintf(stderr, "\n");

Loading…
Cancel
Save